【问题标题】:Summing Large Numbers对大数求和
【发布时间】:2012-05-08 05:04:40
【问题描述】:

我在 Project Euler 网站上遇到了一些问题并且遇到了问题。问题要求“计算出以下一百个 50 位数字之和的前十位。”我猜有一些数学方法可以解决这个问题,但我只是想知道这么大的数字是如何相加的?我将数字存储为字符串并将每个数字转换为长数字,但数字太大以至于总和不起作用。

有没有办法将非常大的数字保存为变量(不是字符串)?我不希望代码解决问题,因为我想自己解决。

【问题讨论】:

  • 你试过数组吗?
  • 我在实现大整数时使用了std::deque <uint8_t>
  • 我没有尝试其中之一,但它可以将数字相加吗?它可以容纳它们,但我需要总结它们。
  • 有几个用于大整数运算的 C++ 库,例如 herehere
  • 我的猜测是想想你在上学的第一年是如何计算的。排列数字并一次添加一个数字。

标签: c++ string variables largenumber


【解决方案1】:

我只是想知道这么大的数字是如何相加的?

你可以使用数组:

long LargeNumber[5] = { < first_10_digits>, < next_10_digits>....< last_10_digits> };

现在你可以计算两个大数之和:

  long tempSum = 0;
  int carry = 0;
  long sum[5] = {0,0,0,0,0};

  for(int i = 4; i >= 0; i--)
  {
    tempSum = largeNum1[i] + largeNum2[i] + carry; //sum of 10 digits

    if( i == 0)
      sum[i] = tempSum; //No carry in case of most significant digit
    else
      sum[i] = tempSum % 1000000000; //Extra digits to be 'carried over'

    carry = tempSum/1000000000;
  }

  for( int i = 0; i < 5; i++ )
    cout<<setw(10)<<setfill('0')<<sum[i]<<"\n"; //Pad with '0' on the left if needed

有没有办法将非常大的数字作为变量(不是 字符串)?

这没有原语,你可以使用任何数据结构(数组/队列/链表)并适当地处理它

我猜有一些数学方法可以解决这个问题

当然!但是,

我不希望代码解决问题,因为我想自己解决这个问题。

【讨论】:

  • 当我解决了这个问题(使用python)时,我只保留了每个数字的前10-15,其余的都扔掉了。
【解决方案2】:

您可以将数字存储在数组中。为了节省空间并提高运算性能,请将数字的位数存储在以 10^9 为基数的范围内。所以一个数字 182983198432847829347802092190 将在数组中表示如下

arr[0]=2092190 arr[1]=78293478 arr[2]=19843284 arr[3]=182983

为了清楚起见,数字表示为 arr[i]*(10^9i) 的总和 现在从 i=0 开始,按照您小时候学习的方式开始添加数字。

【讨论】:

    【解决方案3】:

    我在java中做过,这里我取的是数字N1和N2,我创建了一个大小为1000的数组。让我们举个例子如何解决这个问题,N1=12,N2=1234。对于 N1=12,temp=N1%10=2,现在将此数字与数字 N2 从右到左相加,并将结果存储到从 i=0 开始的数组中,对于 N1 的其余数字类似。该数组将存储结果,但顺序相反。看看这个链接。请查看此链接http://ideone.com/V5knEd

    import java.util.*;
    import java.lang.*;
    import java.io.*;
    
    /* Name of the class has to be "Main" only if the class is public. */
    class Ideone
    {
        public static void main (String[] args) throws java.lang.Exception  {
            Scanner scan=new Scanner(System.in);
            int A=scan.nextInt();
            int B=scan.nextInt();
            int [] array=new int[1000];
            Arrays.fill(array,0);
            int size=add(A,B,array);
            for(int i=size-1;i>=0;i--){
                System.out.print(array[i]);
            }
        }
        public static int add(int A, int B, int [] array){
            int carry=0;
            int i=0;
            while(A>0 || B>0){
                int sum=A%10+B%10+carry+array[i];
                array[i]=sum%10;
                carry=sum/10;
                A=A/10;
                B=B/10;
                i++;
            }
            while(carry>0){
                array[i]=array[i]+carry%10;
                carry=carry/10;
                i++;
            }
            return i;
        }
    }
    

    【讨论】:

      【解决方案4】:
      #include<iostream>
      #include<fstream>
      #include<sstream>
      using namespace std;
      
      struct grid{
          int num[50];
      };
      
      int main()
      {
          struct grid obj[100];
          char ch;
          ifstream myfile ("numbers.txt");
          if (myfile.is_open())
          {
              for(int r=0; r<100; r++)
              {
                  for(int c=0; c<50; c++)
                  {
                      myfile >> ch;
                      obj[r].num[c] = ch - '0';
                  }
              }
              myfile.close();
              int result[50],temp_sum = 0;
              for (int c = 49; c>=0; c--)
              {
                  for (int r=0; r<100; r++)
                  {
                      temp_sum += obj[r].num[c];
                  }
                  result[c] = temp_sum%10;
                  temp_sum = temp_sum/10;
              }
              string temp;
              ostringstream convert;
              convert << temp_sum;
              temp = convert.str();
              cout << temp_sum;
              for(unsigned int count = 0; count < (10 - temp.length()); count++)
              {
                  cout << result[count];
              }
              cout << endl;
          }
          return 0;
      }
      

      【讨论】:

        【解决方案5】:

        这是节省您的时间和内存大小的最佳方式:D

        #include <iostream >
        #include <climits >
        
        using namespace std;
        
        int main()
        {
            unsigned long long  z;
        
            cin >>z;
        
            z=z*(z+1)/2;
        
            C out << z;
        
            return 0;
        }
        

        【讨论】:

        • 如果你想将 1 到用户输入的范围相加到 10^13 如果你想要超过 10^13 ....你可以将 unsigned long long 更改为 long双:D
        • 一个 unsigned long long 是否会存储 50 位数字?你检查了吗?
        猜你喜欢
        • 1970-01-01
        • 2011-06-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多