【问题标题】:Sum of digits in C#C#中的数字总和
【发布时间】:2010-10-03 11:59:05
【问题描述】:

计算数字和的最快和最容易阅读的实现是什么?

即给定数字:17463 = 1 + 7 + 4 + 6 + 3 = 21

【问题讨论】:

    标签: c# algorithm sum-of-digits


    【解决方案1】:
    public static int SumDigits1(int n)
    {
        int sum = 0;
        int rem;
        while (n != 0)
        {           
            n = Math.DivRem(n, 10, out rem);
            sum += rem;
        }
        return sum;
    }
    
    public static int SumDigits2(int n)
    {
        int sum = 0;
        int rem;
        for (sum = 0; n != 0; sum += rem)   
            n = Math.DivRem(n, 10, out rem);        
        return sum;
    }   
    
    public static int SumDigits3(int n)
    {
        int sum = 0;    
        while (n != 0)
        {
            sum += n % 10;
            n /= 10;
        }   
        return sum;
    }   
    

    完整代码在:https://dotnetfiddle.net/lwKHyA

    【讨论】:

      【解决方案2】:

      如果要执行特定操作,例如仅添加奇数/偶数,仅添加具有奇数索引/偶数索引的数字,那么以下代码最适合。在这个例子中,我从输入的数字中添加了奇数。

      using System;
                          
      public class Program
      {
          public static void Main()
          {
              Console.WriteLine("Please Input number");
              Console.WriteLine(GetSum(Console.ReadLine()));
          }
          
          public static int GetSum(string num){
              int summ = 0;
              for(int i=0; i < num.Length; i++){
                  int currentNum;
                  if(int.TryParse(num[i].ToString(),out currentNum)){
                       if(currentNum % 2 == 1){
                          summ += currentNum;
                      }
                  }
             } 
             return summ;
          }
      }
      

      【讨论】:

      • 原始问题不要求对奇数求和。请考虑更新您的答案以提供原始问题的解决方案。
      【解决方案3】:
      static int SumOfDigits(int num)
      {
          string stringNum = num.ToString();
          int sum = 0;
          for (int i = 0; i < stringNum.Length; i++)
          {
            sum+= int.Parse(Convert.ToString(stringNum[i]));
      
          }
          return sum;
      }
      

      【讨论】:

        【解决方案4】:
        int n = 17463; int sum = 0;
        for (int i = n; i > 0; i = i / 10)
        {
        sum = sum + i % 10;
        }
        Console.WriteLine(sum);
        Console.ReadLine();
        

        【讨论】:

        • 虽然这段代码 sn-p 可以解决问题,但including an explanation 确实有助于提高帖子的质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。
        【解决方案5】:

        很惊讶没有人考虑 Substring 方法。不知道它是否更有效。对于任何知道如何使用此方法的人来说,对于这种情况,它非常直观。

        string number = "17463";
        int sum = 0;
        String singleDigit = "";
        for (int i = 0; i < number.Length; i++)
        {
        singleDigit = number.Substring(i, 1);
        sum = sum + int.Parse(singleDigit);
        }
        Console.WriteLine(sum);
        Console.ReadLine();
        

        【讨论】:

          【解决方案6】:

          不久前,我必须找到某物的数字总和。我使用了 Muhammad Hasan Khan 的代码,但是它一直返回正确的数字作为循环小数,即当数字总和为 4 时,我会得到 4.44444444444444 等。 因此我对其进行了编辑,每次都使用此代码正确地得到数字总和:

           double a, n, sumD;
           for (n = a; n > 0; sumD += n % 10, n /= 10);
           int sumI = (int)Math.Floor(sumD);
          

          其中 a 是您想要其数字总和的数字,n 是用于此过程的双精度数,sumD 是双精度数字总和,sumI 是整数数字总和,因此是正确的数字总和。

          【讨论】:

            【解决方案7】:
            #include <stdio.h>
            
            int main (void) {
            
                int sum = 0;
                int n;
                printf("Enter ir num ");
                scanf("%i", &n);
            
                while (n > 0) {
                    sum += n % 10;
                    n /= 10;
                }
            
                printf("Sum of digits is %i\n", sum);
            
                return 0;
            }
            

            【讨论】:

              【解决方案8】:
              private static int getDigitSum(int ds)
              {
                  int dssum = 0;            
                  while (ds > 0)
                  {
                      dssum += ds % 10;
                      ds /= 10;
                      if (dssum > 9)
                      {                
                          dssum -= 9;
                      }
                  }
                  return dssum;
              }
              

              这是提供0-9之间的数字总和

              【讨论】:

                【解决方案9】:
                int j, k = 1234;
                for(j=0;j+=k%10,k/=10;);
                

                【讨论】:

                  【解决方案10】:

                  最简单的方法是使用循环到find sum of digits

                  int sum = 0;
                  int n = 1234;
                  
                  while(n > 0)
                  {
                      sum += n%10;
                      n /= 10;
                  }
                  

                  【讨论】:

                    【解决方案11】:

                    我想我只是为了完成而发布这个:

                    如果需要数字的递归总和,例如:17463 -> 1 + 7 + 4 + 6 + 3 = 21 -> 2 + 1 = 3
                    那么最好的解决方案是

                    int result = input % 9;
                    return (result == 0 && input > 0) ? 9 : result;
                    

                    【讨论】:

                    • 关闭,但应该是:return (result==0 && input>0) ? 9:结果;
                    【解决方案12】:

                    我喜欢 chaowman 的回应,但会做一些改变

                    int result = 17463.ToString().Sum(c => Convert.ToInt32(c));
                    

                    我什至不确定 c - '0',语法是否有效? (我认为减去两个字符应该得到一个字符?)

                    我认为这是最易读的版本(使用 sum 一词与 lambda 表达式相结合,表明您将为每个 char 执行此操作)。但事实上,我认为这不会是最快的。

                    【讨论】:

                    • 我迟到了 7 年,但由于某种原因,Convert.ToInt32 在我使用以下代码运行它时为我返回了4 * 54 = 2062156.ToString().Sum(c =&gt; Convert.ToInt32(c)); 知道发生了什么吗? c - '0' 工作得很好。
                    • @kuskmen 请参阅msdn.microsoft.com/en-us/library/ww9t2871(v=vs.110).aspx ... 字符串的迭代器对字符进行迭代 ToInt32() 的此调用返回一个 32 位有符号整数,该整数表示值的 UTF-16 编码代码单元论据。
                    • 所以我猜我在 2009 年的改进并不是真正的有效改进:-((所以忽略这个答案)
                    • Math.Abs(-123).ToString().Sum(char.GetNumericValue);
                    【解决方案13】:

                    我建议最容易阅读的实现是这样的:

                    public int sum(int number)
                    {
                        int ret = 0;
                        foreach (char c in Math.Abs(number).ToString())
                            ret += c - '0';
                        return ret;
                    }
                    

                    这很有效,而且很容易阅读。顺便说一句:Convert.ToInt32('3') 给出 51,而不是 3。Convert.ToInt32('3' - '0') 给出 3。

                    我认为最快的实现是 Greg Hewgill 的算术解决方案。

                    【讨论】:

                      【解决方案14】:
                      int num = 12346;
                      int sum = 0;
                      for (int n = num; n > 0; sum += n % 10, n /= 10) ;
                      

                      【讨论】:

                      • 虽然正确答案很多,但这应该是最好的正确答案
                      【解决方案15】:

                      对于整数,Greg Hewgill 有大部分答案,但忘记考虑 n

                      n = Math.Abs(n);
                      sum = 0;
                      while (n != 0) {
                          sum += n % 10;
                          n /= 10;
                      }
                      

                      如果数字是浮点数,应该采取不同的方法,chaowman的解决方案到了小数点就会完全失败。

                      【讨论】:

                      • 好收获。这完全取决于模运算符在相关语言中的定义方式;在 C# 中,结果与被除数采用相同的符号,这使我的方法因负数而失败。在其他语言中它可能有效,请参阅en.wikipedia.org/wiki/Modulo_operation 的表格
                      【解决方案16】:

                      我用

                      int result = 17463.ToString().Sum(c => c - '0');
                      

                      它只使用了 1 行代码。

                      【讨论】:

                      • 将整数转换为字符串以求和它的值并不是很有效。我也不认为这段代码特别可读。虽然我没有对此投反对票。
                      • 您忘记先将字符串转换为数组。 17463.ToString().ToCharArray().Sum(c => c - '0');
                      • 您不必先将其转换为数组。
                      • 非常好用的方法!
                      • 您能解释一下这是如何工作的吗?我不明白- '0'
                      【解决方案17】:
                       public static int SumDigits(int value)
                       {
                           int sum = 0;
                           while (value != 0)
                           {
                               int rem;
                               value = Math.DivRem(value, 10, out rem);
                               sum += rem;
                           }
                           return sum;
                       }
                      

                      【讨论】:

                      • 假设 DivRem 做了智能的事情,这应该避免做两次除法。我比其他明显的答案更喜欢它(尽管两者都很接近)。
                      • 这是 DivRem 的代码 public static int DivRem(int a, int b, out int result) { result = a % b;返回(a / b); } 所以它不会成为智能的东西!
                      • 任何合理的编译器都会看到 x 和 y 在 x/y 和 x%y 操作之间没有变化,因此可以使用单个除法操作来获得两个结果。我知道 gcc 为 c/c++ 代码执行此操作。我认为 c# 编译器至少可以胜任这种简单的优化。
                      • 这几乎肯定不是 C# 编译器会做的事情——这取决于 JIT。
                      • 很公平,我有点将 JIT 和适当的编译器归为一类,但是是的,JIT 会进行实际的优化。
                      【解决方案18】:

                      你可以在不使用字符串的情况下进行算术运算:

                      sum = 0;
                      while (n != 0) {
                          sum += n % 10;
                          n /= 10;
                      }
                      

                      【讨论】:

                      • 打败我。这是最好的方法。
                      • 就我个人而言,我认为这在概念上更适合作为 for 循环...但也许这只是我的想法,我倾向于将所有东西都更好地视为 for 循环...
                      • @monoxide,while 循环更简洁。您不需要索引或严格控制循环迭代。
                      • for (; n!= 0; n /= 10) { sum += n % 10;} 在我看来,那里有一个隐含的计数器,n。但众所周知,在谈论循环时,我的大脑工作起来很有趣。当然不需要初始化 n,因为大概是在循环之前处理的。
                      • +1:我喜欢这段代码,它非常优雅。对我来说并不陌生,但很酷。
                      猜你喜欢
                      • 1970-01-01
                      • 2019-03-24
                      • 1970-01-01
                      • 1970-01-01
                      • 2023-03-03
                      • 1970-01-01
                      • 1970-01-01
                      • 2020-04-22
                      • 1970-01-01
                      相关资源
                      最近更新 更多