1

I'm practicing a coding problem on "Check if the frequency of all the digits in a number is same"

#include<bits/stdc++.h> 
using namespace std; 

    // returns true if the number 
    // passed as the argument 
    // is a balanced number. 

bool isNumBalanced(int N) 
{ 

    string st = to_string(N); 
    bool isBalanced = true; 

    // frequency array to store 
    // the frequencies of all 
    // the digits of the number 
    int freq[10] = {0}; 
    int i = 0; 
    int n = st.size(); 

    for (i = 0; i < n; i++) 

        // store the frequency of 
        // the current digit 
        freq[st[i] - '0']++; 

    for (i = 0; i < 9; i++) 
    { 

        // if freq[i] is not 
        // equal to freq[i + 1] at 
        // any index 'i' then set 
        // isBalanced to false 
        if (freq[i] != freq[i + 1]) 
            isBalanced = false; 
    } 

    // return true if 
    // the string is balanced 
    if (isBalanced) 
        return true; 
    else
        return false; 
} 

// Driver code 
int main() 
{ 
    int N = 1234567890; 
    bool flag = isNumBalanced(N); 

    if (flag) 
        cout << "YES"; 
    else
        cout << "NO"; 
} 

but I can't understand this code:

// store the frequency of
// the current digit
freq[st[i] - '0']++;

How this part actually working and storing frequency? And instead of this line, what else I can write?

  • 2
    Since you're asking how the shown code works, it must not be your code, but code that you got from somewhere else (which by the way exhibits a number of poor programming practices). This is yet another example that the only way to learn C++ is with a textbook, instead of some Youtube video or online hacking web site. The shown code is overengineered and quite convoluted, the correct approach takes about one third of the shown code, and does not involve any useless conversion to a `std::string`, but just some simple math. Wherever the code came from, it's a bad example to learn from. – Sam Varshavchik Sep 13 '20 at 00:35
  • There are several things going on in this line. There's array access, there's subtraction, there's integer promotion from `char` to `int` (and I guess `std::size_t`), and there's unary incrementation (`++`). Break the elephant down into individual bites. – JohnFilleau Sep 13 '20 at 00:38
  • 2
    [Why is “using namespace std;” considered bad practice?](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) – 463035818_is_not_an_ai Sep 13 '20 at 00:44
  • 2
    [Why should I not `#include `?](https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h) – 463035818_is_not_an_ai Sep 13 '20 at 00:44
  • 1
    Your words: "_I can't understand this code:_" . This is troublesome since it's supposed to be _your_ code. Voting to close. Focus on one problem only. – Ted Lyngmo Sep 13 '20 at 01:03

5 Answers5

2

st is a string and thus, a sequence of chars. st[i] is the ith char in this string.

Chars are actually positive integers between 0 and 256, so you can use them with mathematical operations, such as -. These integers are assigned to characters according to the ASCII alphabet. For example: The char 0 is assigned to 48 and the char 7 to 55 (Note: in the following, I use x to denote the character).

Their order makes it possible that mathematical operations are sensible as follows: The char 7 and the char 0 are exactly 7 numbers apart, so 0 + 7 = 48 + 7 = 55 = 7. So: 7 - 0 = 7.

So, you get the position in the freq array according to the number, i.e., the position 0 for 0 or position 7 for 7. The ++ operator increments that value in-place.

Green绿色
  • 1,620
  • 1
  • 16
  • 43
  • And instead of this line, what else I can write? – Priyaranjan Dash Sep 13 '20 at 17:53
  • 1
    I think, this line is good in its context. You can split it into multiple expressions to make it more understandable, but for an experienced C++ user, this is quite usual code. So, it is important to understand what this line means. A better solution to the whole problem would be not to convert the number to a string and instead directly calculate the frequency of digits within the realm of integers using division and modulo. Such a solution was proposed below as well. – Green绿色 Sep 14 '20 at 06:01
1

This line is several things condensed into one expression

freq[st[i] - '0']++;

The individual part are rather simple and in total it also isn't too difficult:

st[i] - '0' - character digits do not map 1 to 1 to integers. There is an offset. The integer value of '1' is 1 + '0', '2' is 2 + '0'. Hence to get the integer from the digit you need to subtract '0'.

freq[ ... ] - accesses the element of the array. Element at index i stores frequency of digit i.

()++ - increments that frequency by one.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • 1
    @LajosArpad Given that OP doesn't even know what the code is supposed to do I find it a bit bold to call an answer "correct". – Ted Lyngmo Sep 13 '20 at 01:16
  • @TedLyngmo the question is referring to a part of the code and asks us to explain it. When I called this answer "correct", my point was that someone with basic knowledge of the language, but confused about the code chunk outlined in the question should have a heureka moment reading the answer. I found it bold that you questioned my interpretation of the question. The question, in a quite clear way shows a small part of code which is unclear for the asker. If we try to be humble and nice, then of course both you and I understand the question. – Lajos Arpad Sep 13 '20 at 01:35
  • @LajosArpad I love that you found joy in the question and/or answer. I do like idclev's answers too - I've read a lot of them. I just found this particular one (like many of mine) a shot in the dark. It may be perfect for OP or it may not. I do not find the question as clear as you portray it to be. "_If we try to be humble and nice, then of course both you and I understand the question_" - I agree with the sentiment, but I still don't get the question fully. As I asked OP when the question was asked... – Ted Lyngmo Sep 13 '20 at 01:43
  • @idclev463035818 let's define what basic knowledge is. He/she knows how to define a variable, what types are in general and has used arrays a few times. Arithmetic computations with characters appear to be basic to you because you have been doing it for many year, probably. But that's not the case with someone eager to learn. Someone needs more than just a basic understanding in order to understand that st[i] - '0' is a conversion to a number used as index. – Lajos Arpad Sep 13 '20 at 01:47
  • 1
    @LajosArpad I removed my comments, all this really doesn't belong here. I do agree with Ted that your comment isn't very useful. You could have pointed me to typos or suggested an improvment, but "Another correct answer." just makes me wonder, how can you know? – 463035818_is_not_an_ai Sep 13 '20 at 02:10
  • @idclev463035818 "but I can't understand this code:" is pretty clear to me. If one provides an explanation of the code in question which we can expect the reader to understand, then that's correct in my book. – Lajos Arpad Sep 13 '20 at 13:05
  • @PriyaranjanDash who wrote that code if not you? Please add a proper reference to your question. – 463035818_is_not_an_ai Sep 13 '20 at 17:36
1

Subtracting the '0' character from the single string character results in the actual number you're looking for. This gives you the number whose frequency you are tracking in your code. This works because of the way characters are stored as ASCII values. Check out the table below. Say that the integer value N that is passed in is 1221. The first value observed in this example is '1' which corresponds to an ASCII value of 49. The ASCII value of '0' is 48. Subtracting the two: 49 - 48 = 1. This allows you to access each integer value individually as part of the array that was the result of the transformation of an 'int' value into a string.

ASCII Table

Athos
  • 21
  • 1
  • @LajosArpad Are you that sure that your interpretation of the question is correct? – Ted Lyngmo Sep 13 '20 at 01:10
  • @TedLyngmo Let's not spam this answer with the same discussion we are having at another thread. Having to react to this nitpicking and arrogant comment is not something I will do twice. – Lajos Arpad Sep 13 '20 at 01:38
  • @LajosArpad I agree. Why not remove these extra "yes, this is correct" and "no, I don't think so" comments?`I'm all in. – Ted Lyngmo Sep 13 '20 at 01:46
  • @TedLyngmo agreeing with other answerers is not redundant, because the other answerers are separate persons. Your nitpicking with my agreement is redundant. – Lajos Arpad Sep 13 '20 at 01:48
  • @LajosArpad I've agreed and disagreed with other answerers and been up and downvoted by the same people. We edit and help each other to get a good answer through - often when answering the same question. This is what I find motivating here. I learn a lot by that. In comments there are extras. If a comment claim an answer to be correct, it needs to be challenged - or transformed into an answer - if the claim isn't obviously perfect. – Ted Lyngmo Sep 13 '20 at 02:03
0

The code of

for (i = 0; i < n; i++) 

    // store the frequency of 
    // the current digit 
    freq[st[i] - '0']++; 

traverses the string and for each item, it subtracts '0', which has a value of 48, because character code 48 represents 0, character code 49 represents 1 and so on.

This code however is superfluos, wastes memory in storing a string and wastes time converting a number to a string. This is better:

bool isNumBalanced(int N)
{
    //We create an array of 10 for each digit
    int digits[10];
    //Initialize the difits
    for (int i = 0; i < 10; i++) digits[i] = 0;
    //If the input is 0, then we have a trivial case
    if (N == 0) return true;
    //We loop the digits
    do {
        //N % 10 is the last digit
        //We increment the frequency of that digit
        digits[N % 10]++;
    } while ((N /= 10) != 0); //We don't stop until we reach the trivial case, see above
    //Using the transitivity of equality, we compare all values to the first
    //We return false upon the first difference
    for (int j = 1; j < 10; j++)
        if (digits[0] != digits[j]) return false;
    //Otherwise we return true
    return true;
}
Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175
0

For those who don't understand it.

int arr[5]={0} // it stores 0 in all places
for(int i=0;i<5;i++){
  arr[i]++;
} // Now the array is [1 1 1 1 1]

what happened here is first i=0 then arr[0]++ "here arr[0] value was 0, ++, it increment 0 to 1" now arr[0] value is 1. Now ` let

   st="1221";

   for (i = 0; i < 4; i++) {

     freq[st[i] - '0']++;



for i=0, the freq location is : freq[49-48]++ = freq[1]++ means value of freq[1] is 1
for i=1, the freq location is : freq[50-48]++ = freq[2]++ means value of freq[2] is 1
for i=2, the freq location is : freq[50-48]++ = freq[2]++ means value of freq[2] is 2
for i=3, the freq location is : freq[49-48]++ = freq[1]++ means value of freq[1] is 2

ASCII value of '0' is 48

ASCII value of '1' is 49

ASCII value of '2'is 50