I\'m trying to learn c++ on my own and I\'ve hit a bit of a road block. The problem is I need to take an integer,split it into its digits and get the sum of the digits and
Your indention is hideous. That said, the reason your digits are coming out in reverse order is pretty simple: you're getting the digits in reverse order. Think about it: you're taking a remainder of the number divided by ten, then printing the remainder. Then you divide the number by 10... and so on. You should store the digits in an array, then print the array in reverse order.
And learn to indent.
You're going to have to store them and print them out in reverse order, or else do some recursion and print out after the recursive call.
int printdigits(int number)
{
if (number == 0)
return 0;
int digit = number % 10;
int sum = printdigits(number / 10);
cout <<digit << " ";
return sum+digit;
}
I will put an example up in good faith that you will not reproduce it, if this is a homework assignment, use it as a chance to learn...
// reference: www.cplusplus.com
#include <iostream>
#include <iterator>
#include <vector>
#include <algorithm>
#include <numeric>
using namespace std;
// What does this do?
template <typename T>
struct gen
{
gen(T start) : _num(start) {}
// Do we need these? But why have I commented them out?
//gen(gen const& copy) : _num(copy._num) {}
//gen& operator=(gen const& copy) { _num = copy._num; }
//~gen() {}
// Why do we do this?
T operator()() { T digit = _num % 10; _num /= 10; return digit; }
T _num;
};
// How is this different to the above?
template <typename T>
bool check_non_zero (T i)
{
return i != 0;
}
// And this? what's going on here with the parameter v?
template <typename T, int _size>
T sum_of_digits(T value, std::vector<T>& v)
{
// Why would we do this?
if (value == 0)
{
v.push_back(0);
return 0;
}
// What is the purpose of this?
v.resize(_size);
// What is this called?
gen<T> gen_v(value);
// generate_n? What is this beast? what does v.begin() return? where did _size come from?
generate_n(v.begin(), _size, gen_v);
// reverse? what does this do?
reverse(v.begin(), v.end());
// erase? find_if? what do they do? what the heck is check_non_zero<T>?
v.erase(v.begin(), find_if(v.begin(), v.end(), check_non_zero<T>));
// what the heck is accumulate?
return accumulate(v.begin(), v.end(), 0);
}
int main()
{
// What does this do?
vector<int> v;
// What is this peculiar syntax? NOTE: 10 here is because the largest possible number of int has 10 digits
int sum = sum_of_digits<int, 10>(123, v);
cout << "digits: ";
// what does copy do? and what the heck is ostream_iterator?
copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));
cout << endl;
cout << "sum: " << sum << endl;
// other things to consider, what happens if the number is negative?
return 0;
}
Stack and recursion is overkill for this problem. Just store each digit into a string and then reverse it before output. You need to work out how to call reverse
with the string
members for this to work. for_each can be used to output each element of the string.
For extra credit (by virtue of conciseness and expressiveness), insert the number directly into an ostringstream and use that as the basis for your reversible string
.
My stringstream
version of this code is 5 lines long. Logic is:
for_each
.You can sum the digits using accumulate on the string, provide you account for the fact that int('1') != 1
. That's an extra two lines, to sum the digits and output the result.
The point is not that doing this via stack or recursion is BAD, it's just that once you get more familiar with the STL there are typically more elegant ways to do a job than the obvious. Implementing this using stack, recursion and any other ways you can think of makes a simple homework into a great real-world learning experience.
Here's the accumulate
code to sum the members of a string
consisting of decimal digits, for example:
#include <string>
#include <numeric>
std::string intString("654321");
int sum = accumulate(intString.begin(), intString.end(), 0) -
(intString.size() * int('0'));
EDIT: here's the full code, for comparative purposes:
ostringstream intStream;
int value(123456);
intStream << value;
string intString(intStream.str());
for_each(intString.begin(), intString.end(), [] (char c) { cout << c << endl; });
int sum = accumulate(intString.begin(), intString.end(), 0) -
(intString.size() * int('0'));
cout << "Sum is " << sum << endl;
Being a sum does not really matter the order, but the logic you are using splits it from the least significant digit to the most significant ( and is the easiest way).
digit = number % 10;
This operation will return the the right most number.
so when you try to your app with an input "1357", on the first run through the while loop, it will return 7. Next it will return 5, and so on.
If all you want is the sum of the individual digits, then the order you get them (and print them out) will not affect the final answer. If you still want them to printed in the correct order, you can store the digits in an array (or Vector or Stack, as others have mentioned), reverse the contents, and then loop through the structure, to print out its contents.