I tried to solve the problem on my own but got stuck after a while so looked at the solution.Question #8. And this is what I got.
#include <stdio.h>
int main(void)
{
char str[] =
"73167176531330624919225119674426574742355349194934"
"96983520312774506326239578318016984801869478851843"
"85861560789112949495459501737958331952853208805511"
"12540698747158523863050715693290963295227443043557"
"66896648950445244523161731856403098711121722383113"
"62229893423380308135336276614282806444486645238749"
"30358907296290491560440772390713810515859307960866"
"70172427121883998797908792274921901699720888093776"
"65727333001053367881220235421809751254540594752243"
"52584907711670556013604839586446706324415722155397"
"53697817977846174064955149290862569321978468622482"
"83972241375657056057490261407972968652414535100474"
"82166370484403199890008895243450658541227588666881"
"16427171479924442928230863465674813919123162824586"
"17866458359124566529476545682848912883142607690042"
"24219022671055626321111109370544217506941658960408"
"07198403850962455444362981230987879927244284909188"
"84580156166097919133875499200524063689912560717606"
"05886116467109405077541002256983155200055935729725"
"71636269561882670428252483600823257530420752963450";
size_t len = sizeof str - 1;
size_t i;
unsigned max = 0;
for (i = 0; i < len-4; i++) {
unsigned p = 1;
size_t j;
for (j = 0; j < 5; j++) {
p *= (unsigned)(str[i+j]-'0');
}
if (p > max) {
max = p;
}
}
printf("%u\n", max);
return 0;
}
My Problem : I didn't understand why there was -'0' in this line
p *= (unsigned)(str[i+j]-'0');
Sorry if my question is very stupid. But I can't seem to figure it out.
'0' - '0' == 0
'1' - '0' == 1
'2' - '0' == 2
etc.
Basically, it's for converting a char to its corresponding digit.
An explanation is that characters map directly to ASCII values:
'0' == 48
'1' == 49
'2' == 50
etc.
And the values are sequential. Therefore, when you subtract the lowest digit, you get the position after that digit, which will also be the int value of the digit.
Because that large block of digits is a string, each character is a text representation of a number rather than the number itself. If we take, for example the point at which i = 0 and j = 0, then str[i+j] is '7', note the quotes.
Now, characters in C are typically represented in ASCII, where every character is represented by a number from 0 to 255. '7' when converted to its numeric representation is equal to 55. See here for a table of ASCII values: http://www.asciitable.com/.
Note, now that all the numbers are sequential. The value of '0' is 48 and 57 minus 48 is 7. Subtracting '0' from a character representing a digit is a way to convert it back into the numeric representation of the digit.
Related
So I was assigned to store two 50 digit integers in c language and do math equations using them. the problem for me was to store the input digit by digit in an array. I figured that I can store the input in a char string like this:
#include <stdlib.h>
#include <stdio.h>
int main ()
{
char string_test [50];
scanf("%s", string_test);
return 0;
}
But I couldn't use it as a number because it was stored as char and I couldn't copy them digit by digit into another array which was defined as int
after a whole day of searching, I found out that I need to copy my string one by one like this:
#include <stdlib.h>
#include <stdio.h>
int main ()
{
char string_test [50];
scanf("%s", string_test);
int arr[50];
for (int i = 0; i < 50; i++)
{
arr[i] = string_test[i] - '0';
}
return 0;
}
Now my question is why do I need to subtract '0' to get a suitable result?
The ASCII values for digits 0 - 9 are:
Digit 0 1 2 3 4 5 6 7 8 9
ASCII value 48 49 50 51 52 53 54 55 56 57
So if you have a string representation of an integer, say
char int_str[] = "123456";
and need to convert each char to its numeric value, subtracting the value for '0' (48) from each will will result in the values
int_str[0] == '1' ==> '1' - '0' ==> 42 - 41 == 1
int_str[1] == '2' ==> '2' - '0' ==> 43 - 41 == 2
int_str[2] == '3' ==> '3' - '0' ==> 44 - 41 == 3
int_str[3] == '4' ==> '4' - '0' ==> 45 - 41 == 4
int_str[4] == '5' ==> '5' - '0' ==> 46 - 41 == 5
int_str[5] == '6' ==> '6' - '0' ==> 47 - 41 == 6
To get digits 1 2 3 4 5 6 into the integer 123456 requires additional steps:
This example uses the same conversions encapsulated into a function to convert discrete char digit to int digit values, then assimilate each discrete int digit value into the composite integer value:
int main(void)
{
char str[] = "123456";
int int_num = str2int(str);
return 0;
}
int str2int(char *str)
{
int sum=0;
while(*str != '\0')
{ //qualify string
if(*str < '0' || *str > '9')
{
printf("Unable to convert it into integer.\n");
return 0;
}
else
{ //assimilate digits into integer
sum = sum*10 + (*str - '0');
str++;
}
}
return sum;
}
A char like '0' is just an ASCII representation of a 1 byte number. The numeric representations of these characters can be found in the manual (man ascii). Here you will see that '0' actually represents number 48 or 0x30 and that ASCII '0' to '9' are consecutive.
To convert a numeric char value to its integer counterpart, it is necessary to subtract this value of 48 or '0'.
I hope this clears things up. For further info, look into char arithmetic in C.
This is actually related to the ASCII code representation of numbers; when you input a character, '0', it is stored in memory as value 48 (in decimal) and also any other number or character.
You will find that the ASCII code value for '1' is 49 so, if we applied the operation, int x = '1' - '0';, we are storing the decimal value 1 in x and dealing with it as a number, not a character any more.
You can search more about ASCII codes; it's a very useful topic for any programmer.
Hi i'm fairly new to c but for a program I'm writing I need to convert binary strings to decimal numbers. here is my current code:
int BinaryToInt(char *binaryString)
{
int decimal = 0;
int len = strlen(binaryString);
for(int i = 0; i < len; i++)
{
if(binaryString[i] == '1')
decimal += 2^((len - 1) - i);
printf("i is %i and dec is %i and the char is %c but the length is %i\n", i, decimal, binaryString[i], len);
}
return decimal;
}
int main(int argc, char **argv)
{
printf("%i", BinaryToInt("10000000"));
}
and here is the output:
i is 0 and dec is 5 and the char is 1 but the length is 8
i is 1 and dec is 5 and the char is 0 but the length is 8
i is 2 and dec is 5 and the char is 0 but the length is 8
i is 3 and dec is 5 and the char is 0 but the length is 8
i is 4 and dec is 5 and the char is 0 but the length is 8
i is 5 and dec is 5 and the char is 0 but the length is 8
i is 6 and dec is 5 and the char is 0 but the length is 8
i is 7 and dec is 5 and the char is 0 but the length is 8
5
I'm confused as to why this doesn't work, all help is greatly appreciated. Thanks in advance!
Ps: I'm used to java so at the moment C just makes me cry
The ^ operator is not for exponentiation, but is instead the bitwise XOR operator.
If you want to raise a number to a power of 2, use the left shift operator << to shift the value 1 by the exponent in question.
decimal += 1 << ((len - 1) - i);
The trick is the same as with any number base: for each incoming digit, multiply the accumulator by the number base and add the digit.
#include <stdio.h>
#include <string.h>
int BinaryToInt(char *binaryString)
{
int decimal = 0;
int len = strlen(binaryString);
for(int i = 0; i < len; i++) {
decimal = decimal * 2 + binaryString[i] - '0';
}
return decimal;
}
int main(void)
{
printf("%d", BinaryToInt("10000000"));
return 0;
}
Program output:
128
int atoi(char* s)
{
int i,n;
n=0;
for (i=0; (s[i]>='0') && (s[i]<='9'); i++)
n = 10 * n + (s[i] - '0');
return n;
}
In this code what is s[i]-'0' doing? Can anyone please explain the detailed working of this function?
Have a look at the table in the link below-
http://www.asciitable.com/
The table is called ASCII Table and it is one of the character-encoding schemes used to represent characters in the binary world.
You can see the decimal numbers 0-9 are represented by numbers 48-57 in the ASCII table. All digits(0-9) are stored as characters.
If your computer stores 48 for decimal number 0, 49 for decimal number 1, 50 for decimal number 2 and so-on.
Then, to convert a ASCII number into decimal number, you just need to subtract 48 from ASCII number.
For example,
48 - 48 => 0
49 - 48 => 1
50 - 48 => 2
.. and so-on
'0' also represents 48. It is a character form of number 48. That's why, the equation n = 10 * n + (s[i] - '0'); has '0'.
In this code what is s[i]-'0' doing?
In C, each character like '0', 'A', '+', ' ' is assigned a numeric value or code. C requires that the codes for '0', '1', '2' ... '9' are sequential but does not specify their values.
When code performs the below test, it knows that s[i] has a value within codes '0' and '9'. Since these codes are sequential, the only values s[i] could have are '0', '1', '2' ... '9'.
(s[i]>='0') && (s[i]<='9')
By subtracting '0' from s[i], code obtains the difference:
`0`-'0' --> 0
`1`-'0' --> 1
`2`-'0' --> 2
...
`9`-'0' --> 9
Code has successfully translated the character code for an numeric character into a corresponding integer value.
In your function, s is a sequence of ASCII encoded characters: a string. Actually, the encoding does not matter as long as it has the characters 0 through 9 as a sequence. Let's say it has the value "123ABC", for this explanation.
n is the output number. At the start of the function it is initialized to zero.
In the first iteration of the loop we have
i=0
s[i] = '1' (which is encoded as 49, in ASCII)
n = 0
so the math is like this:
n = n * 10 + (s[i] - '0')
n = 0 * 10 + ('1' - '0')
n = '1' - '0'
And converting the character syntax to the ASCII encoding gives this:
n = 49 - 48
n = 1
In the next iteration we have:
i = 1
s[i] = '2' (ASCII 50)
n = 1
n = n * 10 + (s[i] - '0')
n = 1 * 10 + ('2' - '0')
n = 10 + ('2' - '0')
n = 10 + (50 - 48)
n = 10 + 2
n = 12
And, in the third iteration:
i = 2
s[i] = '3' (ASCII 51)
n = 12
n = n * 10 + (s[i] - '0')
n = 12 * 10 + ('3' - '0')
n = 120 + ('3' - '0')
n = 120 + (51 - 48)
n = 120 + 3
n = 123
And, in the final iteration s[i] = 'A' which is not in the range specified by the if statement, so the loop exits.
As you can see it has correctly converted the string "123" to the number 123.
I quite don't know what this loop does.
int atoi(char s[])
{
int i, n;
n = 0;
for (i = 0; s[i] >= '0' && s[i] <= '9'; ++i)
n = 10 * n + (s[i] - '0');
return n;
}
This part I don't get:
for (i = 0; s[i] >= '0' && s[i] <= '9'; ++i)
n = 10 * n + (s[i] - '0');
I get the whole for loop inside parentheses, and what s[i] - '0' does.
But I don't get what kind of operation is going on here --> n = 10 * n.
I don't know what n is representing and why is multiplying 10.
I know it's converting string of digits to numeric equivalent, but I just don't get the whole operation there.
But I don't get what kind of operation is going on here --> n = 10 * n
That's just how you build a number digit by digit. It's basically the same as it would work if you were writing a calculator. If I wrote a simple calculator, here's how it would handle the input 547:
Start with 0
5 ==> 0*10 + 5 = 5
4 ==> 5*10 + 4 = 54
7 ==> 54*10 + 7 = 547
Basically, atoi does, the exact same thing, but instead of reading each digit from button presses, it's reading them from a string. Each time you read a new digit, you do n *= 10 to make room for that next digit, which just gets directly added on the end.
n is the digits that has already been processed. For instance, for the string "123", first, the program gets digit 1, convert it to integer and store it in n, and then get the next digit 2, this is where n = 10 * n is useful, the previous 1 is multiplied by 10, and added to the next digit 2, the result is 12, and this is stored as the current n.
The same goes on, when processing 3, the previous stored 12 is multiplied by 10, results in 120 and added to 3, ended as 123 as result.
I have a string which may contain either single integers between 0-9 or mathematical operators (+, -, *, /).
Basically, I need to read in all characters / numbers. I am checking if the character is either +,-,* or /. If not, then I know it is either a number or an invalid character. I am using atoi to convert it to an integer. atoi will return 0 in both cases: if the integer is a 0 OR if it was an invalid character.
How else can I make this distinction?
Check each character with standard isdigit() function before using atoi
Use strtol to perform error detection.
int main (void)
{
int i, j ;
char num_string[] = "1 234 23 45" ;
char tmp [2] = {'\0', '\0'} ;
int length = strlen (num_string) ;
int* values = (int*) malloc (sizeof (int) * length) ;
for ( i = 0, j = 0; i < length; ++i)
{
if ( isdigit (num_string[i] ) )
{
tmp [0] = num_string [i] ;
values [j++] = atoi (tmp) ;
}
}
printf ("\nThe string: %s", num_string) ;
printf ("\nThe integer array which results is: ") ;
for ( i = 0; i < j; ++i)
printf (" %d ", values[i]) ;
return 0 ;
}
input:
1 22 33 4 555
output:
1 2 2 3 3 4 5 5 5