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

来源:互联网 发布:以下哪种立体匹配算法 编辑:程序博客网 时间:2024/05/21 09:47

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


0 0
原创粉丝点击