【问题标题】:Find the sum of digits of a number(in c)找到一个数字的数字总和(在c中)
【发布时间】:2016-08-30 14:45:22
【问题描述】:

我需要找到一个数字的数字之和。比如数字1123的各位数字之和是1+1+2+3 =7

我的想法:

1)用户输入和整数

2)我计算数字中的位数(以上情况 - 4位)

3)与使用 for 循环相比,我将用户数除以 10 的 1,2 次方...直到位数(不包括最后一位)并将数字相加。

这是我的代码:

int main (void)
{
    int result,sum,n;
    int div = 10,counter = 0,number;

    printf("Enter the integer:");
    scanf("%i",&number);
    while(result >0){
        result = number/div;
        div *= 10;
        ++counter;
    }
    printf("The number consists of %i digits\n",counter);
    sum = 0;

    for(n=1;n<counter;++n){
        sum += number/pow(10,n);
    }
    printf("%i",sum);

    return 0;


}

第一部分(while 循环)分别工作正确。但与第二部分(for 循环)一起,它给了我不正确的结果(while 循环中的 0 位数字,总和也为零)。你能解释为什么会这样吗? 如何更正我的解决方案?

P.S 我知道我的问题存在更有效的解决方案,但我想使用自己的算法。

【问题讨论】:

  • 不要直接输入到 int 中。作为字符串输入。这使得长度计算变得微不足道,然后您将字符串视为 char aarray 并在各个数字上循环,将它们转换为 int 并加起来
  • 除以10 的幂你不会得到数字。需要同时使用模数10
  • div *= 10;一旦溢出就会出问题。
  • number &lt; 0 的问题没有明确定义。推荐unsigned number

标签: c loops


【解决方案1】:

这里有几个问题:

  • 当你第一次进入while循环时,result还没有被初始化。尝试读取未初始化的变量是 undefined behavior
  • 当您进行除法时,您不会添加数字。您将数字相加除以 10 的连续幂。在 1123 的情况下,您实际上是在相加 112 + 11 + 1。您需要使用模数而不是除法来获取数字。

您可以在一个循环中执行数字的添加和计数,如下所示:

sum = 0;
while(number > 0){
    sum += number % 10;
    number /= 10;
    ++counter;
}
printf("The number consists of %i digits\n",counter);
printf("%i",sum);

【讨论】:

    【解决方案2】:

    更简单:

    result = number;
    sum = 0;
    counter = 0;
    while(result != 0){
        sum += result % 10;
        result /= 10;
        ++counter;
    }
    
    printf ("Counter:%d sum:%d\n", counter, sum);
    

    【讨论】:

      【解决方案3】:

      首先,为了获得最佳调试效果,请使用具有不同数字的数字,例如 12345。

      要进行调试,请分别计算和打印数字而不是累加数字。也就是说,不是sum += &lt;... complex code ...&gt;,而是这样做:

      int digit = ...
      printf("Next digit is %i\n", digit);
      sum += digit;
      

      另外(你应该通过调试发现这一点,但很明显可以直接注意),你的数字计算算法是错误的。做这样的事情:

      int div = 1;
      for (...)
      {
          digit = number / div % 10;
          div *= 10;
      }
      

      注意我这里没有使用pow,因为pow使用的是浮点运算,精度有限。如果您的 int 具有 64 位精度(不太可能但有可能),浮点将计算大数的废话(它只有 53 位精度)。

      【讨论】:

      • pow() 限制的深入了解。
      【解决方案4】:

      代码中有很多错误,但总的来说整个方法是错误的。数位数是不必要的。

      更简单的方法是:

      unsigned temp = number, sum = 0;
      while (temp) {
        sum += temp % 10;
        temp /= 10;
      }
      

      请注意,您知道何时停止循环,因为temp 变为 0(作为条件的temp 等效于temp != 0)。您无需提前知道位数。

      【讨论】:

        【解决方案5】:

        如果使用您的代码,这将起作用:

        for(n=1;n<=counter;++n){
            sum += number%10;
            number /= 10;
        }
        printf("%d",sum);
        

        【讨论】:

          【解决方案6】:

          更简单的解决方案:

          int c, n=0, sum=0;
          printf("Enter number");
          while((c=getchar())!='\n') {    // IMPORTANT: '\n' in unix, '\r' in windows
              if(c<'0' || c>'9') {
                  printf("Bad value");
                  break;
              }
              sum+=c-'0';    // c is the ASCII code of the digit, so you have to subtract an offset
              n++;
          }
          printf("Number of digits: %d", n);
          printf("Sum of digits: %d", sum;
          

          【讨论】:

          • 谢谢,我已经修复了它们,还添加了一个 if 来检查字符是否真的是数字。
          • 你可以使用isdigit(char)函数来检查它是否是一个数字,atoi(char *)从char中获取一个整数
          • @Tiko 是的,但正如另一位用户指出的那样(现在已经删除了他的评论),getchar 返回一个 int,因为它也可以将 EOF 作为第 257 个代码返回。此外,调用函数来代替这种简单的操作并不是那么有效。特别是,如果要将字符串转换为整数, atoi 很方便,但事实并非如此。
          • 我认为您对 atoi 的看法是正确的,但如果 getchar 返回 257 就不会发生任何不好的事情
          • @Tiko 257 需要超过一个字节,因此您不能将其存储在字符中。您可以尝试执行 isdigit((char) int_variable),但根据机器的字节序,您可能会遇到麻烦。如果您尝试制作 atoi((char *) &int_variable),那就更糟了。
          猜你喜欢
          • 2022-08-20
          • 2019-02-01
          • 2010-11-16
          • 2017-05-15
          • 1970-01-01
          • 2022-01-09
          • 2021-06-14
          • 2017-06-06
          相关资源
          最近更新 更多