4

I was going for the solution of a problem i had solved by myself. Many solutions i came across used this notation of str[i]-'0' to perform calculation on string str which has digits stored in it.

The code below compares two such strings, to count the digits which have same index position in both the strings and also maintains a separate count for the digits which appear in both the strings but don't have the same index.

My question is what is the purpose of guess[i] - '0'. How does it work in particular because i have been using int a = guess[i] all the time and want to know how the other method is better.

class Solution {
public:
    string getHint(string secret, string guess) {
        vector<int>tb_guess(10),tb_secret(10);
        int A=0,B=0;
        for (int i=0;i<secret.size();++i){
            if (secret[i]==guess[i]) A++;
            else {
                tb_guess[guess[i]-'0']++;
                tb_secret[secret[i]-'0']++;
            }
        }
        for (int i=0;i<10;++i){
            B=B+ min(tb_guess[i],tb_secret[i]);
        }
        return to_string(A)+'A'+to_string(B)+'B';
    }
};
Curt cobain
  • 147
  • 1
  • 2
  • 8

4 Answers4

8

if str contains stringified digits and you are using ASCII or EBCDIC encoding (or perhaps others), then str[i] - '0' converts the character at position i to a numeric digit.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • 5
    I felt that your answer was not precise enough; and SO encourages multiple answers. – Bathsheba Apr 29 '16 at 15:31
  • 2
    Indeed; the upvoters (of which I am one) thought so too. Be assured that I didn't paraphrase your answer! – Bathsheba Apr 29 '16 at 15:32
  • @user2079303: indeed. That's why I mention ASCII and EBCDIC as the two common cases where this approach works. – Bathsheba Apr 29 '16 at 15:35
  • @Bathsheba oh yea, you did say "perhaps others" OK, yours *is* more precise :) – eerorika Apr 29 '16 at 15:35
  • @all : So does it have any advantage over the method of storing char in int ,memory or speed wise ? – Curt cobain Apr 29 '16 at 15:37
  • 2
    I'd advise against using the idiom as it's not strictly portable: if you need to extract a number from a string then use one of the standard library functions. – Bathsheba Apr 29 '16 at 15:38
  • @Curtcobain: You're comparing apples and oranges. You _must_ do this (or something similar) to convert an ASCII "digit" to a number. Doesn't matter whether you put the result in a `char` or an `int`. – Lightness Races in Orbit Apr 29 '16 at 15:42
  • 2
    The C++ Standard requires that "In both the source and execution basic character sets, the value of each character after 0 in the list of decimal digits shall be one greater than the value of the previous." ([lex.charset](http://eel.is/c++draft/lex.charset#3)). This might imply that if you substract the character '0' from a decimal digit character, the result must be the numeric value of that digit character. – cpplearner Apr 29 '16 at 15:55
5

It converts a char to an integer by subtracting the ASCII value (48) of 0 from the char

'9' - '0' // 9

All this is assuming that the character is between chars 0 and 9 inclusive.

Ryan
  • 14,392
  • 8
  • 62
  • 102
  • That's not true, the statement depends on the current character table and that character values are encoded contiguously. – πάντα ῥεῖ Apr 29 '16 at 15:35
  • 2
    All character encodings follow the principle that numeric digis are encoded contiguously. Character encoding designers have understood that this principle is important since the early days of computing. – Barmar Apr 29 '16 at 15:56
  • @πάνταῥεῖ - C and C++ both require that the character codes for `'0'` through `'9'` are contiguous and increasing. – Pete Becker Apr 29 '16 at 18:36
  • @PeteBecker Sure. That's what I mentioned. – πάντα ῥεῖ Apr 29 '16 at 18:37
2

I don't have enough credits to comment below the answers. The question was elaborated well and detailed in another OS question atoi implementation in C++ by @sim642:

The part str[i] - '0' takes the ASCII character of the corresponding digit 
which are sequentially "0123456789" and subtracts the code for '0' from the 
current character. This leaves a number in the range 0..9 as to which digit is 
in that place in the string.

You can look at the ASCII table for the ASCII code of numbers.

//Suppose the char numbers are '0-9' and suppose they are ACSII:
'0' - '0' = 48 - 48 = 0
'1' - '0' = 49 - 48 = 1
'2' - '0' = 50 - 48 = 2
...

If they are not encoded in ASCII but in another style, the numbers are coded continuously, so the expression still holds.

Steinhafen
  • 61
  • 2
  • 5
0

The number which we are storing in a string is supposed to be 3 in string. Its ASCII value is 51 while printing string this will not create any problem but when we store value 3 as integer then it shows 51 so we have to subtract from it the 0th position ASCII value index which is 48. Example:

      `std::string s = "3a4";
       std::cout << (s[0] - '0') * (s[2] - '0');`

Output

12
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Feb 02 '22 at 20:13
  • @Charchit Bhatt: Thank you for your answer, and please improve your answer. To my knowledge 3a4 cannot be assigned to s. Compiler error: user-defined literal operator not found – Jörg Brüggmann Feb 02 '22 at 20:16
  • @Charchit Bhatt: Please, format your code using the provided formating syntax. – Jörg Brüggmann Feb 02 '22 at 20:18