單鏈表ADT模板應(yīng)用算法設(shè)計(jì):長(zhǎng)整數(shù)加法運(yùn)算(使用單鏈表存儲(chǔ)計(jì)算結(jié)果)
成都一家集口碑和實(shí)力的網(wǎng)站建設(shè)服務(wù)商,擁有專業(yè)的企業(yè)建站團(tuán)隊(duì)和靠譜的建站技術(shù),十余年企業(yè)及個(gè)人網(wǎng)站建設(shè)經(jīng)驗(yàn) ,為成都超過(guò)千家客戶提供網(wǎng)頁(yè)設(shè)計(jì)制作,網(wǎng)站開(kāi)發(fā),企業(yè)網(wǎng)站制作建設(shè)等服務(wù),包括成都營(yíng)銷型網(wǎng)站建設(shè),高端網(wǎng)站設(shè)計(jì),同時(shí)也為不同行業(yè)的客戶提供成都網(wǎng)站建設(shè)、做網(wǎng)站的服務(wù),包括成都電商型網(wǎng)站制作建設(shè),裝修行業(yè)網(wǎng)站制作建設(shè),傳統(tǒng)機(jī)械行業(yè)網(wǎng)站建設(shè),傳統(tǒng)農(nóng)業(yè)行業(yè)網(wǎng)站制作建設(shè)。在成都做網(wǎng)站,選網(wǎng)站制作建設(shè)服務(wù)商就選創(chuàng)新互聯(lián)公司。
時(shí)間限制:1S類別:DS:線性表->線性表應(yīng)用
題目描述:
輸入范例:
-
輸出范例 :
-5345,6467,5768,4654,7658,6798,7098,8098,5345,6467,5768,4654,7658,6798,7098,8098,5345,6467,5768,4654,7658,6798,7098,8098,5345,6467,5768,4654,7658,6798,7098,8098,5345,6467,5768,4654,7658,6798,7098,8098,5345,6467,5768,4654,7658,6798,7098,8098,5345,6467,5768,4654,7658,6798,7098,8098,5345,6467,5768,4654,7658,6798,7098,8098,5345,6467,5768,4654,7658,6798,7098,8098,5345,6467,5768,4654,7658,6798,7098,8098,5345,6467,5768,4654,7658,6798,7098,8098,5345,6467,5768,4654,7658,6798,7098,8098
4356,4375,4856,9856,7943,5643,7548,5698,5679,4356,4375,4856,9856,7943,5643,7548,5698,5679,4356,4375,4856,9856,7943,5643,7548,5698,5679,4356,4375,4856,9856,7943,5643,7548,5698,5679,4356,4375,4856,9856,7943,5643,7548,5698,5679,4356,4375,4856,9856,7943,5643,7548,5698,5679,4356,4375,4856,9856,7943,5643,7548,5698,5679
-5345,6467,5768,4654,7658,6798,7098,8098,5345,6467,5768,4654,7658,6798,7098,8098,5345,6467,5768,4654,7658,6798,7098,8098,5345,6467,5768,4654,7658,6798,7098,8098,5345,2111,1392,9797,7801,8855,1455,0549,9647,0788,1412,0279,2801,6941,9155,2454,7797,0769,0089,0298,3283,1941,7242,0154,9701,8919,0069,8975,3302,2423,2241,8241,7402,0823,8219,8956,1979,2442,2723,3241,5488,8524,0124,7106,1960,1119,2742,3723,0488,6610,7824,9011,0110,1100,1419,3742,0970,1610,5911,6711,2014,9250,1400,2419
這里利用了幾個(gè)關(guān)鍵函數(shù):鏈表的逆置 比較兩個(gè)鏈表的絕對(duì)值大小 鏈表的相加 輸出鏈表
我的題解:
//DHUOJ 單鏈表ADT模板應(yīng)用算法設(shè)計(jì):長(zhǎng)整數(shù)加法運(yùn)算(使用單鏈表存儲(chǔ)計(jì)算結(jié)果) #include#include using namespace std; template<class ElemType> struct Node { ElemType data; Node * next; //構(gòu)造函數(shù)1 用于node構(gòu)造頭結(jié)點(diǎn) Node(Node * ptr = NULL) { next= ptr; } //構(gòu)造函數(shù)2 用于構(gòu)造其他結(jié)點(diǎn) Node(const ElemType& item, Node * ptr = NULL) { next= ptr; data= item; } public: ElemType getdata() { return data; } Node * getnext() { return next; } void set_next(Node * p) { this->next = p; } void set_date(ElemType num) { this->data = num; } }; template<class ElemType> class LinkList { private: Node * head;//頭指針 Node * tail;//尾指針 public: //無(wú)參構(gòu)造函數(shù) LinkList() { head= new Node ; head->next = NULL; tail= head->next;//頭尾指針指向同一個(gè)內(nèi)存 } //有參構(gòu)造 LinkList(const ElemType& item) { head= new Node ; tail= new Node ; head->next = tail = new Node (item);//有參構(gòu)造node } void display() { //避免出現(xiàn)以下情況 所以我們先判斷是不是就一個(gè)單0 if(head->getnext()->getdata()==0&&head->getnext()->getnext()==NULL) { cout<<"0"; return ; } if (head->getdata() == -1) cout<< "-";//如果是0就不能輸出負(fù)號(hào) //其實(shí)這樣寫(xiě)也有問(wèn)題 如果-0000 0005的就無(wú)法判斷 所以我們上面解決了單0的情況 Node * q = head->next; bool zeroflag = 0; bool firstflag = 0; //0要先特判 避免出現(xiàn)0 0000 0000的情況 也不行 會(huì)出現(xiàn)0 0000 0005 的情況無(wú)法輸出 while (q->next) { if (q->getdata() == 0 && !zeroflag) { q= q->next; continue; } else if(q->getdata()!=0&&!zeroflag) { zeroflag= 1; } if (!firstflag) { cout<< abs(q->data) << ","; firstflag= 1; } else printf("%04d,", abs(q->data)); q= q->next; } if (q == head->next)//只有一位特判 cout << abs(q->data); else { if (!firstflag) { cout<< abs(q->data); } else { if (!zeroflag) { cout<< abs(q->data); } else { printf("%04d", abs(q->data)); } } } cout<< endl; } int size() { if (head->next == NULL) return 0; int len = 0; Node * q; q= head->next; while (q) { len++; q= q->next; } return len; } void push_back(ElemType x) { Node * q = new Node ;//新建結(jié)點(diǎn) q->data = x; q->next = NULL; if (size() == 0) { head->next = q; } else { tail->next = q; } tail= q; } Node * get_front(Node * p) {//獲取一個(gè)指針的上一個(gè),頭指針和非法指針會(huì)報(bào)錯(cuò). Node * q; q= head->next; while (q->next != NULL) { if (q->next == p) return q; q= q->next; } } Node * get_next(Node * p) { return p->next; } Node * get_address(int i)//獲取指定下標(biāo)的地址 { Node * q; q= head->next; while (i--) q= q->next; return q; } ElemType at(int i) { Node * q = get_address(i); return q->data; } bool del_p(Node * p)//傳入一個(gè)指針 刪除 { if (size() == 0) return false; if (tail->next == NULL)//如果只有一個(gè)元素 { if (p == tail)//如果這個(gè)指針是那個(gè)唯一的指針 { delete tail; tail= NULL; return true; } else return false;//如果不是 } if (p == tail)//如果刪除的是尾指針 { Node * q = get_front(p); q->next = NULL; tail= q; delete p; return true; } //其他的 Node * q = get_front(p); q->next = p->next; delete p; return true; } bool del(int i)//刪除指定位置的元素 { return del_p(get_address(i)); } Node * get_head() { return head; } Node * get_tail() { return tail; } void set_head(Node * p) { head= p; } void set_tail(Node * p) { tail= p; } void ListReverse() { Node * a, * b, * temp; a= head->getnext(); ElemType datas= head->getdata(); temp= NULL; b= NULL; bool flag = 0;//設(shè)置尾指針的標(biāo)志 while (a) { b= a; a= a->getnext(); b->set_next(temp); if (!flag) { tail= b; flag= 1; } temp= b; } Node * newhead = new Node ; newhead->set_next(b); newhead->set_date(datas); head= newhead; } }; //從長(zhǎng)整數(shù)的低位開(kāi)始拆分(4位為一組,即不超過(guò)9999的非負(fù)整數(shù)),依次存放在單鏈表的每個(gè)結(jié)點(diǎn)的數(shù)據(jù)域中; //頭結(jié)點(diǎn)的數(shù)據(jù)域存放正負(fù)數(shù)標(biāo)志(正數(shù)或0:1,負(fù)數(shù):-1)。 template<class ElemType> void Input_Int_Division(LinkList & L, string& str, int& length) { Node * head = L.get_head(); bool zhengfu_flag = 0;//記錄正負(fù)的flag int l = str.length(); if (str[0] == '-')//先特判正負(fù)數(shù) { zhengfu_flag= 1; head->set_date(-1); } else { head->set_date(1); } int i = 0; if (zhengfu_flag) i= 1; int t0 = l % 4; if (t0 == 0) t0= 4; int t = 0;//記錄位數(shù) int num = 0;//存四位數(shù) bool changeflag = 0;//判斷標(biāo)志 判斷是否有進(jìn)行第一次 for (; i < t0; ++i) { num= num * 10 + (str[i] - '0'); changeflag= 1; } if (changeflag) { length++;//記錄長(zhǎng)度 L.push_back(num); num= 0; } for (; i < str.length(); ++i) { num= num * 10 + (str[i] - '0'); t++; if (t == 4) { length++;//記錄長(zhǎng)度 L.push_back(num); t= 0; num= 0; } } //L.display(); } //兩個(gè)長(zhǎng)整數(shù)的 絕對(duì)值 大小比較 //(x>y 返回值為1;x template<class ElemType> int Two_LongNum_Compare(LinkList & A, LinkList & B, const int& len_A, const int& len_B) { Node * head1 = A.get_head(); Node * head2 = B.get_head(); //正數(shù)的情況 先看長(zhǎng)度 if (len_A > len_B) { return 1; } else if (len_A < len_B) { return 2; } else if (len_A == len_B) { Node * a, * b; a= head1->getnext(); b= head2->getnext(); while (a) { if (a->getdata() > b->getdata()) return 1; else if (a->getdata() < b->getdata()) return 2; else a= a->getnext(), b = b->getnext(); } return 0; } } template<class ElemType> void swaps(LinkList & a, LinkList & b) { LinkList temp = a; a= b; b= temp; } template<class ElemType> void Listadds(LinkList & a, LinkList & b, int& la, int& lb) { Node * x, * y; int ans = 0; if (la < lb) { //swap一下兩個(gè) swaps(a, b); int temp = la; la= lb; lb= temp; } x= a.get_head()->getnext(); y= b.get_head()->getnext();//兩個(gè)指針的創(chuàng)建必須放在 交換判斷之后 int m = a.get_head()->getdata();//m n 存儲(chǔ)符號(hào) int n = b.get_head()->getdata();//存儲(chǔ)符號(hào)也必須放在交換判斷之后 //第一步 判斷結(jié)果的最高位//!必須再加法前進(jìn)行 !!因?yàn)閍會(huì)隨著加法而改變 引用傳遞 bool flag = 0;//標(biāo)記元素 int comp = Two_LongNum_Compare(a, b, la, lb); while (y)//先把每一位結(jié)點(diǎn)的數(shù)值加起來(lái) { ans= x->getdata() * m + y->getdata() * n; x->set_date(ans); x= x->getnext(); y= y->getnext(); } //把長(zhǎng)的位都化成同號(hào)的 不然接下來(lái)進(jìn)位會(huì)出問(wèn)題 while (x) { x->set_date(x->getdata() * m); x= x->getnext(); } //再做進(jìn)位處理 if (comp == 1) { flag= 1; } //第二步 開(kāi)始逐位遍歷 x = a.get_head()->getnext(); int zheng_fu = 0;//判斷正負(fù)的符號(hào) if (flag) zheng_fu= a.get_head()->getdata(); else zheng_fu= b.get_head()->getdata(); if (zheng_fu > 0)//分正負(fù)兩種情況 先看是正的 { a.get_head()->set_date(1);//定最高位符號(hào) while (x->getnext())//最后一個(gè)結(jié)點(diǎn)先不遍歷 最后單獨(dú)討論 { if (x->getdata() > 9999) { x->set_date(x->getdata() - ); x->getnext()->set_date(x->getnext()->getdata() + 1); //下一位就加一 } else if (x->getdata() < 0) { x->set_date(x->getdata() + ); x->getnext()->set_date(x->getnext()->getdata() - 1); } x= x->getnext(); } //討論最后一位 是否要進(jìn)位 if (x->getdata() > 9999) { x->set_date(x->getdata() - ); a.push_back(1); } } else //討論負(fù)數(shù)的情況 { a.get_head()->set_date(-1);//定最高位符號(hào) while (x->getnext())//最后一個(gè)結(jié)點(diǎn)先不遍歷 最后單獨(dú)討論 { if (x->getdata() < -9999) { x->set_date(x->getdata() + ); x->getnext()->set_date(x->getnext()->getdata() - 1); //下一位就加一 } else if (x->getdata() > 0) { x->set_date(x->getdata() - ); x->getnext()->set_date(x->getnext()->getdata() + 1); } x= x->getnext(); } //討論最后一位 是否要進(jìn)位 if (x->getdata() < -9999) { x->set_date(x->getdata() + ); a.push_back(1); } } } int main() { LinkList<int>head1, head2; string str1, str2; getline(cin, str1); getline(cin, str2); int la = str1.length(); int lb = str2.length(); if (str1[0] == '-') la-= 1; if (str2[0] == '-') lb-= 1; int length1 = 0; int length2 = 0; Input_Int_Division(head1, str1, length1); Input_Int_Division(head2, str2, length2); head1.display(); head2.display(); cout<< endl; head1.ListReverse(); head2.ListReverse(); Listadds(head1, head2, la, lb); head1.ListReverse(); head1.display(); //swaps(head1, head2); //head1.display(); //head2.display(); //cout << endl; //int comp = Two_LongNum_Compare(head1, head2, length1, length2); //cout << comp; //cout << length< //head.ListReverse(); //head.display(); return 0; }