Display Individual Digits and Find Sum of an Integer

This is an exercise from a textbook

Problem:
Write a program that prompts the user to input an integer and then outputs both the individual digits of the number and the sum of the digits. For example, it should output the individual digits of 3456 as 3 4 5 6, output the individual digits of 8030 as 8 0 3 0, output the individual digits of 2345526 as 2 3 4 5 5 2 6, output the individual digits of 4000 as 4 0 0 0, and output the individual digits of -2345 as 2 3 4 5.

This problem was found in Chapter 5 of a C++ Textbook, which means, this problem was meant to be solved with the concepts covered by the first 5 chapters only.

Here are the Chapters and what each chapter covered
1. Chapter 2: Declare Variables, Variable Types, <iostream>
2. Chapter 3: Input / Output, <iomanip> <cmath> <fstream>
3. Chapter 4: Control Structure (Selection), if, else if, else, switch
4. Chapter 5: Control Structure (Repetition), while, do-while, for loop, nested loops


To solve this problem, this is the algorithm I used
1. Find the number of digits in a given integer
2. Find nth power of 10 with the # of digits so individual digits can be taken off from the left (Ex: 4321, take off 4 by dividing by 10^3)
3. Print each individual digit while calculating sum
4. Print sum

It took me some time, but eventually, I came up with a solution. I can usually solve a problem, but I find that the solution is sometimes more complicated than it needs to be and I can't seem to really optimize it.

If you can show me an example of a simpler and more efficient solution, I'd appreciate it.

To me, the goal is to improve my problem-solving skills with limited tools before I dive into more advanced C++ concepts.

Thank You.


This is my solution to the problem using only the concepts listed above.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#include <cmath>

int main ()
{
    int integer;
    int numberOfDigits = 0;
    int digit = 0;
    int sum = 0;

    std::cout << "Enter an integer: ";
    std::cin >> integer;
    std::cout << std::endl;

    integer = std::abs ( integer );         // Convert neg value to abs

    int copyInteger = integer;              // Create a working copy of integer

    // Find the number of digits
    do
    {
        numberOfDigits ++;

        copyInteger /= 10;
    }
    while ( copyInteger != 0 );

    int divisor = std::pow ( 10 , numberOfDigits - 1 );

    // Take out each digit from the left, calculate sum and print the digit
    do
    {
        digit = integer / divisor;                  // Take out a digit

        integer = integer - ( digit * divisor );    // Update integer

        std::cout << digit << ' ';

        sum += digit;

        divisor /= 10;                              // Take a zero off the divisor
    }
    while ( divisor > 0 );

    std::cout << "\nSum = " << sum << std::endl;

    return 0;
}
Last edited on
i already did this, but i only get the sum of even digits, but its almost the same :)
look:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>


int main()
{

    std::cout << "Enter a number: ";

    int number = 0;

    std::cin >> number;

    int trailingzeroes = 10;

    int sum = 0;
    for ( int a = 2; a < number*2; a*=10, trailingzeroes*=10 )
    {
            int ctr = 0;
            while( number%trailingzeroes != 0 )
            {
                --number;
                ++ctr;
            }
            ctr /= (trailingzeroes/10);
            if ( ctr % 2 == 0 )
            {
                sum+=ctr;
                std::cout << ctr << " + ";
            }
    }
    std::cout << "\b\b" << "= " << sum;
}
Last edited on
If you can use the <cmath> then the (numberOfDigits) can be acquired directly by the logarithmic function (log10f)
An interesting way to do it is with the recursive definition of a number.
A number ::= Digit || Number + Digit

So a number is either a digit, or a digit appended to another number. Thus you can do a recursive algorithm where if it's a digit, you're done. Otherwise it's call the function on the number and append the final digit.
Here is a working implementation.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
#include <vector>
#include <iterator>
#include <numeric>

// Assuming you want to store the digits, this could also simply print them. See below
void digitStore(int x, std::vector<int>& d) {
	if(x < 10) d.push_back(x);
	else {
		digitStore(x/10, d);
		d.push_back(x%10);
	}
}

int digitSum(int x, int count) {
	if(x < 10) {
		std::cout << x << " ";
		return x;
	}
	else {
		count = digitSum(x/10, count) + x%10;
		std::cout << x%10 << " ";
	}
	return count;
}
// Note that "copy" and "accumulate" could be replace by loops. But hey, it looks prettier.
int main() {
	std::vector<int> dig;
	digitStore(12345435, dig);
	std::copy(dig.begin(), dig.end(),
            std::ostream_iterator<int>(std::cout, " "));
	std::cout << std::endl;
	// To sum them, simply loop through the vector.
	std::cout << std::accumulate(dig.begin(), dig.end(), 0) << std::endl;
	// Now for the in place algorithm
	std::cout << std::endl << digitSum(12345435, 0) << std::endl;
	return 0;
}


1
2
3
Input = 12345435
Output = 1 2 3 4 5 4 3 5
                27
Here's mine.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <iostream>

// char to int
int ctoi(char c);
bool isdigit(char c);

int main()
{
    char number[100];
    std::cout << "Enter a number: ";
    std::cin.getline(number, 100);

    int sum = 0;
    for(int i = 0; ;i++){
        if(isdigit(number[i])){
            std::cout << number[i] << " ";
            sum += ctoi(number[i]);
        }
        else break;
    }

    std::cout << "\nSum: " << sum << std::endl;
}

int ctoi(char c)
{
    switch(c)
    {
    case '0':
        return 0;
        break;

    case '1':
        return 1;
        break;

    case '2':
        return 2;
        break;

    case '3':
        return 3;
        break;

    case '4':
        return 4;
        break;

    case '5':
        return 5;
        break;

    case '6':
        return 6;
        break;

    case '7':
        return 7;
        break;

    case '8':
        return 8;
        break;

    case '9':
        return 9;
        break;

    default:
        return -1;
        break;
    }
}

bool isdigit(char c)
{
    return (ctoi(c) != -1);
}



Enter a number: 1337
1 3 3 7
Sum: 14

Process returned 0 (0x0)   execution time : 3.524 s
Press any key to continue.


Could be better though... Would be so much more compact if you could use the string class.
Last edited on
You could also compact it by cutting out the switch block:
1
2
3
4
5
6
7
8
9
10
11
int ctoi(char c)
{
    if (c >= '0' && c <= '9')
    {
        return (int)(c - '0');
    }
    else
    {
        return -1;
    }
}
@obscure

You are right!. I played around with std::log10 and I was able to find the number of digits of a given integer. That allowed me to remove working copy of integer line and an entire do-while loop, greatly reducing the size of the code! Thanks.


@Semoirethe

I've read the chapter that covered recursion but I didn't have too much time playing around with recursion. I did create a simply program to calculate Factorial using recursion but that's about it. I can easily get a piece of paper and follow loop iterations, but I still have a hard time following recursion like loops. I will study your example later.

@integralfx and booradley60

I like that different approach - using char to get individual digits rather than integer. By the way, the textbook did touch <string> library, so you can definitely use std::string. The earlier chapters didn't cover array or user-defined functions, but it's all good. I like seeing different ideas.

Thank you all for the input. I'm marking it as resolved.
Topic archived. No new replies allowed.