4

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

    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 的字符串格式。谢谢谁能帮我解决这个问题

4

8 回答 8

5

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

  • 用 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);
}

这里

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

                +--------+--------------+------------+-------> 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存在于 header 中<algorithm>,请参阅 ideone 发布的链接。

于 2013-10-09T03:12:42.050 回答
3

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

#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;
}
于 2015-12-26T18:24:44.733 回答
0

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

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

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

于 2013-10-09T02:51:07.247 回答
0

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

char sumdigit = (input1[0]-'0') + (input2[0]-'0') + '0';
于 2013-10-09T02:57:05.647 回答
0

atoi()就转换input[0]为int而言,会更好:

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

然后使用 stringstream 转换回字符串:

stringstream convert;
convert << temp;
string newString = convert.str();
于 2013-10-09T03:12:15.457 回答
0

这是一个解决方案,但这远非明智之举,甚至都不好笑。

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";
}
于 2013-10-09T13:32:49.170 回答
0

这是一个简单的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;
}
于 2016-03-02T03:23:58.343 回答
0

引用自C - 将 2 个字符串中的数字相加,如果答案长度不同 ,我编写了更易读的代码:</p>

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

于 2017-12-02T09:17:50.270 回答