C 數據結構:多項式的加法,乘法,微分運算

鏈表實現

例如:多項式
A(x) =x + 2x3

鏈表中的數據域有兩個成員:coef 存放多項式的係數;exp 存放指數

  • 多項式的數據結構
typedef struct PolyNode
{
	int coef;	//係數
	int exp;	//指數
	struct PolyNode * next;
}PolyNode,* PolyList;
  • 多項式加法實現:Add(PolyList l_a, PolyList l_b)
    例如:兩個多項式
    a(x)=x2 + 2x3 和 b(x)=x
    算法思想: a和b的單項式指數作比較;a的指數>b的指數,a加入到和多項式,反之,將b加入和多項式;a的指數=b的指數,如果a和b的係數和爲零,跳過此項,反之,將a和b單項式相加加入到和多項式。

  • 多項式乘法實現:Mcl(PolyList l_a, PolyList l_b)
    算法思想: 1. a的單項式乘b的每一項 2. 對獲得的乘積多項式求和

  • 多項式微分實現:DCPolyList(PolyList L)
    算法思想: 1. 跳過多項式中的常數項 2. 每一項的係數乘於指數,同時指數減一

遇到問題

對多項式a和b的和進行微分操作,會改變多項式a的鏈表中的成員值(具體表現爲多項式a的係數和指數發生改變)
將微分操作放在多項式乘積操作前,會導致多項式乘積出錯,或者程序意外終止。
錯誤截圖

解決過程

首先我想過是不是指針傳遞問題,導致多項式a的鏈表指針list_a被誤傳遞給了微分方法,導致鏈表list_a的成員被修改。然而我仔細找了一遍任然沒有發現直接對鏈表list_a進行更改的證據。
由於我不會使用VC++6.0進行調試,於是我就瘋狂的在整個程序執行過程中涉及到list_a和其他鏈表指針的地方輸出它們的地址(printf("%x",指針)),將所有的指針梳理了一遍。
指針表
指針表
在微分函數運行的過程中,我發現了其中的兩個指針指向的地址竟然就是list_a中的地址,那就說明是後來的指向修改了表list_a
其中一次的運行指針地址

解決問題

查看了一下我的微分函數,修改之前,我直接對指針L的鏈表進行操作(包括刪除),然後我發現在地址中指向了list_a的結點;修改之後,我重新建立一個鏈表來存儲微分結果,對L只執行遍歷操作,問題得到了解決。(至於爲什麼L會指向鏈表list_a中的結點,我也不太清楚,可以幫忙指出一下,這個問題可是卡了我好幾天)
多項式微分運算

正確截圖

正確的運行截圖

順序表實現

       順序表結構體存儲多項式,數組角標表示單項式指數,數組值存放單項式係數;相比較下通過順序表對多項式進行操作更加簡單,畢竟鏈表需要修改大量的指針。

  • 結構體如下:
typedef struct
{
	int elem[MAX_SIZE];
	int HighPower;
}PolyNode,* PolyList;
  • 多項式加法 PolyList AddPolyList(PolyList a, PolyList b)
  • 多項式乘法 PolyList MultPolyList(PolyList a, PolyList b)
    在乘法運算中,處理係數相同的單項式,順序表中只需要將數組下角標相同的兩個成員相加
  • 多項式微分 PolyList DiffPolyList(PolyList a)

遇到的問題

  • 乘法運算中的存放乘積的順序表mult的elem數組未初始化,得到結果亂碼

運算亂碼
因爲elem數組值沒有初始化,但後面有加上了數組值。
初始化數組值

運行截圖

順序表實現多項式的運算

全部代碼

鏈表實現

#include<stdio.h>
#include<stdlib.h>
typedef struct PolyNode
{
	int coef;	//係數
	int exp;	//指數
	struct PolyNode * next;
}PolyNode,* PolyList;

PolyList InitPolyList(PolyList L)
{
	///初始化鏈表
	L = (PolyList)malloc(sizeof(PolyNode));
	L->next = NULL;
	return L;
}

void CreatePolyList(PolyList L)
{
	///建立多項式
	PolyNode * node;
	int lceof, lexp;
	printf("請輸入多項式的係數和指數(指數從小到大依次輸入)\n");
	while(true)
	{
		scanf("%d%d",&lceof,&lexp);
		if(lceof == 0)		break;
		node = (PolyNode *)malloc(sizeof(PolyNode));
		node->next = NULL;
		node->coef = lceof;
		node->exp = lexp;
		L->next = node;
		L = L->next;
	}
	printf("創建成功!!\n\n");
}

void PrintPolyList(PolyList L)
{
	///打印多項式
	printf("====打印結果====\nA(x)=");
	while(L->next != NULL)
	{
		L = L->next;
		printf("%d",L->coef);
		if(L->exp != 0)		printf("x^%d",L->exp);
		if(L->next == NULL)		printf(";\n\n");
		else	printf("+");
	}
}

PolyList Add(PolyList l_a, PolyList l_b)
{
	///多項式相加
	PolyList L;
	L = InitPolyList(L);
	PolyList head = L;
	PolyNode *node;
	PolyList a, b;
	a = l_a->next;
	b = l_b->next;
	
	printf("執行多項式加法操作\n");
	while(a != NULL && b != NULL)
	{
		if(a->exp < b->exp)
		{
			//若多項式a的第一項指數小於多項式b第一項的指數,將第一項加入到和多項式
			node = (PolyNode*)malloc(sizeof(PolyNode));
			node->next = NULL;
			node->exp = a->exp;
			node->coef = a->coef;
			L->next = node;
			L = L->next;
			a = a->next;
		}
		else if(a->exp == b->exp)
		{
			if(a->coef + b->coef != 0)
			{
				//兩個係數相加不爲零纔有意義
				node = (PolyNode*)malloc(sizeof(PolyNode));
				node->next = NULL;
				node->exp = a->exp;
				node->coef = a->coef + b->coef;
				L->next = node;
				L = L->next;
				a = a->next;
				b = b->next;
			}
		}
		else
		{
			node = (PolyNode*)malloc(sizeof(PolyNode));
			node->next = NULL;
			node->exp = b->exp;
			node->coef = b->coef;
			L->next = node;
			L = L->next;
			b = b->next;
		}
	}
	if(a == NULL || b == NULL)
	{
		while(b != NULL)
		{
			L->next = b;
			L = L->next;
			b = b->next;
		}
		while(a != NULL)
			{
			L->next = a;
			L = L->next;
			a = a->next;
		}
	}
	printf("多項式求和操作成功!!\n");
	return head;
}

PolyList Mcl(PolyList l_a, PolyList l_b)
{
	///多項式乘法
	PolyList mult;
	mult = InitPolyList(mult);
	PolyNode *node;
	PolyList ax[100];
	int i = 0;

	PolyList a, b;
	a = l_a->next;

	printf("執行多項式乘法操作\n");
	while(a != NULL)
	{
		b = l_b->next;
		PolyList L = (PolyList)malloc(sizeof(PolyNode));
		ax[i] = L;
		while(b != NULL)
		{
			//結點插入失敗
			node = (PolyNode *)malloc(sizeof(PolyNode));
			node->next = NULL;
			node->coef = a->coef * b->coef;
			node->exp = a->exp + b->exp;
			L->next = node;
			L = L->next;
			b = b->next;
		}
		i++;
		a = a->next;
	}
	i--;
	PolyList m = ax[0];
	mult = ax[0];
	while(i > 0)
	{
		mult = Add(m, ax[i]);
		m = mult;
		i--;
	}
	return mult;
}

PolyList DCPolyList(PolyList L)
{
	///多項式微分運算
	PolyList head;
	head = (PolyList)malloc(sizeof(PolyNode));
	PolyList list = head;
	printf("多項式微分操作\n");
	while(L->next != NULL)
	{
		L = L->next;
		PolyNode * node;
		node = (PolyNode *)malloc(sizeof(PolyNode));
		node->next = NULL;
		if(L->exp == 0)
			continue;
		node->coef = L->coef * L->exp;
		node->exp = L->exp - 1;
		head->next = node;
		head = head->next;
		/*if(L->next->exp == 0)
		{
			//如果多項式的指數爲零,則刪除這一項
			PolyNode * node = L->next;
			L->next = L->next->next;
			free(node);
			node = NULL;
			continue;
		}
		else
		{
			L->next->coef = L->next->coef * L->next->exp;
			L->next->exp -= 1;
			L = L->next;
		}*/
	}
	printf("微分操作執行成功!!\n");
	return list;
}
int main()
{
	PolyList list_a, list_b;
	list_a = InitPolyList(list_a);
	list_b = InitPolyList(list_b);
	
	CreatePolyList(list_a);
	PrintPolyList(list_a);

	CreatePolyList(list_b);
	PrintPolyList(list_b);

	PolyList list_sum;	//多項式和
	list_sum = InitPolyList(list_sum);

	list_sum = Add(list_a, list_b);
	PrintPolyList(list_sum);

	PolyList list_dc;	//多項式微分
	list_dc = InitPolyList(list_dc);

	list_dc = DCPolyList(list_sum);
	PrintPolyList(list_dc);

	PolyList list_mult;	//多項式乘積
	list_mult = InitPolyList(list_mult);

	list_mult = Mcl(list_a, list_b);
	PrintPolyList(list_mult);

	return 0;
}

順序表實現

#include<stdio.h>
#include<stdlib.h>
#define MAX_SIZE 100
typedef struct
{
	int elem[MAX_SIZE];
	int HighPower;
}PolyNode,* PolyList;
PolyList CreatePolyList()
{
	///創建多項式
	PolyList P;
	P = (PolyList)malloc(sizeof(PolyNode));
	printf("請輸入多項式係數:\n");
	for(int i = 0; i < MAX_SIZE; i++)
	{
		scanf("%d",&P->elem[i]);
		if(getchar() == '\n')
		{
			P->HighPower = i;
			printf("%d",P->HighPower);
			break;
		}
	}
	printf("創建成功!\n\n");
	return P;
}

void PrintPolyList(PolyList P)
{
	///打印多項式
	printf("打印結果:A(x)=");
	for(int i = 0; i <= P->HighPower; i++)
	{
		if(P->elem[i] == 0)	continue;
		if(i == 0)	printf("%d",P->elem[i]);
		else	printf("%dx^%d",P->elem[i],i);
		if(i == P->HighPower) break;
		printf("+");
	}
	printf(";\n");
	printf("打印成功!!\n\n");
}

PolyList AddPolyList(PolyList a, PolyList b)
{
	///多項式求和
	PolyList sum;
	int i = 0;
	sum = (PolyList)malloc(sizeof(PolyNode));
	while(i <= a->HighPower|| i<= b->HighPower)
	{
		sum->elem[i] = a->elem[i] + b->elem[i];
		if(a->HighPower > b->HighPower)
			sum->HighPower = a->HighPower;
		else
			sum->HighPower = b->HighPower;
		i++;
	}
	return sum;
}

PolyList MultPolyList(PolyList a, PolyList b)
{
	PolyList mult;
	mult = (PolyList)malloc(sizeof(PolyNode));
	int i = 0;
	mult->HighPower = a->HighPower + b->HighPower;
	while(i <= mult->HighPower)
	{
		mult->elem[i] = 0;
		i++;
	}
	i = 0;
	while(i <= a->HighPower)
	{
		int j = 0;
		while(j<= b->HighPower)
		{
			mult->elem[i+j] += a->elem[i] * b->elem[j];
			j++;
		}
		i++;
	}
	while(i-- >= 0)
	{
		if(mult->elem[i] == 0)
		{
			mult->HighPower = i;
			break;
		}
		i--;
	}
	printf("多項式乘積運算完成!!\n");
	return mult;
}

PolyList DiffPolyList(PolyList a)
{
	///多項式微分
	PolyList diff;
	diff = (PolyList)malloc(sizeof(PolyNode));
	int i = 0;
	while(i <= a->HighPower - 1)
	{
		printf("%d",a->elem[i+1]);
		diff->elem[i] = a->elem[i+1] * (i+1);
		i++;
	}
	diff->HighPower = i - 1;
	return diff;
}
int main()
{
	PolyList a, b, sum, mult, diff;

	//創建兩個多項式
	a = CreatePolyList();
	printf("%d",a->HighPower);
	PrintPolyList(a);

	b = CreatePolyList();
	PrintPolyList(b);

	//求多項式和
	sum = AddPolyList(a, b);
	PrintPolyList(sum);

	//求多項式乘積
	mult = MultPolyList(a, b);
	PrintPolyList(mult);

	//求多項式乘積微分
	diff = DiffPolyList(mult);
	PrintPolyList(diff);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章