Given this implementation of atoi in C++
// A simple atoi() function
int myAtoi(char *str)
{
int res = 0; // Initialize result
// Iterate through all characters of input string and update result
for (int i = 0; str[i] != '\0'; ++i)
res = res*10 + str[i] - '0';
// return result.
return res;
}
// Driver program to test above function
int main()
{
char str[] = "89789";
int val = myAtoi(str);
printf ("%d ", val);
return 0;
}
How exactly does the line
res = res*10 + str[i] - '0';
Change a string of digits into int values? (I'm fairly rusty with C++ to be honest. )
The standard requires that the digits are consecutive in the character set. That means you can use:
str[i] - '0'
To translate the character's value into its equivalent numerical value.
The res * 10 part is to shuffle left the digits in the running total to make room for the new digit you're inserting.
For example, if you were to pass "123" to this function, res would be 1 after the first loop iteration, then 12, and finally 123.
Each step that line does two things:
Shifts all digit left by a place in decimal
Places the current digit at the ones place
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.
So when looking at your example case the following would happen:
i = 0 → str[i] = '8': res = 0 * 10 + 8 = 8
i = 1 → str[i] = '9': res = 8 * 10 + 9 = 89
i = 2 → str[i] = '7': res = 89 * 10 + 7 = 897
i = 3 → str[i] = '8': res = 897 * 10 + 8 = 8978
i = 4 → str[i] = '9': res = 8978 * 10 + 9 = 89789
And there's your result.
The digits 0123456789are sequential in ASCII.
The char datatype (and literal chars like '0') are integral numbers. In this case, '0' is equivalent to 48. Subtracting this offset will give you the digit in numerical form.
Lets take an example:
str = "234";
to convert it into int, basic idea is to process each character of string like this:
res = 2*100 + 3*10 + 4
or
res = 0
step1: res = 0*10 + 2 = 0 + 2 = 2
step2: res = res*10 + 3 = 20 + 3 = 23
step3: res = res*10 + 4 = 230 + 4 = 234
now since each letter in "234" is actually a character, not int
and has ASCII value associated with it
ASCII of '2' = 50
ASCII of '3' = 51
ASCII of '4' = 52
ASCII of '0' = 48
refer: http://www.asciitable.com/
if i had done this:
res = 0;
res = res*10 + str[0] = 0 + 50 = 50
res = res*10 + str[1] = 500 + 51 = 551
res = res*10 + str[2] = 5510 + 52 = 5562
then i would have obtained 5562, which we don't want.
remember: on using characters in arithmetic expressions, their ASCII value is used up (automatic typecasting of char -> int). Hence we need to convert character '2'(50) to int 2, which we can accomplish like this:
'2' - '0' = 50 - 48 = 2
Lets solve it again with this correction:
res = 0
res = res*10 + (str[0] - '0') = 0 + (50 - 48) = 0 + 2 = 2
res = res*10 + (str[1] - '0') = 20 + (51 - 48) = 20 + 3 = 23
res = res*10 + (str[2] - '0') = 230 + (52 - 48) = 230 + 4 = 234
234 is the required answer
Related
Please, name thise methods.I new there, could you provide some reference?
char Time[] = "TIME:00:00:00";
void loop() {
Date[5] = gps.date.day() / 10 + 48;
Date[6] = gps.date.day() % 10 + 48;
Date[8] = gps.date.month() / 10 + 48; //Please, name thise methods.
Date[9] = gps.date.month() % 10 + 48;
Date[13] =(gps.date.year() / 10) % 10 + 48;
Date[14] = gps.date.year() % 10 + 48;}
Adding 48 is a way to convert a digit to a corresponding character. ASCII codes of digits start with 48 for '0'. so 5 + '0' is '5'.
x / 10 is division of x by 10. with integer division you get 2 from 23
x % 10 is modulo of x by 10. you get the remainder of division of x by 10. so you get 3 from 23.
So the code in question converts time digit by digit to a printable text.
This code outputs 12480.. Why? I expected it will print 124816. Could someone explain that to me?
int main()
{
char c = 48; // From ASCII one can find that char 48 represents 0.
int i , mask = 1;
for(i = 1; i <= 5; i++)
{
printf("%c", c|mask); // Here print the char formatted output
mask = mask << 1;
}
return 0;
}
You are printing one variable as char, you will never get 16 (which is two characters) out of that.
You have 48 = 110000, when you bitwise-or it with 1 you get 110001 = 49 which when translated from ASCII to a char would be equal to character 1.
The next time you get 110000 | 10 = 110010 = 50 which is 2.
This goes on until you reach 5th iteration when 110000 | 10000 = 110000 = 48 which is 0.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have a problem:
I have a N (N <= 40). N is a length of sequence of zeroz and ones. How to find the number of sequences of zeros and ones in which there are no three "1" together?
Example:
N = 3, answer = 7
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
Here's a solution using a recursive function :
(PHP code here, but it's really simple)
$seq = '';
function tree ($node, $flag, $seq)
{
if ($flag == 3) { return 0; }
if ($node == 0) { echo $seq, ' '; return 0;}
$seq1 = $seq.'1';
$seq2 = $seq.'0';
tree($node-1, $flag+1, $seq1);
tree($node-1, 0, $seq2);
}
tree(8, 0, $seq);
I use a tree to go through all the possible sequences, and a flag to check how many 1 in a row.
If there is two 1 in a row, then the flag reaches 3, and the function is stopped for this branch.
If we reach a leaf of the tree (ie. $node = 0), then the sequence is displayed, and the function ends.
Else, the function explores the two sub-trees starting from the current node.
void tree ( int node, int flag, std::string seq)
{
std::string seq1 = seq;
std::string seq2 = seq;
if(flag ==3) { return; }
if(node ==0) { printf("%s\n",seq.c_str()); return;}
seq1 += '1';
seq2 += '0';
tree(node-1, flag+1, seq1);
tree(node-1, 0, seq2);
}
You can write a grammar for the (non-empty) strings of this language. It's designed so that each string appears exactly once.
S := 0 | 1 | 11 | 10 | 110 | 0S | 10S | 110S
Let a_i be the total number of strings of length i in S.
First, look at the number of strings of length 1 on both sides of the grammar rule. There's a_1 in S by definition which deals with the left-hand-side.
a_1 = 2
For a_2, on the right-hand-side we immediately get two strings of length 2 (11 and 10), plus another two from the 0S rule (00 and 01). This gives us:
a_2 = 2 + a_1 = 4
Similarly, for a_3, we get:
a_3 = 1 + a_2 + a_1 = 7
(So far so good, we've got the right solution 7 for the case where the strings are length three).
For i > 3, consider the number of strings of length i on both sides.
a_i = a_{i-1} + a_{i-2} + a_{i-3}
Now we've got a recurrence we can use. A quick check for a_4...
a_4 = a_1 + a_2 + a_3 = 2 + 4 + 7 = 13.
There's 16 strings of length 4 and three containing 111: 1110, 0111, 1111. So 13 looks right!
Here's some code in Python for the general case, using this recurrence.
def strings_without_111(n):
if n == 0: return 1
a = [2, 4, 7]
for _ in xrange(n - 1):
a = [a[1], a[2], a[0] + a[1] + a[2]]
return a[0]
This is a dp problem. I will explain the solution in a way so that it is easy to modify it to count the number of sequences having no sequence a0a1a2 in them(where ai is arbitrary binary value).
I will use 4 helper variables each counting the sequence up to a given length that are valid and end with 00, 01, 10, and 11 respectively. Name those c00, c01, c10, c11. It is pretty obvious that for length N = 2, those numbers are all 1:
int c00 = 1;
int c01 = 1;
int c10 = 1;
int c11 = 1;
Now assuming we have counted the sequences up to a given length k we count the sequences in the four groups for length k + 1 in the following manner:
int new_c00 = c10 + c00;
int new_c01 = c10 + c00;
int new_c10 = c01 + c11;
int new_c11 = c01;
The logic above is pretty simple - if we append a 0 to either a sequence of length k ending at 0 0 or ending at 1 0 we end up with a new sequence of length k + 1 and ending with 0 0 and so on for the other equations above.
Note that c11 is not added to the number of sequences ending with 1 1 and with length k + 1. That is because if we append 1 to a sequence ending with 1 1 we will end up with an invalid sequence( ending at 1 1 1).
Here is a complete solution for your case:
int c00 = 1;
int c01 = 1;
int c10 = 1;
int c11 = 1;
for (int i = 0; i < n - 2; ++i) {
int new_c00 = c10 + c00;
int new_c01 = c10 + c00;
int new_c10 = c01 + c11;
int new_c11 = c01;
c00 = new_c00;
c01 = new_c01;
c10 = new_c10;
c11 = new_c11;
}
// total valid sequences of length n
int result = c00 + c01 + c10 + c11;
cout << result << endl;
Also you will have to take special care for the case when N < 2, because the above solution does not handle that correctly.
To find a number of all possible sequences for N bits are easy. It is 2^N.
To find all sequences contains 111 a bit harder.
Assume N=3 then Count = 1
111
Assume N=4 then Count = 3
0111
1110
1111
Assume N=5 then Count = 8
11100
11101
11110
11111
01110
01111
00111
10111
If you write simple simulation program it yields 1 3 8 20 47 107 ...
Subtract 2^n - count(n) = 2 4 7 13 24 44 81 149...
Google it and it gives OEIS sequence, known as tribonacci numbers. Solved by simple recurrent equation:
a(n) = a(n - 1) + a(n - 2) + a(n - 3)
i want to convert between char and int in c++ but i've found a problem with char to int conversion.
I did a test with two numbers, 103 and 155. 103 give me "g" in char and 155 give me "ø" and both are correct, but the problem is when i try to back chars to int: "g" give me 103 (correct) but i don't know why "ø" give me -101.
I'm using a char variable to store numbers, and "prinf("%d", char[x]);" to show back the number.
I've this test script:
#include <cstdlib>
#include <cstdio>
using namespace std;
int numero = 26523;
char *inttochar(int number) {
char *salida;
for (int j=0;j<=5;j++) {
salida[5-j] = number % 256;
printf("%d = %d = %c = %c = %d\n", 5-j, number % 256, number % 256, salida[5-j], salida[5-j]);
number = number / 256;
}
return salida;
}
int main(int argc, char** argv) {
char *texto = inttochar(numero);
for (int j=0;j<=5;j++) {
printf("%d: ", j+1);
printf("%c = %d\n", texto[j], texto[j]);
}
return 0;
}
And result is:
5 = 155 = ø = ø = -101
4 = 103 = g = g = 103
3 = 0 = = = 0
2 = 0 = = = 0
1 = 0 = = = 0
0 = 0 = = = 0
1: = 0
2: = 0
3: = 0
4: = 0
5: g = 103
6: ø = -101
With this script i want to convert a number to a base 256 char. ¿What i'm doing wrong?.
Thanks!!, and i'm sorry for my english.
Characters are signed values between -128 and 127 (on most systems). You're converting something from outside that range; the conversion to a char truncates but the bit pattern is OK. Converting the other direction puts you back into the range, and 155 isn't part of it. The bit pattern for 155 is 0x9b; to convert to a signed value you invert the bits and add one, so it becomes -0x65 which is -101 in decimal.
You can fix it with an and that strips off the extended sign bits: salida[5-j] & 0xff.
Edit: As noted in the comments your salida variable is intended to be a string but you never allocate any storage for it.
char *salida = new char[6];
char appears to be a signed type on your platform. That means 155 won't fit in it. You're getting that 155 interpreted as a 2's complement signed number, which equals -101.
How does this code concatenate the data from the string buffer? What is the * 10 doing? I know that by subtracting '0' you are subtracting the ASCII so turn into an integer.
char *buf; // assume that buf is assigned a value such as 01234567891234567
long key_num = 0;
someFunction(&key_num);
...
void someFunction(long *key_num) {
for (int i = 0; i < 18; i++)
*key_num = *key_num * 10 + (buf[i] - '0')
}
(Copied from my memory of code that I am working on recently)
It's basically an atoi-type (or atol-type) function for creating an integral value from a string. Consider the string "123".
Before starting, key_num is set to zero.
On the first iteration, that's multiplied by 10 to give you 0, then it has the character value '1' added and '0' subtracted, effectively adding 1 to give 1.
On the second iteration, that's multiplied by 10 to give you 10, then it has the character value '2' added and '0' subtracted, effectively adding 2 to give 12.
On the third iteration, that's multiplied by 10 to give you 120, then it has the character value '3' added and '0' subtracted, effectively adding 3 to give 123.
Voila! There you have it, 123.
If you change the code to look like:
#include <iostream>
char buf[] = "012345678901234567";
void someFunction(long long *key_num) {
std::cout << *key_num << std::endl;
for (int i = 0; i < 18; i++) {
*key_num = *key_num * 10 + (buf[i] - '0');
std::cout << *key_num << std::endl;
}
}
int main (void) {
long long x = 0;
someFunction (&x);
return 0;
}
then you should see it in action (I had to change your value from the 17-character array you provided in your comment to an 18-character one, otherwise you'd get some problems when you tried to use the character beyond the end; I also had to change to a long long because my longs weren't big enough):
0
0
1
12
123
1234
12345
123456
1234567
12345678
123456789
1234567890
12345678901
123456789012
1234567890123
12345678901234
123456789012345
1234567890123456
12345678901234567
As a shorter example with the number 1234, that can be thought of as:
1000 * 1 + 100 * 2 + 10 * 3 + 4
Or:
10 * (10 * (10 * 1 + 2) + 3) + 4
The first time through the loop, *key_num would be 1. The second time it is multiplied by 10 and 2 added (ie 12), the third time multiplied by 10 and 3 added (ie 123), the fourth time multiplied by 10 and 4 added (ie 1234).
It just multiples the current long value (*key_num) by 10, adds the digit value, then stores the result again.
EDIT: It's not bit-shifting anything. It's just math. You can imagine it as shifting decimal digits, but it's binary internally.
key_num = 0 (0)
key_num = key_num * 10 + ('0' - '0') (0)
key_num = key_num * 10 + ('1' - '0') (1)
key_num = key_num * 10 + ('2' - '0') (12)