2013-10-09 3 views
3

Я осматривал форумы, и я до сих пор не смог найти свой ответ на свою проблему. У меня две строки, которые на самом деле представляют собой массив чисел. например (я просто выбрать случайных чиселДобавление двух строк математически?

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

Я хочу, чтобы добавить эти две строки вместе, но действуют они, как там целых чисел. Моя цель создать класс, где я могу добавить больше чисел, чем (длинные долгое межд), так он может превысить самый большой длинный длинный ИНТ переменной.

так я revese строку без проблем, так что теперь там

input1="21234567890987654321" 
    input2="54321" 

тогда я попробовал, добавив, скажем input1 [0] + input2 [0] (2 + 5) в новую строку, можно назвать newString [0], где это wou ld равно (7); но я не могу найти хороший способ временного преобразования текущего числа в строку, чтобы я мог добавить его в новую строку? может кто-нибудь помочь. Я устал от атой, stof, stod. они, кажется, не работают вообще для меня. В любом случае я могу заставить эту функцию работать. Мне все равно не нужно создавать класс, мне просто нужно найти способ добавить эти две строки математически, но при этом сохранить строковый формат newString. Спасибо за то, кто может это понять для меня

+0

Используйте существующую библиотеку bignum, например: повысить multiprecision. См. Эту статью в Википедии для общей дискуссии: http://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic –

+0

ну, я хочу создать свою собственную, это то, что делает – OPJ

ответ

5

Хорошо, так, предполагая, что ваша единственная проблема с логикой, а не класс дизайн вещь, я пришел с этой логикой

  • заполнения до входов с 0s, проверкой длиной, соответствует длине
  • добавить как нормальное дополнение, отслеживание переноса
  • окончательно удалить начальные нули из результата

Таким образом, используя std::transform с лямбда-функции на обратной итераторов: -

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 присутствует в heade r <algorithm>, см. ссылку ideone.

+0

Можете ли вы прокомментировать, что вы здесь делаете ... Я не уверен, что происходит на всем пути? Спасибо – OPJ

+0

И std :: transform? Я не могу найти его .. Я использую визуальную студию – OPJ

+0

@Juan обновленный ответ, если вы все еще не получите его, я предлагаю вам получить [хорошую книгу] (http://stackoverflow.com/ q/388242/1870232) – P0W

0

Я не очень женственник с C++, но не можем ли мы это сделать?

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

Пожалуйста, обратите внимание, это может быть сделано в C++ 11 см [1] и 2 а

+0

. Честно говоря, я не знаю, что. – OPJ

+0

Вы используете C++ 11? вы можете попробовать это, а также std :: string s = "21234567890987654321"; int i = std :: stoi (s); – poohdedoo

+0

для (я = 0; 0 <= 20; я ++) { \t \t \t \t INT х, у; \t \t x = std :: stoi (input1 [i]); \t \t} – OPJ

0

Вы можете преобразовать символ к междунар вычитанием «0» из него:

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

и перелив ...? –

0

atoi() бы лучше пойти, насколько преобразования input[0] к междунар:

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

затем использовать stringstream преобразовать обратно в строку:

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

Вот решение, но это так далеко от разумного, что это даже не смешно.

GCC 4.7.3: г ++ -Wall -Wextra -std = C++ 0x немого большой 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"; 
} 
1

Вот решение для сложения двух чисел, представленных в виде строк.

#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

Небольшая ошибка в коде. После добавления переносить на «temp» set carry = 0 (в три цикла) в качестве переноса я уже добавил к полученному добавленному числу. – rachitmanit

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; 
} 
0

цит 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; 
} 

выход:

Смежные вопросы