两个多项式相乘 使用散列表加速 在计算时合并多项式的项

数据结构与算法分析——c语言描述 练习5.7 答案


使用散列表加速,O(1)时间找到相同的指数多项式进行合并,原来是一遍又一遍扫表链表找到相同指数的合并,复杂度为O(M^2*N^2),现在为O(MN),由于散列表并不能比较大小之类的。所以要相乘后再遍历一遍散列表添加到链表(此时指数顺序是乱的)。没有排序。

头文件管理好麻烦,没有c++的命名空间,所以hash的position和list的position冲突的,解决办法就是起一个不同的名字。。。

还有elementType重定义,解决办法是新建一个头文件,把elementType的定义加上去。然后再在hash和list中include


ElementType.h

#pragma once
#ifndef _ElementType_H
#define _ElementType_H

struct ElementType {
	int Coefficient;//系数  
	int Exponent;//指数  
};

#endif // ! ElementType_H


hashQuad.h


#ifndef _HashQuad_H
#define _HashQuad_H

#include"ElementType.h"

typedef unsigned int Index;
typedef Index Position_hash;

struct HashTbl;
typedef struct HashTbl* HashTable;

HashTable initializeTable(int tableSize);
void destroyTable(HashTable h);
Position_hash find(ElementType key, HashTable h);
HashTable insert(ElementType key, HashTable h);
HashTable rehash(HashTable h);
ElementType retrive(Position_hash p, HashTable h);
int isLegitimate(Position_hash pos, HashTable h);

#endif


hashQuad.cpp

#include"hashQuad.h"
#include"fatal.h"
#include<math.h>
#include<string.h>
#define MinTableSize 5

enum KindOfEntry { Legitimate, Empty, Deleted };

struct HashEntry {
	ElementType element;
	enum KindOfEntry info;
};

typedef struct HashEntry Cell;

struct HashTbl {
	int tableSize;
	int hasInsertedNum;
	Cell *theCells;//数组
};

static int hash(ElementType key, int tableSize) {
	return key.Exponent % (tableSize);
}

static Position_hash hash2(ElementType key, int tableSize) {
	return 7 - (key.Exponent % 7);
}

static int isPrime(int num) {
	for (int i = 2; i <= sqrt(num); i++)
		if (num%i == 0)
			return 0;
	return 1;
}
static int nextPrime(int num) {
	int i = num;
	while (!isPrime(i))
		i++;
	return i;
}

int isLegitimate(Position_hash pos, HashTable h) {
	return h->theCells[pos].info == Legitimate;
}


HashTable initializeTable(int tableSize) {
	HashTable h;
	int i;
	if (tableSize < MinTableSize) {
		Error("Table size too small");
		return NULL;
	}
	h = (HashTable)malloc(sizeof(struct HashTbl));
	if (h == NULL)
		FatalError("Out of space!!!");
	h->tableSize = nextPrime(tableSize);
	h->theCells = (Cell *)malloc(sizeof(Cell)*h->tableSize);
	h->hasInsertedNum = 0;
	if (h->theCells == NULL)
		FatalError("Out of space!!!");
	for (i = 0; i < h->tableSize; i++) {
		h->theCells[i].info = Empty;
	}
	return h;
}

void destroyTable(HashTable h) {
	free(h->theCells);
	free(h);
}

Position_hash find(ElementType key, HashTable h) {
	Position_hash currentPos = hash(key, h->tableSize);
	int i = 0;
	while (h->theCells[currentPos].info != Empty && h->theCells[currentPos].element.Exponent != key.Exponent) {
		currentPos += (++i * hash2(key, h->tableSize));
		currentPos = currentPos % h->tableSize;
	}
	return currentPos;
}

HashTable insert(ElementType key, HashTable h) {
	if ((double)h->hasInsertedNum / h->tableSize > 0.5)
		h = rehash(h);
	Position_hash pos = find(key, h);
	if (h->theCells[pos].info == Empty) {
		h->theCells[pos].element = key;
		h->theCells[pos].info = Legitimate;
		h->hasInsertedNum++;
	}
	else if (h->theCells[pos].info == Legitimate) {
		h->theCells[pos].element.Coefficient += key.Coefficient;//同类项合并
	}
	return h;
}

HashTable rehash(HashTable h) {
	HashTable newH = initializeTable(h->tableSize * 2);
	for (int i = 0; i < h->tableSize; i++)
		if (h->theCells[i].info == Legitimate)
			insert(h->theCells[i].element, newH);
	destroyTable(h);
	return newH;
}



ElementType retrive(Position_hash p, HashTable h) {
	return h->theCells[p].element;
}



list.h



#ifndef _List_H  
#define _List_H  

#include"ElementType.h"

struct Node;
typedef struct Node *PtrToNode_list;
typedef PtrToNode_list List;
typedef PtrToNode_list Position_list;

List CreateList();
List MakeEmpty(List L);
int IsEmpty(List L);
int IsLast(Position_list P, List L);
Position_list Find(ElementType X, List L);
void Delete(ElementType X, List L);
Position_list FindPrevious(ElementType X, List L);
void Insert(ElementType X, Position_list P);
void DeleteList(List L);
Position_list Header(List L);
Position_list First(List L);
Position_list Advance(Position_list P);
ElementType Retrieve(Position_list P);
void deleteNext(Position_list p);
#endif  



list.cpp

#include"list.h"
#include<stdlib.h>
#include"fatal.h"


struct  Node {
	ElementType Element;
	Position_list Next;
};


int elementCmp(ElementType e1, ElementType e2) {
	return e1.Coefficient == e2.Coefficient && e1.Exponent == e2.Exponent;
}

List CreateList() {
	List l = (List)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_list P, List L) {
	return P->Next == NULL;
}

Position_list Find(ElementType X, List L) {
	Position_list P;
	P = L->Next;
	while (P != NULL&& elementCmp(P->Element, X)) {
		P = P->Next;
	}
	return P;
}

void Delete(ElementType X, List L) {
	Position_list P;
	P = FindPrevious(X, L);
	if (!IsLast(P, L)) {
		Position_list TmpCell = P->Next;
		P->Next = TmpCell->Next;
		free(TmpCell);
	}
}

Position_list FindPrevious(ElementType X, List L) {
	Position_list P;
	P = L;
	while (P->Next != NULL&& elementCmp(P->Next->Element, X))
		P = P->Next;
	return P;
}

void Insert(ElementType X, Position_list P) {
	Position_list 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_list p;
	p = L->Next;
	L->Next = NULL;
	while (p != NULL) {
		Position_list tmp;
		tmp = p->Next;
		free(p);
		p = tmp;
	}
}

Position_list Header(List L) {
	return L;
}

Position_list First(List L) {
	return L->Next;
}

Position_list Advance(Position_list P) {
	return P->Next;
}

ElementType Retrieve(Position_list P) {
	return P->Element;
}

void deleteNext(Position_list p) {
	Position_list temp = p->Next->Next;
	free(p->Next);
	p->Next = temp;
}


Polynomial.h

#ifndef _Polynomial_H
#define _Polynomial_H


#include"list.h"

typedef struct {
	List list;
}Polynomial;



Polynomial creatPolynomial();
void insertMonomials(ElementType e, Polynomial poly);
void inputPolynomial(Polynomial poly);
void ZeroPolynomial(Polynomial Poly);
void AddPolynomial(const  Polynomial Poly1, const  Polynomial Poly2, Polynomial PolySum);
void MulPolynomial(const  Polynomial Poly1, const  Polynomial Poly2, Polynomial PolyProd);
void printAll(Polynomial poly);


#endif // !_Polynomial_H



Polynomial.cpp

#include"Polynomial.h"
#include<stdio.h>
#include"hashQuad.h"

struct  Node {
	ElementType Element;
	Position_list Next;
};

enum KindOfEntry { Legitimate, Empty, Deleted };

struct HashEntry {
	ElementType element;
	enum KindOfEntry info;
};

typedef struct HashEntry Cell;

struct HashTbl {
	int tableSize;
	int hasInsertedNum;
	Cell *theCells;//数组
};

Polynomial creatPolynomial() {
	Polynomial poly;
	poly.list = CreateList();
	return poly;
}

void insertMonomials(ElementType e, Polynomial poly) {
	Position_list p = poly.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 == 0)
			deleteNext(p);
	}
}

void inputPolynomial(Polynomial poly) {
	int coefficient, exponent;
	ElementType monomials;
	printf("please enter Coefficient and Exponent,alphabet to end\n");
	while (scanf("%d", &coefficient) == 1) {
		scanf("%d", &exponent);
		monomials.Coefficient = coefficient;
		monomials.Exponent = exponent;
		insertMonomials(monomials, poly);
	}
	getchar();//字母还留在输入流当中,scanf是不会删去的
}


void ZeroPolynomial(Polynomial Poly) {
	MakeEmpty(Poly.list);
}

void AddPolynomial(const  Polynomial Poly1, const  Polynomial Poly2, Polynomial PolySum) {
	ZeroPolynomial(PolySum);
	Position_list p1 = Poly1.list->Next;
	Position_list p2 = Poly2.list->Next;
	Position_list p3 = PolySum.list;
	ElementType e;
	while (p1 && p2) {
		if (Retrieve(p1).Exponent > Retrieve(p2).Exponent) {
			Insert(Retrieve(p1), p3);

			p1 = Advance(p1);
			p3 = Advance(p3);
		}
		else if (Retrieve(p1).Exponent < Retrieve(p2).Exponent) {
			Insert(Retrieve(p2), p3);
			p2 = Advance(p2);
			p3 = Advance(p3);
		}
		else {
			int temp_coefficient = (Retrieve(p1).Coefficient + Retrieve(p2).Coefficient);
			if (temp_coefficient != 0) {
				e.Coefficient = temp_coefficient;
				e.Exponent = Retrieve(p1).Exponent;
				Insert(e, p3);
				p1 = Advance(p1);
				p2 = Advance(p2);
				p3 = Advance(p3);
			}
			else {
				p1 = Advance(p1);
				p2 = Advance(p2);
			}
		}
	}
	Position_list temp_p;
	temp_p = (p1) ? p1 : p2;
	if (temp_p == NULL)
		return;
	while (temp_p) {
		Insert(Retrieve(temp_p), p3);
		p3 = Advance(p3);
		temp_p = Advance(temp_p);
	}
}


void MulPolynomial(const  Polynomial Poly1, const  Polynomial Poly2, Polynomial PolyProd) {
	ZeroPolynomial(PolyProd);
	HashTable h = initializeTable(100);
	ElementType prod;
	for (Position_list i = Poly1.list->Next; i != NULL; i = Advance(i)) {
		for (Position_list j = Poly2.list->Next; j != NULL; j = Advance(j)) {
			prod.Coefficient = Retrieve(i).Coefficient * Retrieve(j).Coefficient;
			prod.Exponent = Retrieve(i).Exponent + Retrieve(j).Exponent;
			insert(prod, h);
		}
	}
	for (int i = 0; i < h->tableSize; i++) {
		if (h->theCells[i].info == Legitimate){
			Insert(h->theCells[i].element, PolyProd.list);
		}
	}
}


void printAll(Polynomial poly) {
	Position_list p = Advance(poly.list);
	printf("%dx^%d", Retrieve(p).Coefficient, Retrieve(p).Exponent);
	p = Advance(p);
	while (p) {
		if (Retrieve(p).Coefficient > 0)
			putchar('+');
		printf("%dx^%d", Retrieve(p).Coefficient, Retrieve(p).Exponent);
		p = Advance(p);
	}
	printf("\n");
}


main.cpp

#include"Polynomial.h"  
#include<stdio.h>  
#define N 1208  

int main() {
	Polynomial p1, p2, p3;
	p1 = creatPolynomial();
	p2 = creatPolynomial();
	p3 = creatPolynomial();
	inputPolynomial(p1);
	printAll(p1);
	inputPolynomial(p2);
	printAll(p2);
	MulPolynomial(p1, p2, p3);
	printf("\n");
	printAll(p3);
}


你可能感兴趣的:(两个多项式相乘 使用散列表加速 在计算时合并多项式的项)