link-list 省空間,但程式繁雜:
int main (/*081116*/) { int i; struct List { //polynomial list struct P { //polynomial component int a, i; //a= coefficient, i= exponential index P* next; //pointer to next element P() {a=i=0; next=0;} //init to zero } *h, *t; //pointer to head and tail List() {h = t = new P;} void expand() { //add a new component t = (t->next = new P); } void release() { while (h->next) { t=h->next; delete h; h=t; } } P* operator->() {return t;} List operator + (const List& L) { List x; P **pp, *p1 = h, *p2 = L.h; for (;p1->next || p2->next; x.expand()) if (p1->next && p2->next && p1->i == p2->i) { //if exponential index the same x->i = p1->i; x->a = p1->a + p2->a; p1 = p1->next; p2 = p2->next; } else { //overwise select the bigger one pp = &p2; if (!p2->next || (p1->next && p1->i > p2->i)) pp = &p1; x->i = pp[0]->i; x->a = pp[0]->a; *pp = pp[0]->next; } return x; } List operator * (const List& L) { List x, y, z; P *p1 = h, *p2 = x.h; for (; p1 != t; p1 = p1->next) { x = x + L; for (p2=x.h; p2->next; p2=p2->next) { p2->a *= p1->a; p2->i += p1->i; } z = x + y; y.release(); x.release(); y = z; } return z; } void show() { for (P* p=h; p!=t; ) { if (p->i > 0) printf ("%dx^%d", p->a, p->i); else printf ("%d", p->a ); p = p->next; p!=t? printf(" + "): puts(""); } } } //================= main program =================== p[4]; for (i=0; i<2; i++) while (cin >> p[i]->a && 99 != p[i]->a) { cin >> p[i]->i; p[i].expand(); } p[0].show(); p[1].show(); puts("-----------------------"); p[2] = p[0] + p[1]; p[2].show(); p[3] = p[0] * p[1]; p[3].show(); for (i=0; i<4; i++) p[i].release(); }array 的空間使用率一般偏低,係數值域限制較大,但算式簡潔直觀。
底下使用固定大小的 array size,很沒彈性,好處是不用再想東想西:
煩惱是否要加個 Copy-on-Write 加速,檢查是否自我指派,
或是用 Immutable pattern 讓它「多一點」thread-safe:
沒有留言:
張貼留言