1. 程式人生 > >c++設計一個一元稀疏多項式簡單計算器

c++設計一個一元稀疏多項式簡單計算器

#include <iostream>  

using namespace std;

struct Node {
	float coef;
	int expn;
	Node *next;
	
};
void Copy(Node *&pc, Node *pa)//把一個連結串列的內容複製給另一個連結串列  
{
	Node *p,*q, *r;
	pc = new Node;
	pc->next = NULL;
	r = pc;
	p = pa;
	while (p->next != NULL)
	{
		q = new Node;
		q->coef = p->next->coef;
		q->expn = p->next->expn;
		r->next = q;
		q->next = NULL;
		r = q;
		p = p->next;
	}
}
void CreatPolynomial(Node *&head, int n)        //  生成帶表頭結點的單鏈表,除頭結點外另生成n個結點  
{
	head = (Node *)new Node;
	head->coef = 0;
	head->expn = 0;
	head->next = NULL;                           //  初始化頭結點  
	cout << "請輸入各項係數及指數:" << endl;
	Node *p = head;
	for (int i = 0; i < n; i++) {
		p->next = (Node *)new Node;  //  生成新結點,尾插入生成連結串列  
		p = p->next;
		cin >> p->coef >> p->expn;
		p->next = NULL;
	}
}

void PrintPolynomial(Node *&head)
{
	if (head->next == NULL)                           //  結果是0時直接輸出0  
		putchar('0');
	else {
		for (Node *p = head->next; p != NULL; p = p->next) {
			if (p != head->next && p->coef >0)      //  當p非首項且指向的係數為正時才輸出'+'  
				putchar('+');                       //  之前只判定了p->coef >0  

			if (p->coef == 1) {                       //  係數為1或-1時特殊處理  
				if (p->expn == 0)
					putchar('1');                   //  判斷條件不能寫在一起:  
			}                                       // if(p->coef == 1 && p->expn == 0) putchar('1');  
			else if (p->coef == -1)
				putchar('-');
			else
				cout << p->coef;

			switch (p->expn) {                        //  指數為0或1時特殊處理  

			case 0:
				break;

			case 1:
				putchar('x');
				break;

			default:
				p->expn < 0 ? printf("x^(%d)", p->expn) : printf("x^%d", p->expn);  //  指數小於0時打括號  
				break;
			}
		}
	}
	cout << endl;
}

void Free(Node *&head)
{
	Node *q = NULL;
	for (Node *p = head; p != NULL; p = q) {
		q = p->next;
		free(p);
	}
}

char cmp(int a, int b)
{
	if (a > b)
		return '>';
	if (a < b)
		return '<';
	return '=';
}

void AddPolynomial(Node *&pA, Node *&pB)        //  傳進兩個連結串列的頭指標  
{
	
	Node *ha = pA;
	Node *hb = pB;
	Node *qa = ha->next;                     //  ha, hb分別跟在qa, qb的後一位置  
	Node *qb = hb->next;                    //  qa, qb分別指向Pa, Pb中當前比較元素  
	while (qa && qb)
	{
		float sum = 0;
		int a = qa->expn;
		int b = qb->expn;
		switch (cmp(a, b)) {

		case '<':
			ha = qa;
			qa = qa->next;                       //  非ha = ha->next;  
			break;

		case '=':
			sum = qa->coef + qb->coef;
			if (sum != 0.0) {
				qa->coef = sum;
				ha = qa;
			}
			else {
				if (ha->next != qa)
					cout << "Error: ha->next != qa" << endl;
				ha->next = ha->next->next;     //  刪除和為0的結點,ha不變,還在qa後一位置  
				free(qa);
			}
			if (hb->next != qb)
				cout << "Error: hb->next != qb" << endl;
			hb->next = hb->next->next;
			free(qb);
			qb = hb->next;
			qa = ha->next;
			break;

		case '>':
			hb->next = hb->next->next;         //  刪除qb指向的結點  
			qb->next = ha->next;              //  將qb插入ha後qa前  
			ha->next = qb;

			qb = hb->next;                       //  not qb = ha->next  
			ha = ha->next;
			break;

		default:
			cout << "Error!" << endl;
			break;
		}
	}
	if (qb)
		ha->next = qb;
	free(hb);
}
void SubPolynomial(Node *&pA, Node *&pB)        //  傳進兩個連結串列的頭指標  
{
	
	Node *ha = pA;
	Node *qb = pB;
;   Node *hb = qb->next;
    Node *qa = ha->next;
	while (hb!=NULL) {
		
		hb->coef = -1*hb->coef;
		hb = hb->next;
	}
	while (qa && qb)
	{
		float sum = 0;
		int a = qa->expn;
		int b = qb->expn;
		switch (cmp(a, b)) {

		case '<':
			ha = qa;
			qa = qa->next;                       //  非ha = ha->next;  
			break;

		case '=':
			sum = qa->coef - qb->coef;
			if (sum != 0.0) {
				qa->coef = sum;
				ha = qa;
			}
			else {
				if (ha->next != qa)
					cout << "Error: ha->next != qa" << endl;
				ha->next = ha->next->next;     //  刪除和為0的結點,ha不變,還在qa後一位置  
				free(qa);
			}
			if (hb->next != qb)
				cout << "Error: hb->next != qb" << endl;
			hb->next = hb->next->next;
			free(qb);
			qb = hb->next;
			qa = ha->next;
			break;

		case '>':
			hb->next = hb->next->next;         //  刪除qb指向的結點  
			qb->next = ha->next;              //  將qb插入ha後qa前  
			ha->next = qb;

			qb = hb->next;                       //  not qb = ha->next  
			ha = ha->next;
			break;

		default:
			cout << "Error!" << endl;
			break;
		}
	}
	if (qb)
		ha->next = qb;
	free(hb);
	
}

int main( )
{
	 
	Node *A = NULL;
	Node *B = NULL;
	int lenA;
	int lenB;
	int choose;
	cout << "多項式加法請輸入1" << endl;
	cout << "多項式減法請輸入2" << endl;
	
	cin >> choose;
	
	while (choose!=0) {

		cout << "請輸入A的項數:" << endl;
		cin >> lenA;
		CreatPolynomial(A, lenA);                   //  生成A連結串列         
		cout << "請輸入B的項數:" << endl;         //  生成B連結串列  
		cin >> lenB;
		
		switch (choose)
		{
		case 1:
			CreatPolynomial(B, lenB);
			cout << " A = ";                          //  輸出A連結串列  
			PrintPolynomial(A);
			cout << " B = ";                          //  輸出B連結串列  
			PrintPolynomial(B);


			AddPolynomial(A, B);                        //  A = A + B  
			cout << "A+B= ";
			PrintPolynomial(A);                         //  輸出和  
			cout << endl;

			delete A;                                    //  務必釋放結點 
			cout << "多項式加法請輸入1" << endl;
			cout << "多項式減法請輸入2" << endl;
			cout << "輸入0退出" << endl;
			cin >> choose;
			break;

		case 2:
			CreatPolynomial(B, lenB);
			cout << " A = ";                          //  輸出A連結串列  
			PrintPolynomial(A);
			cout << " B = ";                          //  輸出B連結串列  
			PrintPolynomial(B);


			SubPolynomial(A, B);                        //  A = A - B  
			cout << "A-B= ";
			PrintPolynomial(A);                         //  輸出差  
			cout << endl;

			delete A;                                   
			cout << "多項式加法請輸入1" << endl;
			cout << "多項式減法請輸入2" << endl;
			cout << "輸入0退出" << endl;
			cin >> choose;
			break;
		}
	}
	return 0;
}