#30260: _M_replace_aux?? 不懂這個是什麼意思


jhuangchenleo@gmail.com (Wood)

學校 : 不指定學校
編號 : 130868
來源 : [182.155.148.199]
最後登入時間 :
2024-07-18 21:46:30
a021. 大數運算 | From: [49.215.21.84] | 發表日期 : 2022-05-13 09:38

出現了以下錯誤訊息,我在網路上查了還是不懂哪邊出問題,懇請各位大大指點迷津,告訴小弟這個是什麼意思、可能是什麼東西出問題? 謝謝

系統呼叫了 abort 函式! terminate called after throwing an instance of 'std::length_error' what(): basic_string::_M_replace_aux Aborted (core dumped)

以下為我的程式碼

#include <iostream>

using namespace std;

string add(string aa,string ba)  //加法
{
    string ret="";
    int up=0;

    if(aa.size()>ba.size())
        ba.insert(0,aa.size()-ba.size(),'0');
    else
        aa.insert(0,ba.size()-aa.size(),'0');

    for(int i=(int)aa.size()-1;i>=0;i--){
        int sum=0;
        string sum_s="";
        sum=aa[i]-48+ba[i]-48+up;//int,begin with back
        up=sum/10;//int
        ret.insert(0,1,char(sum%10+48));//ascii
    }
    if(up!=0){
        ret.insert(0,1,char(up+48));
        up=0;
    }

    return ret;
}

string sub(string aa,string bb)  //減法
{
    string ret="";
    int up=1; //for first number
    int p_or_n=1;
    int sum=0;
    int fin_len=0;

    if(aa.size()>bb.size()) //fill up space
        bb.insert(0,aa.size()-bb.size(),'0');
    else
        aa.insert(0,bb.size()-aa.size(),'0');

    p_or_n=aa.compare(bb);

    if(p_or_n==-1)
        swap(aa,bb);

    for(int i=aa.size()-1;i>=0;i--){
        sum=aa[i]+up-1-bb[i]+10; //int,all down
        up=sum/10;
        ret.insert(0,1,sum%10+48);
    }

    for(int i=0;i<=(int)ret.size()-1 && ret[i]==48;i++)   //ascii,delete space, .size() return some thing not int
        fin_len++;

    if(p_or_n==-1)
        ret.insert(0,1,'-');   //+or-
    else if(p_or_n==0){
        ret="0";
        fin_len=0;
    }

    return ret.erase(0,fin_len);
}

string mult(string aa,string bb)   //乘法
{
    string ret="";
    string one="";
    string two="";
    int up=0;
    int sum=0;
    int fin_len=0;

    if(aa.size()>bb.size())
        bb.insert(0,aa.size()-bb.size(),'0');
    else
        aa.insert(0,bb.size()-aa.size(),'0');

    for(int i=aa.size()-1;i>=0;i--){
        two="";//clear
        for(int n=aa.size()-1;n>=0;n--){
            sum=(aa[n]-48)*(bb[i]-48)+up;
            up=sum/10;
            two.insert(0,1,sum%10+48);
        }
        if(up!=0){ //more
            two.insert(0,1,up+48);
            up=0;
        }
        one=add(one,two.append(aa.size()-i-1,'0'));   //push
    }

    ret=one;

    for(int i=0;i<=(int)ret.size()-1 && ret[i]==char(48);i++)   //ascii,delete space
        fin_len++;

    return ret.erase(0,fin_len);
}

string dev(string aa,string bb)   //除法
{
    string rett="0";
    int t=0;

    for(;sub(aa,bb)[0]!='-'&&sub(aa,bb)[0]!='0';){
        string zero="1";   //avoid too big and thus TLE

        if(aa.size()-bb.size()<=0)
            t=1;
        else
            t=aa.size()-bb.size();

        aa=sub(aa,mult(bb,zero.append(t-1,'0')));
        rett=add(rett,zero);

    }

    if(sub(aa,bb)[0]=='0')
        rett=add(rett,"1");

    return rett;
}

int main()
{
    string a,b,ca;
   while(cin>>a>>ca>>b){
        if(ca=="+")
            cout << add(a,b) << endl;
        if(ca=="-")
            cout << sub(a,b) << endl;
        if(ca=="*")
            cout << mult(a,b) << endl;
        if(ca=="/")
            cout << dev(a,b) << endl;
        }

    return 0;
}

 
#30263: Re: _M_replace_aux?? 不懂這個是什麼意思


cges30901 (cges30901)

學校 : 不指定學校
編號 : 30877
來源 : [39.9.74.255]
最後登入時間 :
2024-10-14 22:20:08
a021. 大數運算 | From: [27.240.162.19] | 發表日期 : 2022-05-13 22:08

1.

    p_or_n=aa.compare(bb);

    if(p_or_n==-1)

2.

    return ret.erase(0,fin_len);

3.

        aa=sub(aa,mult(bb,zero.append(t-1,'0')));

  1. 如果aa<bb,compare()回傳的值會小於0,但不見得是-1,可能是其他負數
  2. 如果前面是0又是負數,你會把負號移除掉,最前面是0,你可以在插入負號前移除0
  3. _M_replace_aux來自於這裡,因為減法算錯了,t-1小於0,所以append()出錯。把減法改好就不會有問題了
 
#30422: Re: _M_replace_aux?? 不懂這個是什麼意思


jhuangchenleo@gmail.com (Wood)

學校 : 不指定學校
編號 : 130868
來源 : [182.155.148.199]
最後登入時間 :
2024-07-18 21:46:30
a021. 大數運算 | From: [182.155.148.199] | 發表日期 : 2022-05-20 15:37

1.

    p_or_n=aa.compare(bb);

    if(p_or_n==-1)

2.

    return ret.erase(0,fin_len);

3.

        aa=sub(aa,mult(bb,zero.append(t-1,'0')));

  1. 如果aa<bb,compare()回傳的值會小於0,但不見得是-1,可能是其他負數
  2. 如果前面是0又是負數,你會把負號移除掉,最前面是0,你可以在插入負號前移除0
  3. _M_replace_aux來自於這裡,因為減法算錯了,t-1小於0,所以append()出錯。把減法改好就不會有問題了

原來如此,改了後成功AC了,非常感謝您!

但有些地方我仍想不通:

請問 3. 的t-1為什麼會小於0呢? 前面不是有著這段嗎?

if((aa.size()-bb.size())<=0)

    t=1;

else

    t=aa.size()-bb.size();



 
#30423: Re: _M_replace_aux?? 不懂這個是什麼意思


lfs92002 (GMan每日殺水題1.6449340668482264364...)

學校 : 國立臺南第一高級中學
編號 : 19129
來源 : [140.114.89.50]
最後登入時間 :
2024-10-21 16:23:26
a021. 大數運算 | From: [61.230.26.173] | 發表日期 : 2022-05-20 16:35

* aa.size()-bb.size()

C++ 的 size 型態是 unsigned 的,( 這裡假設他是 32 bit unsigned int ),所以他相減必大於等於 0 ,因此如果遇到像是 

aa.aize() = 2U

bb.size() = 3U

那麼

t = aa.size() - bb.size() = 2U - 3U = -1U = 4294967295U

(你可以用 cout 來輸出上面的數字看看是不是這樣)

所以你的 zero.append(t-1, '0') 就會因為嘗試插入過多的資料 (40 多億) 導致 RE

 

 
#30447: Re: _M_replace_aux?? 不懂這個是什麼意思


cges30901 (cges30901)

學校 : 不指定學校
編號 : 30877
來源 : [39.9.74.255]
最後登入時間 :
2024-10-14 22:20:08
a021. 大數運算 | From: [59.115.17.102] | 發表日期 : 2022-05-21 23:42

* aa.size()-bb.size()

C++ 的 size 型態是 unsigned 的,( 這裡假設他是 32 bit unsigned int ),所以他相減必大於等於 0 ,因此如果遇到像是 

aa.aize() = 2U

bb.size() = 3U

那麼

t = aa.size() - bb.size() = 2U - 3U = -1U = 4294967295U

(你可以用 cout 來輸出上面的數字看看是不是這樣)

所以你的 zero.append(t-1, '0') 就會因為嘗試插入過多的資料 (40 多億) 導致 RE

 


t是int,所以其實不會插入40多億,轉換後還是會變成負數

 
#30488: Re: _M_replace_aux?? 不懂這個是什麼意思


jhuangchenleo@gmail.com (Wood)

學校 : 不指定學校
編號 : 130868
來源 : [182.155.148.199]
最後登入時間 :
2024-07-18 21:46:30
a021. 大數運算 | From: [182.155.148.199] | 發表日期 : 2022-05-25 09:11

* aa.size()-bb.size()

C++ 的 size 型態是 unsigned 的,( 這裡假設他是 32 bit unsigned int ),所以他相減必大於等於 0 ,因此如果遇到像是 

aa.aize() = 2U

bb.size() = 3U

那麼

t = aa.size() - bb.size() = 2U - 3U = -1U = 4294967295U

(你可以用 cout 來輸出上面的數字看看是不是這樣)

所以你的 zero.append(t-1, '0') 就會因為嘗試插入過多的資料 (40 多億) 導致 RE

 


t是int,所以其實不會插入40多億,轉換後還是會變成負數

原來如此,之前不知道有分signed 跟unsigned,非常感謝二位!

 
ZeroJudge Forum