编写任意精度整数运行包。要使用类似于多项式运算的方法。计算在2^4000内数字0到9的分布

数据结构与算法分析——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;
}



biginteger.h

#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



biginteger.c

#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));
}



你可能感兴趣的:(编写任意精度整数运行包。要使用类似于多项式运算的方法。计算在2^4000内数字0到9的分布)