Finding the sum of digits in c++. Different method - c++

I am new to c++ and having trouble with a simple programme
I need to find the sum of digits I can do that in python but I don't know how to do the same in c++.
digits = "1234"
sum = 0
for digit in digits:
sum += int(digit)
print(sum)
How to do the same in c++?
I tried to do the same in c++ but ends up in a error.
string digits = "1234";
int sum, i;
for(i=0;i<digits.length();i++){
sum += stoi(digits[i]);
}
But this doesn't work

string digits = "1234";
int sum = 0;
for(int i = 0; i < digits.length(); i++){
sum += digits[i] - '0';
}
Characters have their numbers (ord). By working with characters in C++ you actually work with these numbers (so char is an integer type). For '0' it's some number, for '1' it's 1 + '0', for '2' it's 2 + '0' and so on. So by subtracting '0' you get the right digit.

Related

I don't understand the process converting string to int [duplicate]

This question already has answers here:
Why does subtracting '0' in C result in the number that the char is representing?
(8 answers)
Closed 1 year ago.
Given the following code.
this problem is Leet Code 415.
string addStrings(string num1, string num2) {
string res;
int sum = 0;
int i = num1.size() - 1;
int j = num2.size() - 1;
while(i >= 0 && j >= 0)
{
sum += (num1[i--] - '0') + (num2[j--] - '0'); // this problem point
res.push_back(char(sum%10 + '0'));
sum = sum/10;
}
while(i >= 0)
{
sum += (num1[i--] - '0');
res.push_back(char(sum%10 + '0'));
sum = sum/10;
}
while(j >= 0)
{
sum += (num2[j--] - '0');
res.push_back(char(sum%10 + '0'));
sum = sum/10;
}
if(sum > 0)
res.push_back(char(sum%10 + '0'));
reverse(res.begin(), res.end());
return res;
}
I don't understand the process converting string to int.
Why is it a int when I subtract '0' from string?
If it doesn't change int, how is it possible to operate on strings?
In c++ characters can be implicitly cast to integers using their ASCII codes. I don't really want to spoil the fun of solving the given problem so i'll just provide a hint here:
Given a single digit number '2' and '4' with an ASCII code of 50 and 52 (decimal) respectively, subtracting '0' with an ASCII code of 48 from both numbers, you get the actual numerical values of the characters (50-48 = 2) and so on.
Have fun coding!
So the way ascii works is that consecutive numbers are following each other. If a string of characters only contain digits, you can get those digits by subtracting the value '0' from them. In ascii '0' = 0x30, '1' = 0x31 etc..
In your code num[i--] - '0' just checks "how far" you are from '0' in the ascii table, giving the correct digit if it is indeed a digit.
Also you don't convert string to anything (at least on the specific line). You access an element, which is a char that is an integer type in c++.

unexpected value in my code and how I fix it

My assignment:
The teacher has written down the sum of multiple numbers. Pupils should calculate the sum. To make the calculation easier, the sum only contains numbers 1, 2 and 3. Still, that isn't enough for Xenia. She is only beginning to count, so she can calculate a sum only if the summands follow in non-decreasing order. For example, she can't calculate sum 1+3+2+1 but she can calculate sums 1+1+2 and 3+3.
You've got the sum that was written on the board. Rearrange the summons and print the sum in such a way that Xenia can calculate the sum.
Input
The first line contains a non-empty string s — the sum Xenia needs to count. String s contains no spaces. It only contains digits and characters "+". Besides, string s is a correct sum of numbers 1, 2, and 3. String s is at most 100 characters long.
Output
Print the new sum that Xenia can count.
Examples:
Input
3+2+1
Output
1+2+3
Here is my solution:
#include<string>
#include <iostream>
using namespace std;
int main()
{
string su ;
cin >> su;
int n, temp ;
n = su.size();
for (int i = 0 ; i < n ; i+=2)
{
if (su[i]=='1')
{
su[i]-='0';
}
else if (su[i]=='2')
{
su[i]-='0';
}
else if ( su[i]== '3')
{
su[i]-='0';
}
}
for (int i =0 ; i <n ; i+=2)
{
for(int j = 0 ; j< n; j+=2 )
{
if (su[i]< su [j])
{
temp = su[i];
su[i]=su[j];
su[j]=temp;
}
}
}
for(int i = 0 ; i < n ; i++)
{
if(su[i]=='+')
{
cout<<su[i];
}
else
cout<<su[i];//this is the line I can't understand why the result like that;
}
}
the problem is when I run the code with input 3+2+1 i expect the output is 1+2+3+ but I get ?+?+? something like that and I can't understand the reason.
First doing the s[i] -= '0' is very dangerous as it is a string, you should do int myNum = s[i] - '0' instead and then try storing it inside of the string, because when you do s[i] -= '0' it is never casted into an integer, but it stays char all the time so if you do not cast it to integer, it will go ascii code of '1' - '0' okay that is 1, which symbol has an ascii code of one? Oh it's the SOH character... And it takes the SOH character and put it inside of your string, but you string does not know what SOH is so it goes ???..(just joking, strings do not have emotions). All jokes aside the strange behavior is probably caused by you trying to store an illegal character inside a string. I would convert the '1' - '0' to int first.... Then store it in a string.

Why is there a need to add a '0' to indexes in order to access array values? [duplicate]

This question already has answers here:
What's the real use of using n[c-'0']?
(13 answers)
Closed 2 years ago.
I am confused with this line:
sum += a[s[i] - '0'];
To give some context, this is the rest of the code:
#include <iostream>
using namespace std;
int main() {
int a[5];
for (int i = 1; i <= 4; i++)
cin >> a[i];
string s;
cin >> s;
int sum = 0;
for (int i = 0; i < s.size(); i++)
sum += a[s[i] - '0'];
cout << sum << endl;
return 0;
}
- '0' (or less portable - 48, for ASCII only) is used to manually convert numerical characters to integers through their decimal codes, C++ (and C) guarantees consecutive digits in all encodings.
In EBCDIC, for example, the codes range from 240 for '0' to 249 for '9', this will work fine with - '0', but will fail with - 48). For this reason alone it's best to always use the - '0' notation like you do.
For an ASCII example, if '1''s ASCII code is 49 and '0''s ASCII code is 48, 49 - 48 = 1, or in the recommended format '1' - '0' = 1.
So, as you probably figured out by now, you can convert all the 10 digits from characters using this simple arithmetic, just subtracting '0' and in the other direction you can convert all digits to it's character encoding by adding '0'.
Beyond that there are some other issues in the code:
The array does not start being populated at index 0, but at index 1, so if your string input is, for instance, "10" the sum will be a[1] + a[0], but a[0] has no assigned value, so the behaviour is undefined, you need to wach out for these cases.
for (int i = 0; i < 5; i ++)
cin >> a[i];
would be more appropriate, indexes from 0 to 4, since the array has 5 indexes, if you want input numbers from 1 to 5, you can subract 1 from the to the index later on.
As pointed out in the comment section, a bad input, with alpabetic characters, for instance, will also invoke undefined behaviour.
From the C++ Standard (2.3 Character sets)
... In both the source and execution basic character sets, the value of
each character after 0 in the above list of decimal digits shall be
one greater than the value of the previous.
So if you have a character for example '4' then to get value 4 you can write '4' - '0'.
If you will write like for example
sum += a[s[i]];
where i is the character '0' then in fact you will have either
sum += a[s[48]];
if the ASCII coding is used or
sum += a[s[240]];
if the EBCDIC coding is used.
The reversed operation of getting a character from a digit you can write for example
int digit = 4;
char c = digit + '0';
Pay attention to that indices of arrays in C++ start from 0.
Thus this loop
for (int i = 1; i <= 4; i ++)
cin >> a[i];
should be written like
for (int i = 0; i < 5; i ++)
cin >> a[i];
Also to avoid such an error you could use the range based for loop like
for ( auto &item : a ) std::cin >> item;

Check if char array contains digits

So I have a random char array, i.e "asdd1vnb24vnf63vbn,-5h-2kk", and I should check if it contains digits, and if it does, my task is to add them with opposite signs (S=-1-2-4-6-3+5+2) without using string functions.
But for now I'm stuck here and simply cannot understand why it doesn't work and "Sum" gives random numbers, though it is able to print digits in an array.
int main ()
{
char s [] = "asdd1vnb24vnf63vbn,-5h-2kk";
int sum = 0;
for (int i = 0; i < sizeof(s)/sizeof(s[0]); i++) {
if (isdigit(s[i]) !=0) {
sum += s[i];
cout << "Sum is " << sum << endl;
}
}
system ("pause");
return 0;
}
Can somebody tell me what's wrong?
you add the ASCII value to sum variable not the integer value
only need little correction in your code in sum += s[i] to sum += s[i] - '0'
You should add not s[i], instead it should be s[i] - '0'.
Why?
s[i] is a char code, for 'zero' it could be 48, then 49 for 'one', 50 for 'two' and so on. So, you increment ascii code value instead of char value
Once you decrement s[i] with '0' char, you receive exact digit value (in case it is really a digit, because we don't see your isdigit implementation)
Besides the obvious sum += s[i] - '0' I see another problem - topic starter wont to inverse digits sign. So you need to check preceding '-' key:
if (isdigit(s[i])) {
if (i > 0 && s[i - 1] == '-')
sum += s[i] - '0';
else
sum -= s[i] - '0';
my task is to add them with opposite signs
If that's the case, in addition to the advice given in the other answers, you need to keep track of the polarity of the sign, whether it is negative or positive.
#include <iostream>
#include <cctype>
int main()
{
char ptr[] = "asdd1vnb24vnf63vbn,-5h-2kk";
int multiplier = 1; // this starts out at 1
char *p = ptr;
int value = 0;
while ( *p ) // keep going until the end of the string
{
if (isdigit(*p))
{
value += multiplier * (*p - '0');
multiplier *= -1; // switch polarity
}
++p;
}
std::cout << value;
}
Live Example

Add two octal numbers directly without converting to decimal

I'm trying to add two octal numbers by adding the corresponding digits but, I'm stuck when the case is that the sum of digits is greater than 7. I'll have to take a carry and add it to the next addition cycle. I'm unable to find the right expression to consider the carry and compute the final sum.
Another case to consider is when the octal numbers a and b do not have same number of digits, ex: 6 and 13 (6+13=21 in octal). I'm unable to establish a condition for the while loop for such a condition (if both have same number of digits I can run the while loop till either of them or both of them become zero)
Can somebody please help/complete the following code:
int octal_sum(int a,int b) //a and b and octal numbers
{
int sum=0,carry=0,d=0;
while(**???**)
{
d=0;
d=carry+(a%10)+(b%10);
a/=10;b/=10;
if(d>7)
{
carry=1;
d=d%8;
}
sum= **???**
}
return sum; //returns octal sum of a and b
}
Since you are passing ints, I assume that you are using decimal-coded octals*, i.e. decimal numbers that use only digits 0 through 7, inclusive. For example, number 1238 which is actually 8310 would be coded as 12310 using your scheme.
Deciding on the stopping condition - you want your while loop to continue until both numbers a, b, and carry turn zero. In other words, the condition should be a || b || carry
Adding the next digit to the sum - since the result is coded as decimal, you need to multiply digit d by the next consecutive power of ten. A simple way of doing that would be adding a new variable m which starts at 1 and gets multiplied by ten each iteration.
The result would look like this:
int octal_sum(int a,int b) {
int sum=0, carry=0, d=0, m = 1;
while(a || b || carry) {
d=0;
d=carry+(a%10)+(b%10);
a/=10;b/=10;
if(d>7) {
carry=1;
d=d%8;
} else {
carry = 0;
}
sum += d*m;
m *= 10;
}
return sum; //returns octal sum of a and b
}
Demo.
* This would be similar to Binary-Coded Decimal (BCD) representation, when a representation capable of storing hex digits is used to store decimal digits.
Here is the function I made. It is important to remember about the carry. Because if your numbers add up to be longer (ex: 7777 + 14 = 10013) if you ignore the carry, the code will only return four digits (your longest lenght of number), so 0013, which is 13. Not good. So we need to account for the carry. We must continue our loop until both our numbers and the carry are all 0.
Further more, if the digit you obtain by calculating a%10 + b%10 + carry is smaller than 8, then we no longer need to carry again, so we need to reset the value.
Note I'm using a digit rank integer, which basically allows me to add the digit to the beginning of the sum by multiplying by powers of ten and then adding it to the sum.
The final code looks like this.
int octal_sum(int a, int b)
{
int sum = 0, digit = 0, carry = 0, digit_rank = 1;
// Calculate the sum
while (a > 0 || b > 0 || carry)
{
// Calculate the digit
digit = a % 10 + b % 10 + carry;
// Determine if you should carry or not
if (digit > 7)
{
carry = 1;
digit %= 8;
}
else
carry = 0;
// Add the digit at the beggining of the sum
sum += digit * digit_rank;
digit_rank *= 10;
// Get rid of the digits of a and b we used
a /= 10;
b /= 10;
}
return sum;
}
Hope it helped you!
I am using StringBuilder to append character, which is better than using Strings, it's immutable.
2.read the char from String by converting String to char array, converting char to an integer by subtracting from its ASCII value '0'
make sure handle the carryforward case too
private static String OctaNumberAddition(String o1, String o2) {
StringBuilder sb = new StringBuilder();
int carry = 0;
for(int i = o1.length() - 1, j =o2.length()-1;i >= 0 || j >= 0;i--,j--){
int sum = carry + (i >= 0 ? o1.charAt(i) - '0':0)+(j >= 0 ? o2.charAt(j) - '0':0);
sb.insert(0,sum%8);
carry = sum /8;
}
if(carry > 0){
sb.insert(0,carry);
}
return sb.toString();
}