iT邦幫忙

1

我現在在做費式數列的class,要解決大數,所以我用string來做,但是在相加的地方輸出發生了反轉,請問我該怎麼辦?

  • 分享至 

  • xImage

我在這裡遇到了問題,會把reverse(result.str.begin(), result.str.end());註解是因為要是有這行,執行時8+13會變成39,但是註解掉後卻變成31,後面的數字也都是對的但是反了過來,請問我該怎麼改才好?

Bigint Bigint::operator+(const Bigint& that) const {
    Bigint result;
    int carry = 0;
    int i = 0;
    while (i < this->str.length() || i < that.str.length() || carry != 0) {
        int sum = carry;
        if (i < this->str.length()) {
            sum += (this->str[i] - '0');
        }
        if (i < that.str.length()) {
            sum += (that.str[i] - '0');
        }
        carry = sum / 10;
        sum %= 10;
        result.str += to_string(sum);
        i++;
    }
    //reverse(result.str.begin(), result.str.end());
    return result;
}

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

class Bigint {
private:
    string str;
public:
    Bigint();
    Bigint(const Bigint& s);
    Bigint(string st);
    Bigint operator+(const Bigint&) const;
    Bigint operator=(const Bigint&);
    Bigint operator*(const Bigint&) const;
    int operator[](int idx) const;
    friend ostream& operator<<(ostream&, const Bigint&);
};

class N2Comp {
private:
    Bigint x, y;
public:
    int count = 0;
    N2Comp();
    N2Comp(const N2Comp& s);
    N2Comp(int a, int b);
    N2Comp(int a);
    ~N2Comp();
    N2Comp operator+(const N2Comp&) const;
    N2Comp operator=(const N2Comp&);
    int operator[](int inans) const;
    friend ostream& operator<<(ostream&, const N2Comp&);
};

Bigint::Bigint() {
    str = "";
}

Bigint::Bigint(const Bigint& s) {
    str = s.str;
}

Bigint::Bigint(string st) {
    str = st;
}

Bigint Bigint::operator+(const Bigint& that) const {
    Bigint result;
    int carry = 0;
    int i = 0;
    while (i < this->str.length() || i < that.str.length() || carry != 0) {
        int sum = carry;
        if (i < this->str.length()) {
            sum += (this->str[i] - '0');
        }
        if (i < that.str.length()) {
            sum += (that.str[i] - '0');
        }
        carry = sum / 10;
        sum %= 10;
        result.str += to_string(sum);
        i++;
    }
    //reverse(result.str.begin(), result.str.end());
    return result;
}

Bigint Bigint::operator*(const Bigint& that) const {

    Bigint result;
    result.str.resize(this->str.length() + that.str.length(), '0');
    for (int i = 0; i < this->str.length(); i++) {
        int carry = 0;
        for (int j = 0; j < that.str.length(); j++) {
            int digit = (this->str[i] - '0') * (that.str[j] - '0') + carry + (result.str[i + j] - '0');
            carry = digit / 10;
            result.str[i + j] = (digit % 10) + '0';
        }
        if (carry > 0) {
            result.str[i + that.str.length()] += carry;
        }
    }
    while (result.str.size() > 1 && result.str.back() == '0') {
        result.str.pop_back();
    }
    reverse(result.str.begin(), result.str.end());
    return result;
}

Bigint Bigint::operator=(const Bigint& that) {
    this->str = that.str;
    return *this;
}

int Bigint::operator[](int idx) const {
    if (idx < str.length()) {
        return str[idx] - '0';
    }
    else {
        return 0;
    }
}

ostream& operator<<(ostream& os, const Bigint& num) {
    os << num.str;
    return os;
}
N2Comp::N2Comp() {
    x = Bigint();
    y = Bigint();
}

N2Comp::N2Comp(const N2Comp& s) {
    x = s.x;
    y = s.y;
}

N2Comp::N2Comp(int a, int b) {
    x = Bigint(to_string(a));
    y = Bigint(to_string(b));
}

N2Comp::N2Comp(int a) {
    x = Bigint(to_string(a));
    y = Bigint(to_string(0));
}

N2Comp::~N2Comp() {}

N2Comp N2Comp::operator+(const N2Comp& that) const {
    N2Comp result;
    result.x = this->x + that.x;
    result.y = (this->x + that.x) + (this->y * that.y);
    return result;
}

N2Comp N2Comp::operator=(const N2Comp& that) {
    this->x = that.x;
    this->y = that.y;
    return *this;
}

int N2Comp::operator[](int inans) const {
    int count = 0;
    count++;
    int ans;
    if (count == 1) {
        ans = x[inans];
    }
    else {
        ans = y[inans];
    }
    return ans;
}

ostream& operator<<(ostream& os, const N2Comp& num) {
    os << "(" << num.x << ", " << num.y << ")";
    return os;
}


N2Comp diNFib(int n = 0) {
    if (n == 0)
        return 0;
    if (n == 1)
        return 1;
    return diNFib(n - 1) + diNFib(n - 2);
}

int main()
{
    int level = 0;
    cout << "Hello user! How many level do you want to reach?" << endl;
    cin >> level;

    N2Comp ANS(0, 0);
    for (int i = 0; i < level; ++i) {
        ANS = diNFib(i);
        cout << "F(" << i << ") = ";
        cout << ANS[0] << "," << ANS[1] << endl;
        cout << ANS << endl;
    }
    //cout << "[Test prog. for operator >>]" << endl;
    //N2Comp A1(0), A2(0);
    //cout << "Input A1: "; cin >> A1; cout << endl;
    //cout << "Input A2: "; cin >> A2; cout << endl;
    //cout << "Exec A1+A2 = " << A1 + A2 << endl;
    return 0;
}
淺水員 iT邦大師 6 級 ‧ 2023-04-04 11:55:29 檢舉
Bigint.str 的儲存方式先決定好吧
有確定要照目前的儲存方式嗎?
還是要反過來儲存?這樣位數就會對齊
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
3
海綿寶寶
iT邦大神 1 級 ‧ 2023-04-03 23:41:13

https://ithelp.ithome.com.tw/upload/images/20230404/20001787hQ7CuiB5pA.png

masawu iT邦新手 5 級 ‧ 2023-04-04 00:22:58 檢舉

謝謝提醒

0
deh
iT邦研究生 1 級 ‧ 2023-04-04 00:15:22

將reverse(result.str.begin(), result.str.end())刪除,
改成reverse(result.str.rbegin(), result.str.rend())即可。
原因是std::string中使用reverse時,需要使用反向迭代器(reverse iterators),以保持正確的順序。

masawu iT邦新手 5 級 ‧ 2023-04-04 00:24:32 檢舉

剛剛有去嘗試了,但是在8+13的地方變成了39。

Bigint Bigint::operator+(const Bigint& that) const {
    Bigint result;
    int carry = 0;
    int i = 0;
    while (i < this->str.length() || i < that.str.length() || carry != 0) {
        int sum = carry;
        if (i < this->str.length()) {
            sum += (this->str[i] - '0');
        }
        if (i < that.str.length()) {
            sum += (that.str[i] - '0');
        }
        carry = sum / 10;
        sum %= 10;
        result.str += to_string(sum);
        i++;
    }
    reverse(result.str.rbegin(), result.str.rend());
    return result;
}
0
淺水員
iT邦大師 6 級 ‧ 2023-04-04 12:04:43

如果照你原本的方式修改
要注意個位數是在字串的最後面

Bigint Bigint::operator+(const Bigint& that) const
{
    Bigint result;
    int carry = 0;
    int i = 0, lenThis = this->str.length(), lenThat = that.str.length();
    while (i < lenThis || i < lenThat || carry != 0) {
        int sum = carry;
        if (i < lenThis) {
            // 個位數在最後,所以是從字串的最後往前取值
            sum += (this->str[lenThis - 1 - i] - '0');
        }
        if (i < lenThat) {
            // 個位數在最後,所以是從字串的最後往前取值
            sum += (that.str[lenThat - 1 - i] - '0');
        }
        carry = sum / 10;
        sum %= 10;
        result.str += std::to_string(sum);
        i++;
    }
    std::reverse(result.str.begin(), result.str.end());
    return result;
}

乘法就留給您自己改了,猜測有類似問題

masawu iT邦新手 5 級 ‧ 2023-04-06 11:11:12 檢舉

非常感謝

我要發表回答

立即登入回答