数据结构与算法分析——c语言描述 练习3.9 答案
这道题真的是要狗带了。。。。我的在vs2015 release模式只能计算到2的60次方。超过60次方就会一直卡在那。估计是有些地方没有优化好。可能是栈溢出什么的,因为函数存在相互之间互相调用。
使用了我的多项式代码。日后再更新代码吧。目前也不知道怎样解决。
2016.4.6
终于更新了,问题出在函数互相调用,虽然不是栈溢出,而是调用insertMonomial的时候会删除p,假如连续两个都是0要删除的时候,深一层删除上一层的指针,返回来的一层要访问,造成访问已经释放的内存。也就是野指针。
更新了进制10000,输出的时候除了第一位不足4位数的要前面补上0
list.h
typedef struct { int Coefficient;//系数 int Exponent;//指数 }ElementType; #ifndef _List_H #define _List_H struct Node; typedef struct Node *PtrToNode; typedef PtrToNode List; typedef PtrToNode Position; List CreatList(); List MakeEmpty(List L); int IsEmpty(List L); int IsLast(Position P, List L); Position Find(ElementType X, List L); void Delete(ElementType X, List L); Position FindPrevious(ElementType X, List L); void Insert(ElementType X, Position P); void DeleteList(List L); Position Header(List L); Position First(List L); Position Advance(Position P); ElementType Retrieve(Position P); void deleteNext(Position p); #endif
list.c
#include"list.h" #include<stdlib.h> #include"fatal.h" struct Node { ElementType Element; Position Next; }; int elementCmp(ElementType e1, ElementType e2) { return e1.Coefficient == e2.Coefficient && e1.Exponent == e2.Exponent; } List CreatList() { List l = malloc(sizeof(struct Node)); if (l == NULL) Error("out of memory"); l->Next = NULL; return l; } List MakeEmpty(List L) { if (L == NULL) Error("L is not created"); DeleteList(L); L->Next = NULL; return L; } int IsEmpty(List L) { return L->Next == NULL; } int IsLast(Position P, List L) { return P->Next == NULL; } Position Find(ElementType X, List L) { Position P; P = L->Next; while (P != NULL&& elementCmp(P->Element, X)) { P = P->Next; } return P; } void Delete(ElementType X, List L) { Position P; P = FindPrevious(X, L); if (!IsLast(P, L)) { Position TmpCell = P->Next; P->Next = TmpCell->Next; free(TmpCell); } } Position FindPrevious(ElementType X, List L) { Position P; P = L; while (P->Next != NULL&& elementCmp(P->Next->Element, X)) P = P->Next; return P; } void Insert(ElementType X, Position P) { Position tmpCell; tmpCell = (List)malloc(sizeof(struct Node)); if (tmpCell == NULL) FatalError("Out of space!!"); tmpCell->Element = X; tmpCell->Next = P->Next; P->Next = tmpCell; } void DeleteList(List L) { Position p; p = L->Next; L->Next = NULL; while (p != NULL) { Position tmp; tmp = p->Next; free(p); p = tmp; } } Position Header(List L) { return L; } Position First(List L) { return L->Next; } Position Advance(Position P) { return P->Next; } ElementType Retrieve(Position P) { return P->Element; } void deleteNext(Position p) { Position temp = p->Next->Next; free(p->Next); p->Next = temp; }
#ifndef _biginteger_h #define _biginteger_h #include<stdlib.h> #include"list.h" typedef struct { List list; }Biginteger; struct Node { ElementType Element; Position Next; }; Biginteger creatBiginteger(); void ZeroBiginteger(Biginteger big); void MulBiginteger(const Biginteger big1, const Biginteger big2, Biginteger bigProd); void printBiginteger(Biginteger big); #endif
#include"biginteger.h" #include<stdio.h> static int BASE = 10000; static void carry(ElementType * e, Biginteger big); Biginteger creatBiginteger() { Biginteger poly; poly.list = CreatList(); return poly; } static void insertMonomial(ElementType e, Biginteger big) { Position p = big.list; while (Advance(p) != NULL && Advance(p)->Element.Exponent > e.Exponent) p = Advance(p); if (Advance(p) == NULL) { Insert(e, p); } else if (Advance(p)->Element.Exponent != e.Exponent) Insert(e, p); else { Advance(p)->Element.Coefficient += e.Coefficient; if (Advance(p)->Element.Coefficient >= BASE) carry(&(Advance(p)->Element), big); //if (Advance(p)->Element.Coefficient == 0)这里不能要,有时会删除在更深一层删除了p //deleteNext(p); } } static void carry(ElementType * e, Biginteger big) { ElementType carry_e; carry_e.Coefficient = (*e).Coefficient / BASE; carry_e.Exponent = (*e).Exponent + 1; (*e).Coefficient = (*e).Coefficient % BASE; insertMonomial(carry_e, big); } void ZeroBiginteger(Biginteger big) { MakeEmpty(big.list); } void MulBiginteger(const Biginteger big1, const Biginteger big2, Biginteger bigProd) { ZeroBiginteger(bigProd); ElementType prod; for (Position i = big1.list->Next; i != NULL; i = Advance(i)) { for (Position j = big2.list->Next; j != NULL; j = Advance(j)) { prod.Coefficient = Retrieve(i).Coefficient * Retrieve(j).Coefficient; prod.Exponent = Retrieve(i).Exponent + Retrieve(j).Exponent; if (prod.Coefficient >= BASE) carry(&prod, bigProd); insertMonomial(prod, bigProd); } } } void printBiginteger(Biginteger big) { Position p = Advance(big.list); printf("%d", Retrieve(p).Coefficient); p = Advance(p); while (p) { printf("%04d", Retrieve(p).Coefficient);//当一个单元不满足的时候够进制的个数的时候,要补上0 p = Advance(p); } printf("\n"); }
main.c
#include"biginteger.h" #include<math.h> #define MAXN 1000 Biginteger powOfBiginteger(Biginteger big, int p) { Biginteger PowersOfXO[MAXN]; int cnt, i; Biginteger ans = creatBiginteger(); ElementType e; e.Coefficient = 1; e.Exponent = 0; Insert(e, ans.list); cnt = (int)log2(p); PowersOfXO[0].list = big.list; for (i = 1; i <= cnt; i++) { PowersOfXO[i] = creatBiginteger(); MulBiginteger(PowersOfXO[i - 1], PowersOfXO[i - 1], PowersOfXO[i]); } i = 0; while (p > 0) {//将n转换为2进制,如果为1乘 if (p % 2 == 1) { Biginteger temp = creatBiginteger(); MulBiginteger(ans, PowersOfXO[i], temp); ans.list = temp.list; } i++; p /= 2; } return ans; } int main() { Biginteger b1; b1 = creatBiginteger(); ElementType e; e.Coefficient = 2; e.Exponent = 0; Insert(e, b1.list); printBiginteger(powOfBiginteger(b1, 4000)); }