【问题标题】:Adding two strings mathematically?在数学上添加两个字符串?
【发布时间】:2013-10-16 05:33:12
【问题描述】:

我浏览了论坛,但仍然找不到我的问题的答案。 我有两个字符串,它们实际上是一个数字数组。例如(我只是选择随机数

    string input1="12345678909876543212";
    string input2="12345";

我想把这两个字符串加在一起,但把它们当作整数。 我的目标是创建一个类,我可以在其中添加比 (long long int) 更大的数字,这样它就可以超过最大的 long long int 变量。

所以我修改字符串没有问题,所以现在有

  input1="21234567890987654321" 
  input2="54321"

然后我尝试添加,比如说 input1[0]+input2[0] (2+5) 到一个新字符串,让我们称它为 newString[0] 等于 (7);但我找不到一个好方法来临时转换字符串中的当前数字,以便我可以将它添加到新字符串中?谁能帮忙。我厌倦了atoi,stof,stod。他们似乎根本不适合我。 任何方式我都可以使这个功能工作。 我还不关心制作课程,我只关心找到一种方法以数学方式添加这两个字符串,但仍保持 newString 的字符串格式。谢谢谁能帮我解决这个问题

【问题讨论】:

标签: c++ string int converter


【解决方案1】:

我对 C++ 不是很熟悉,但我们不能这样做吗?

   int i = stoi( input1[0]); 
     int j = stoi( input2[0]);
     int x = i+j;

请注意,这可以在 C++11 中完成,请参考 [1]2 以及

【讨论】:

  • 编译器对此抱怨。老实说,我不知道是什么。
  • 您使用的是 C++11 吗?你也可以试试这个 std::string s = "21234567890987654321"; int i = std::stoi(s);
  • for(i=0; 0
【解决方案2】:

您可以通过从中减去 '0' 将 char 转换为 int:

char sumdigit = (input1[0]-'0') + (input2[0]-'0') + '0';

【讨论】:

    【解决方案3】:

    atoi() 会更好,只要将input[0] 转换为 int:

    int temp = atoi(input.substr(0,1).c_str());
    

    然后使用stringstream转回字符串:

    stringstream convert;
    convert << temp;
    string newString = convert.str();
    

    【讨论】:

      【解决方案4】:

      好吧,假设你唯一的问题是逻辑,而不是类设计问题,我想出了这个逻辑

      • 用 0 填充输入,检查长度,匹配长度
      • 像正常添加一样添加,跟踪进位
      • 最终从结果中删除前导零

      所以在反向迭代器上使用 std::transform 和 lambda 函数:-

      char carry = 0;
      
      std::transform(input1.rbegin(),input1.rend(),input2.rbegin(),
                    result.rbegin(),[&carry]( char x,  char y){
          char z = (x-'0')+(y-'0') + carry;
          if (z > 9)
          {
              carry = 1;
              z -= 10;
          }
          else
          {
              carry = 0;
          }
          return z + '0';
      });
      
      //And finally the last carry
      result[0] = carry + '0';
      
      //Remove the leading zero
      n = result.find_first_not_of("0");
      if (n != string::npos)
      {
          result = result.substr(n);
      }
      

      Here

      编辑 “你能评论一下你在这里做什么吗?”

                      +--------+--------------+------------+-------> Reverse Iterator
                      |        |              |            |
      std::transform( | input1.rbegin(), input1.rend(),input2.rbegin(),
                     result.rbegin(), [&carry]( char x,  char y){
                     //This starts a lambda function
          char z = (x-'0')+(y-'0') + carry; // x,y have ASCII value of each digit
          // Substracr ASCII of 0 i.e. 48 to get the "original" number
          // Add them up
          if (z > 9) //If result greater than 9, you have a carry
          {
              carry = 1; // store carry for proceeding sums
              z -= 10; // Obviously 
          }
          else
          {
              carry = 0; //Else no carry was generated
          }
          return z + '0'; // Now you have "correct" number, make it a char, add 48
      });
      

      std::transform 出现在标题 &lt;algorithm&gt; 中,请参阅 ideone 发布的链接。

      【讨论】:

      • 您能评论一下您在这里所做的事情吗...我不确定一路上发生了什么?谢谢
      • 还有std::transform?我似乎找不到它..我正在使用视觉工作室
      • @Juan 更新了答案,如果你还是不明白,我建议你得到一个good book
      【解决方案5】:

      这是一个解决方案,但这太不明智了,甚至都不好笑。

      GCC 4.7.3:g++ -Wall -Wextra -std=c++0xdumb-big-num.cpp

      #include <algorithm>
      #include <cctype>
      #include <iostream>
      #include <sstream>
      #include <stdexcept>
      #include <string>
      
      // dumb big num
      // unsigned integer
      class DBN {
      public:
        DBN() : num("0") {}
      
        explicit DBN(const std::string& s) : num(s) {
          for (const auto& c : num) {
            if (!std::isdigit(c)) { throw std::invalid_argument("DBN::DBN"); } }
          std::reverse(std::begin(num), std::end(num)); }
      
        DBN operator+(const DBN& rhs) const {
          DBN tmp(*this);
          return tmp += rhs; }
      
        DBN& operator+=(const DBN& rhs) {
          std::string r;
          const int m = std::min(num.size(), rhs.num.size());
          int c = 0;
          for (int i = 0; i < m; ++i) {
            int s = (num[i] - '0') + (rhs.num[i] - '0') + c;
            c = s / 10;
            s %= 10;
            r += static_cast<char>('0' + s); }
          const std::string& ref = num.size() < rhs.num.size() ? rhs.num : num;
          for (int i = m; i < ref.size(); ++i) {
            int s = (ref[i] - '0') + c;
            c = s / 10;
            s %= 10;
            r += static_cast<char>('0' + s); }
          if (0 < c) { r += '1'; }
          num = r;
          return *this; }
      
        friend std::ostream& operator<<(std::ostream& os, const DBN& rhs);
        friend std::istream& operator>>(std::istream& os, DBN& rhs);
      
      private:
        std::string num;
      };
      
      
      std::ostream& operator<<(std::ostream& os, const DBN& rhs) {
        std::string s(rhs.num);
        std::reverse(std::begin(s), std::end(s));
        return os << s;
      }
      
      std::istream& operator>>(std::istream& is, DBN& rhs) {
        std::stringstream ss;
        char c;
        while (is && std::isspace(is.peek())) { is.ignore(); }
        while (is) {
          if (!std::isdigit(is.peek())) { break; }
          is >> c;
          ss << c; }
        DBN n(ss.str());
        rhs = n;
        return is;
      }
      
      int main() {
        DBN a, b, t;
        while (std::cin >> a >> b) {
          std::cout << a + b << "\n";
          (t += a) += b;
        }
        std::cout << t << "\n";
      }
      

      【讨论】:

        【解决方案6】:

        这是将两个表示为字符串的数字相加的解决方案。

        #include<iostream>
        using namespace std;
        
        string add(string a, string b)
        {
           int al=a.size()-1;
           int bl=b.size()-1;
        
           int carry=0;
           string result="";
        
           while(al>=0 && bl>=0)
            {
            int temp = (int)(a[al] - '0') + (int)(b[bl] - '0') + carry ;
            carry = 0;
            if(temp > 9 )
            {
                carry=1;
                temp=temp-10;
            }
        
            result+=char(temp + '0');
            al--;
            bl--;
            }
        
           while(al>=0)
            {
                int temp = (int)(a[al] - '0') + carry ;
                carry = 0;
                if(temp>9)
                {
                    carry=1;
                    temp=temp%10;
                }
        
                result+=char(temp + '0');
                al--;
            }
        
           while(bl>=0)
            {
                int temp = (int)(b[bl] - '0') + carry ;
                carry = 0;
                if(temp>9)
                {
                    carry=1;
                    temp=temp%10;
                }
        
                result+=char(temp + '0');
                bl--;
            }
        
        if(carry)
            result+="1";
        
        string addition="";
        
        for(int i=result.size()-1;i>=0;i--)
            addition+=result[i];   // reversing the answer
        
        return addition;
        }
        
        string trim(string a)   // for removing leading 0s
        {
           string res="";
           int i=0;
        
           while(a[i]=='0')
              i++;
        
           for(;i<a.size();i++)
            res+=a[i];
        
           return res;
        }
        
        
        int main()
        {
            string a;
            string b;
        
            cin>>a>>b;
        
            cout<<trim(add(a,b))<<endl;
        }
        

        【讨论】:

        • 代码中的一个小错误。将进位添加到“临时”设置进位 = 0(在三个循环中)作为进位后,我已经添加到结果添加的数字中。
        【解决方案7】:

        这是一个简单的 C++ 代码

        string Sum(string a, string b)
        {
            if(a.size() < b.size())
                swap(a, b);
        
            int j = a.size()-1;
            for(int i=b.size()-1; i>=0; i--, j--)
                a[j]+=(b[i]-'0');
        
            for(int i=a.size()-1; i>0; i--)
                if(a[i] > '9')
                {
                    int d = a[i]-'0';
                    a[i-1] = ((a[i-1]-'0') + d/10) + '0';
                    a[i] = (d%10)+'0';
                }
            if(a[0] > '9')
            {
                string k;
                k+=a[0];
                a[0] = ((a[0]-'0')%10)+'0';
                k[0] = ((k[0]-'0')/10)+'0';
                a = k+a;
            }
            return a;
        }
        

        【讨论】:

          【解决方案8】:

          引用自C - Adding the numbers in 2 strings together if a different length 回答,我写了一个更易读的代码:

          void str_reverse(char *beg, char *end){
              if(!beg || !end)return;
              char cTmp;
              while(beg < end){
                  cTmp = *beg;
                  *beg++ = *end;
                  *end-- = cTmp;
              }
          }
          
          #define c2d(c) (c - '0')
          #define d2c(d) (d + '0')
          void str_add(const char* s1, const char* s2, char* s_ret){
              int s1_len = strlen(s1);
              int s2_len = strlen(s2);
          
              int max_len = s1_len;
              int min_len = s2_len;
              const char *ps_max = s1;
              const char *ps_min = s2;
          
              if(s2_len > s1_len){
                  ps_min = s1;min_len = s1_len;
                  ps_max = s2;max_len = s2_len;
              }
          
              int carry = 0;
              int i, j = 0;
              for (i = max_len - 1; i >= 0; --i) {
                  // this wrong-prone
                  int idx = (i - max_len + min_len) >=0 ? (i - max_len + min_len) : -1;
                  int sum = c2d(ps_max[i]) + (idx >=0  ? c2d(ps_min[idx]) : 0) + carry;
          
                  carry = sum / 10;
                  sum = sum % 10;
          
                  s_ret[j++] = d2c(sum);
              }
          
              if(carry)s_ret[j] = '1';
              str_reverse(s_ret, s_ret + strlen(s_ret) - 1);
          }
          

          测试代码如下:

          void test_str_str_add(){
              char s1[] = "123";
              char s2[] = "456";
              char s3[10] = {'\0'};
          
              str_add(s1, s2, s3);
              std::cout<<s3<<std::endl;
          
              char s4[] = "456789";
              char s5[10] = {'\0'};
              str_add(s1, s4, s5);
              std::cout<<s5<<std::endl;
          
              char s7[] = "99999";
              char s8[] = "21";
              char s9[10] = {'\0'};
              str_add(s7, s8, s9);
              std::cout<<s9<<std::endl;
          }
          

          输出:

          579

          456912

          100020

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-07-14
            • 1970-01-01
            • 2012-09-18
            • 2019-03-31
            • 2016-03-01
            • 2014-08-13
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多