C++字符串(int)+字符串(int)

C++字符串(int)+字符串(int),c++,string,add,uint64,C++,String,Add,Uint64,我有两个字符串,都只包含数字。这些数字大于uint64\t的最大值 如何添加这两个数字,然后将结果转换为字符串?您需要一个BigInt实现。你可以找到几个不同的 无论您选择什么样的BigInt实现,都需要在字符串之间进行转换。您需要一个BigInt实现。你可以找到几个不同的 无论您选择什么样的BigInt实现,都需要与通常使用的字符串进行转换。好的,您可以使用更大的数据类型,例如处理大整数的库,也可以快速创建自己的数据类型 我会建议,如果这是一次性的,你可以做长加法,就像你在学校的头几年所学的那

我有两个字符串,都只包含数字。这些数字大于uint64\t的最大值


如何添加这两个数字,然后将结果转换为字符串?

您需要一个BigInt实现。你可以找到几个不同的


无论您选择什么样的BigInt实现,都需要在字符串之间进行转换。

您需要一个BigInt实现。你可以找到几个不同的


无论您选择什么样的BigInt实现,都需要与通常使用的字符串进行转换。

好的,您可以使用更大的数据类型,例如处理大整数的库,也可以快速创建自己的数据类型

我会建议,如果这是一次性的,你可以做长加法,就像你在学校的头几年所学的那样。您可以直接对这两个字符串进行操作,添加列,执行“进位”,然后构建另一个包含结果的字符串。您可以在不进行任何二进制转换的情况下完成所有这些操作

在这里。只是为了好玩,我为你想出了一个解决方案:

string Add( const string& a, const string& b )
{
    // Reserve storage for the result.
    string result;
    result.reserve( 1 + std::max(a.size(), b.size()) );

    // Column positions and carry flag.
    int apos = a.size();
    int bpos = b.size();
    int carry = 0;

    // Add columns
    while( carry > 0 || apos > 0 || bpos > 0 )
    {
        if( apos > 0 ) carry += a[--apos] - '0';
        if( bpos > 0 ) carry += b[--bpos] - '0';
        result.push_back('0' + (carry%10));
        carry /= 10;
    }

    // The result string is backwards.  Reverse and return it.
    reverse( result.begin(), result.end() );
    return result;
}

请注意,为清楚起见,此代码甚至不尝试处理错误。它也不会产生负面影响,但解决这个问题并不困难。

好吧,您可以使用更大的数据类型,例如处理大整数的库,也可以快速创建自己的数据类型

我会建议,如果这是一次性的,你可以做长加法,就像你在学校的头几年所学的那样。您可以直接对这两个字符串进行操作,添加列,执行“进位”,然后构建另一个包含结果的字符串。您可以在不进行任何二进制转换的情况下完成所有这些操作

在这里。只是为了好玩,我为你想出了一个解决方案:

string Add( const string& a, const string& b )
{
    // Reserve storage for the result.
    string result;
    result.reserve( 1 + std::max(a.size(), b.size()) );

    // Column positions and carry flag.
    int apos = a.size();
    int bpos = b.size();
    int carry = 0;

    // Add columns
    while( carry > 0 || apos > 0 || bpos > 0 )
    {
        if( apos > 0 ) carry += a[--apos] - '0';
        if( bpos > 0 ) carry += b[--bpos] - '0';
        result.push_back('0' + (carry%10));
        carry /= 10;
    }

    // The result string is backwards.  Reverse and return it.
    reverse( result.begin(), result.end() );
    return result;
}

请注意,为清楚起见,此代码甚至不尝试处理错误。它也不做负数,但修复它并不困难。

如果你只想处理正数,而不必担心引入像GMP这样的整个bignum库,以及它在内存不足错误时中止的趋势,我发现这在通用库中是不可原谅的,你可以自己动手,比如:

static std::string add (const std::string& num1, const std::string& num2) {
    // Make num1 the wider number to simplify further code.

    int digit, idx1 = num1.length() - 1, idx2 = num2.length() - 1;
    if (idx1 < idx2) return add (num2, num1);

    // Initialise loop variables.

    int carry = 0;
    std::string res;  // reserve idx1+2 chars if you want.

    // Add digits from right until thinner number finished.

    while (idx2 >= 0) {
        digit = num1[idx1--] - '0' + num2[idx2--] - '0' + carry;
        carry = (digit > 9);
        res.insert (0, 1, (digit % 10) + '0');
    }

    // Then just process rest of wider number and any leftover carry.

    while (idx1 >= 0) {
        digit = num1[idx1--] - '0' + carry;
        carry = (digit > 9);
        res.insert (0, 1, (digit % 10) + '0');
    }
    if (carry) res.insert (0, 1, '1');

    return res;
}

您可以提高效率,例如提前在目标字符串中保留空间,并设置其特定索引,而不是插入,但是,除非您处理的是真正庞大的字符串或每秒执行多次,我通常更喜欢易于理解和维护的代码。

如果您只想处理正数,而不必担心引入像GMP这样的整个bignum库,以及它在内存不足错误时中止的趋势,我发现这在通用库中是不可原谅的,您可以自己动手,比如:

static std::string add (const std::string& num1, const std::string& num2) {
    // Make num1 the wider number to simplify further code.

    int digit, idx1 = num1.length() - 1, idx2 = num2.length() - 1;
    if (idx1 < idx2) return add (num2, num1);

    // Initialise loop variables.

    int carry = 0;
    std::string res;  // reserve idx1+2 chars if you want.

    // Add digits from right until thinner number finished.

    while (idx2 >= 0) {
        digit = num1[idx1--] - '0' + num2[idx2--] - '0' + carry;
        carry = (digit > 9);
        res.insert (0, 1, (digit % 10) + '0');
    }

    // Then just process rest of wider number and any leftover carry.

    while (idx1 >= 0) {
        digit = num1[idx1--] - '0' + carry;
        carry = (digit > 9);
        res.insert (0, 1, (digit % 10) + '0');
    }
    if (carry) res.insert (0, 1, '1');

    return res;
}

您可以提高效率,例如提前在目标字符串中保留空间,并为其设置特定索引,而不是插入,但是,除非您处理的是真正庞大的字符串或每秒执行多次,否则我通常更喜欢易于理解和维护的代码。

以下是解决您问题的代码:

#include <iostream>
#include <string>
using namespace std;
string StrAdd(string a, string b) {
  string::reverse_iterator rit_a = a.rbegin();
  string::reverse_iterator rit_b = b.rbegin();
  string c;
  int val_c_adv = 0;
  while(rit_a != a.rend() && rit_b != b.rend() ) {
    int val_a_i = *rit_a - '0';
    int val_b_i = *rit_b - '0';
    int val_c_i = val_a_i + val_b_i + val_c_adv;
    if(val_c_i >= 10 ) {
      val_c_adv = 1;
      val_c_i -= 10;
    } else {
      val_c_adv = 0;
    }
    c.insert(0,1, (char)(val_c_i+'0'));
    ++rit_a;
    ++rit_b;
  }
  if(rit_a == a.rend() ) {
    while( rit_b != b.rend() ) {
      int val_b_i = *rit_b - '0';
      int val_c_i = val_b_i + val_c_adv;
      if(val_c_i >= 10 ) {
        val_c_adv = 1;
        val_c_i -= 10;
      } else {
        val_c_adv = 0;
      }
      c.insert(0, 1, (char)(val_c_i+'0'));
      ++rit_b;
    }
  } else if( rit_b == b.rend() ) {
    while( rit_a != a.rend() ) {
      int val_a_i = *rit_a - '0';
      int val_c_i = val_a_i + val_c_adv;
      if(val_c_i >= 10 ) {
        val_c_adv = 1;
        val_c_i -= 10;
      } else {
        val_c_adv = 0;
      }
      c.insert(0, 1, (char)(val_c_i+'0'));
      ++rit_a;
    }
  }
  return c;
}

int main() {
  string res, a, b;
  cout << "a=" << endl;
  cin >> a;
  cout << "b=" << endl;
  cin >> b;
  res = StrAdd(a, b);
  cout << "Result=" << res << endl;    
}

以下是您的问题代码:

#include <iostream>
#include <string>
using namespace std;
string StrAdd(string a, string b) {
  string::reverse_iterator rit_a = a.rbegin();
  string::reverse_iterator rit_b = b.rbegin();
  string c;
  int val_c_adv = 0;
  while(rit_a != a.rend() && rit_b != b.rend() ) {
    int val_a_i = *rit_a - '0';
    int val_b_i = *rit_b - '0';
    int val_c_i = val_a_i + val_b_i + val_c_adv;
    if(val_c_i >= 10 ) {
      val_c_adv = 1;
      val_c_i -= 10;
    } else {
      val_c_adv = 0;
    }
    c.insert(0,1, (char)(val_c_i+'0'));
    ++rit_a;
    ++rit_b;
  }
  if(rit_a == a.rend() ) {
    while( rit_b != b.rend() ) {
      int val_b_i = *rit_b - '0';
      int val_c_i = val_b_i + val_c_adv;
      if(val_c_i >= 10 ) {
        val_c_adv = 1;
        val_c_i -= 10;
      } else {
        val_c_adv = 0;
      }
      c.insert(0, 1, (char)(val_c_i+'0'));
      ++rit_b;
    }
  } else if( rit_b == b.rend() ) {
    while( rit_a != a.rend() ) {
      int val_a_i = *rit_a - '0';
      int val_c_i = val_a_i + val_c_adv;
      if(val_c_i >= 10 ) {
        val_c_adv = 1;
        val_c_i -= 10;
      } else {
        val_c_adv = 0;
      }
      c.insert(0, 1, (char)(val_c_i+'0'));
      ++rit_a;
    }
  }
  return c;
}

int main() {
  string res, a, b;
  cout << "a=" << endl;
  cin >> a;
  cout << "b=" << endl;
  cin >> b;
  res = StrAdd(a, b);
  cout << "Result=" << res << endl;    
}

您可以使用bignum库,也可以将字符串切碎成适合uint64_t的较小字符串,将它们相加,并将多余的数字带到下一个加法中。您需要一个大整数库或编写自己的整数库。是时候做一些谷歌搜索了!最简单的方法是使用专为这些事情设计的。只需查找该问题:另请参阅以了解任意精度算术的解释。您可以使用bignum库,或者您可以将字符串拆分为适合uint64_t的较小字符串,添加它们,并将多余的数字带到下一个加法。您需要一个大的整数库或编写自己的整数库。是时候做一些谷歌搜索了!最简单的方法是使用专为这些事情设计的。只需查找这个问题:另请参阅,以了解任意精度算术的解释。对求和运算的进位使用得很好,我以前从未见过这样做-它很好地减少了代码大小。对求和运算的进位使用得也很好,我以前从未见过这样做——它很好地减少了代码大小。