简体   繁体   中英

Find the sum of digits of a sequence of integers

I made up my mind to write a little piece of code that gets two integers, lets say M and N ( M <= N ) and sum the digits of all the integers between them, inclusive. So for example if M = 1 and N = 9, DigitSum will equal to 45. If M = 10 and N = 11 the sum will be (1 + 0 (10) + 1 + 1 (11) = 3). Here is my code so far (Done the for loop instead of the return):

#include <iostream>
#include <vector>

using namespace std;
// the partial digits sums digitSum[i] = the sum of the digits between 0 and i
int digitSum[] = {0, 1, 3, 6, 10, 15, 21, 28, 36, 45};
int pow_of_ten[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
 // the sums of all the digits in the numbers from 1 to (10^(i) - 1) where i is the index in the array
long subsums[] = {0, 45, 20 * 45, 300 * 45, 4000 * 45, 50000 * 45, 600000 * 45, 7000000 * 45, 80000000 * 45,
    900000000 * 45};
//Calculates the sum of all digits between 0 and M inclusive
long Digit_Sum(int M) {

  if (M < 10) {
    return digitSum[M];
  }
  long result = 0;
  int same = M;
  int counter = 0;
  int lastdigit = 0;
  while (same > 0) {
    if (same <  10) {
      lastdigit = same;
      break;
    }
    same /= 10;
    counter ++;
  }
  for(;counter >= 0; counter --) {
    result += (subsums[counter] + M % pow_of_ten[counter] + 1) * lastdigit;
    result += digitSum[lastdigit - 1] * pow_of_ten[counter];
    if (counter == 0) {
      break;
    }
    lastdigit = (M / pow_of_ten[counter - 1]) % 10;
  }
  return result;

}

int main() {

int M;
int N;
vector<long> sums;
while (true) {
  cin >> M >> N;
  if (M == 0 &&  N == 0) {
    break;
  }
  sums.push_back(Digit_Sum(N) - Digit_Sum(M - 1));
}

for (vector<long>::iterator it = sums.begin(); it != sums.end(); ++it) {
  cout << *it << endl;
}
}

For most cases this works well but an Online judge says it is wrong. I looked at other solutions that work but no one hard-coded the values in arrays the way I did. May this cause a partial problem, any ideas?

You can easily just create a for-loop to greatly simplify this code.

There is no need to go through all that effort.

for (Initialization Action, Boolean Expression, Update_Action)

Re deletion below: sorry, I have a bit influenza and mizread N as M . :(

I think a main error is M-1 in

        sums.push_back(Digit_Sum(N) - Digit_Sum(M - 1));

Also noting that < when corrected that formula will only work for single-digit numbers . My comment earlier about using a simple formula was based on misunderstanding your problem description, in view of that formula and your examples. Both indicated single digit numbers only.

However, the complexity of the code appears unreasonably high. Consider this, assuming non-negative integers as input, and assuming m is always less than or equal to n :

#include <iostream>
#include <stdexcept>
using namespace std;

bool throwX() { throw std::runtime_error( "Ouch." ); }

auto main() -> int
{
    for( ;; )
    {
        int m, n;
        cin >> m >> n || throwX();
        if( m == 0 && n == 0 ) { break; }

        int sum = 0;
        for( int i = m; i <= n; ++i )
        {
            for( int v = i; v != 0; v /= 10 )
            {
                sum += v % 10;
            }
        }
        cout << sum << endl;
    }
}

It needs not be more complicated than that.

Tested and working to spec, sans console input:

#include <iostream>
#include <string>
using namespace std;

void sum_a_to_b(const int & a, const int & b)
{
    if (a <= b && a >= 0)
    {
        long long sum = 0;
        for (int i = a; i <= b; i++)
        {
            sum += i;
        }
        cout << "Sum of digits from " << a << " through " << b << " is " << sum << ".\n";
    }
}

int main()
{
    sum_a_to_b(5, 6);
    sum_a_to_b(1, 9);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM