兩個多項式合并
多項式 L1 與 L2
處理方法:將較短 L2 ,合并到長的 L1
通過逐項比較,依次添加
L1 連續(xù)三項指數(shù) : X ,Y , Z
L1 某項指數(shù) :N
L2 某項指數(shù) :M
- 當(dāng) M == N 相同,則兩項系數(shù)相加,然后 L1 與 L2 都跳到下一項
注意:存在系數(shù)為0 的情況,位于中間項的可以直接扼殺在搖籃,不占內(nèi)存空間,位于結(jié)尾的則需要單獨處理
當(dāng) X < M < Y ,則需要把 M項 插入到 X,Y 兩項 之間
開頭和結(jié)尾需要單獨處理,也存在三種可能,指數(shù)相同,指數(shù)位于兩項之間,指數(shù)在開頭結(jié)尾
多項式排序
方法:
- 從左到右剔除第一個順序有問題的項,并保存
- 將此項插入到合適的位置
- 依次執(zhí)行,直到?jīng)]有順序錯誤的項
#include "pch.h"
#include <iostream>
using namespace std;
/*
1 : 最后顯示時的符號問題 ,此方法:void FindPolyn(ListNode L);
2 : 系數(shù)為0,解決方法:void AddPolyn(ListNode &L1, ListNode L2);
3 : 兩個多項式相加時,在第一個多項式結(jié)尾出現(xiàn)系數(shù)為0,這個零無法直接在產(chǎn)生時去除,解決方法:void DelZeroPolyn(ListNode &L);
4 : 多項式排序
5 : 兩個多項式合并,釋放剩余的多項式的內(nèi)存空間
*/
#define LIST_SIZE sizeof(LNode)
typedef struct Polynomial
{
float coef;
int expn;
struct Polynomial *next;
}LNode,*ListNode;
ListNode CreatePolyn(); // 創(chuàng)建一個多項式
void FindPolyn (ListNode L); // 查看多項式
int LengthPolyn (ListNode L); // 判斷多項式的長度
bool IsNULL (ListNode L); // 判斷是否為空
bool AddOnePolyn (ListNode &L1, ListNode &L2); // 處理 多項式 與 只有一項的多項式
bool AddPolyn (ListNode &L1, ListNode &L2); // 合并多項式
void DelZeroPolyn (ListNode &L); // 處理系數(shù)為零的情況
bool UnOrderPro (ListNode& L, LNode * &e); // 刪除按順序第一個錯誤位置的元素
bool SortPolyn(ListNode &L); // 插入刪除錯誤位置的元素
void ListLink (ListNode &L, int length); // 多項式排序
void UnRepetition(ListNode &L); // 多項式去重,前提條件,必須是有序多項式
void polynomial()
{
ListNode L1 = CreatePolyn(); // 創(chuàng)建多項式
cout << "_________________________" << endl;
ListNode L2 = CreatePolyn(); // 創(chuàng)建多項式
ListLink(L1, LengthPolyn(L1)); // 多項式排序
ListLink(L2, LengthPolyn(L2)); // 多項式排序
UnRepetition(L1); // 多項式去重
UnRepetition(L2); // 多項式去重
int n1 = LengthPolyn(L1); // 獲取多項式長度
int n2 = LengthPolyn(L2); // 獲取多項式長度
cout << "L1 = ";
FindPolyn(L1); // 查看多項式
cout << "_________________________" << endl;
cout << "L2 = ";
FindPolyn(L2); // 查看多項式
cout << "_________________________" << endl;
if (AddPolyn(L1, L2)) // 合并多項式
{
DelZeroPolyn(L1); // 多項式去零
cout
<< "L=";
FindPolyn(L1); // 查看多項式
}
cout << "_________________________長度:" << endl;
cout
<< n1 << "+" << n2 << "="
<< LengthPolyn(L1) // 獲取多項式長度
<< endl;
cout << "_________________________" << endl;
ListLink(L1, LengthPolyn(L1)); // 多項式排序
cout
<< "L=";
FindPolyn(L1); // 查看多項式
}
// 創(chuàng)建一個多項式
ListNode CreatePolyn()
{
LNode * L = (ListNode)malloc(LIST_SIZE);
if (!L) exit(1);
L->next = NULL;
LNode * p = (ListNode)malloc(LIST_SIZE),*q;
if (!p) exit(1);
int num = 1;
cout << "第 " << num << " 項" << endl;
cout << "輸入系數(shù):";
cin >> p->coef;
cout << "輸入指數(shù):";
cin >> p->expn;
q = L;
while ( 1)
{
if (p->coef == 0)
{
q->next = NULL;
break;
}
else
{
q->next = p;
q = p;
num++;
}
p = (ListNode)malloc(LIST_SIZE);
if (!p) exit(1);
cout << "第 " << num << " 項" << endl;
cout << "輸入系數(shù):";
cin >> p->coef;
cout << "輸入指數(shù):";
cin >> p->expn;
}
free(p);
return L;
}
// 查看多項式
void FindPolyn(ListNode L)
{
if (!L->next)
{
cout << 0 << endl;
return;
}
ListNode p = L->next;
while (p != NULL)
{
if (p->coef == 1)
{
// 系數(shù)為1,省略不寫
if (p->expn == 0)
{
// 系數(shù)為1,同時指數(shù)為0,則需要顯示 1
cout << p->coef;
}
}
else
{
cout << p->coef;
}
if (p->expn != 0)
{// 系數(shù)不為 0,指數(shù)為 0,則省略未知數(shù)部分
if (p->coef == 1)
{
// 系數(shù)為一,省略乘號
cout << "X^" << p->expn;
}
else
{
// 系數(shù)為一,顯示乘號
cout << "·X^" << p->expn;
}
}
if (p->next == NULL)
{
// 結(jié)尾,換行
cout << endl;
}
else
{
// 判斷下一項的系數(shù),添加符號
if(p->next->coef < 0)
cout << " ";
else
cout << " + ";
}
p = p->next;
}
}
// 判斷多項式的長度
int LengthPolyn(ListNode L)
{
int num = 0;
if (!L->next) return num; // 判斷是否為空多項式
ListNode p = L;
while (p->next != NULL)
{
p = p->next;
num++;
}
return num;
}
// 判斷是否為空
bool IsNULL(ListNode L)
{
return L->next == NULL;
}
//處理 多項式 與 只有一項的多項式
bool AddOnePolyn(ListNode &L1, ListNode &L2)
{
ListNode p1, p2 , q;
if (LengthPolyn(L1) < LengthPolyn(L2))
{
// 第一個多項式長度 小于 第二個多項式
p1 = L2, p2 = L1;
}
else
{
// 否則,默認
p1 = L1, p2 = L2;
}
while (p1->next != NULL)
{
if (p2->expn == p1->expn)
{
// 當(dāng)指數(shù)相同,系數(shù)相加
p1->coef = p1->coef + p2->coef;
// 釋放內(nèi)存空間
free(p2);
return true;
}
else if (p2->expn > p1->expn && p2->expn < p1->next->expn)
{
// 位于第一個多項式某兩項之間
// 新建空間 q ,存放 p2 的內(nèi)容
q = (ListNode)malloc(LIST_SIZE);
if (!q) exit(1);
q->coef = p2->coef;
q->expn = p2->expn;
q->next = NULL;
// 添加 q 到 p1 中
q->next = p1->next;
p1->next = q;
// 釋放內(nèi)存空間
free(p2);
return true;
}
else if (p2->expn < L1->next->expn)
{
// 小于第一個多項式的第一項
p2->next = p1;
L1->next = p2;
return true;
}
p1 = p1->next;
}
// 處理最后一項
if (p1->next == NULL)
{
if (p2->expn == p1->expn)
{
// 當(dāng)指數(shù)相同,系數(shù)相加
p1->coef = p1->coef + p2->coef;
// 釋放內(nèi)存空間
free(p2);
}
else
p1->next = p2;
}
return true;
}
// 合并多項式
bool AddPolyn(ListNode &L1, ListNode &L2)
{
if ((IsNULL(L1) && IsNULL(L2))
|| (!IsNULL(L1) && IsNULL(L2))
)
{
// 兩個都為空
// 第一個不為空,第二個為空
return false;
}
else if (IsNULL(L1) && !IsNULL(L2))
{
// 第一個為空,第二個不為空
L1 = L2;
return true;
}
ListNode p1, p2;
if (LengthPolyn(L1) < LengthPolyn(L2))
{
// 第一個多項式長度 小于 第二個多項式
p1 = L2->next, p2 = L1->next;
}
else
{
// 否則,默認
p1 = L1->next, p2 = L2->next;
}
ListNode q , p;
// q 作用: 新建內(nèi)存,存放數(shù)據(jù)
// p 作用: 釋放L2元素內(nèi)存空間
//可以釋放L2頭節(jié)點
L2->next = NULL;
free(L2);
// 若第二個多項式僅一項
if (p2->next == NULL)
{
if (AddOnePolyn(p1, p2))
return true;
else
return false;
}
while (1)
{
if (p1->next == NULL || p2->next == NULL)
{// 當(dāng)一個多項式結(jié)束,則跳出循環(huán)
break;
}
if (p1->expn == p2->expn)
{
// 當(dāng)指數(shù)相同,系數(shù)相加
p1->coef = p1->coef + p2->coef;
// 兩式均跳到下一項
if (p1->coef == 0)
{
// 若系數(shù)為0,需要刪除本位元素,并釋放空間
// 存在問題,最后一項系數(shù)為零無法去除,因此創(chuàng)建方法 void DelZeroPolyn(ListNode &L) 去除系數(shù)為零
// 雖然 DelZeroPolyn 可以去除全部為零的項,但為了減少內(nèi)存占用,此處先去除中間的零
if (p1->next != NULL)
{
// 方法:
// 把下一項傳過來,釋放下一項
// 先判斷下一項是否為空
q = p1->next; // 獲取下一項的地址
p1->coef = p1->next->coef; // 修改 本項系數(shù) 為 下一項系數(shù)
p1->expn = p1->next->expn; // 修改 本項指數(shù) 為 下一項指數(shù)
p1->next = p1->next->next; // 指針 指向 下一項的下一項
free(q); // 釋放下一項的內(nèi)存空間
}
}
else
{
p1 = p1->next;
}
p = p2;
p2 = p2->next;
// 釋放內(nèi)存空間
free(p);
}
else if (p1->expn > p2->expn)
{
// 添加數(shù)據(jù)項
// 若第一項指數(shù)大于第二項,因此第二項 遍歷直到遇到 第一項相同的指數(shù),中間的添加到 L1式中
// 新建空間 q ,存放 p2 的內(nèi)容
q = (ListNode)malloc(LIST_SIZE);
if (!q) exit(1);
q->coef = p2->coef;
q->expn = p2->expn;
q->next = NULL;
// 添加 q 到 p1 中
q->next = p1->next;
p1->next = q;
// 獲取p2當(dāng)前位置
p = p2;
// L2跳到下一項
p2 = p2->next;
p1 = p1->next;
// 釋放內(nèi)存空間
free(p);
}
else if (p1->expn < p2->expn)
{
// 若第一項指數(shù)小于第二項,遍歷到下一項
p1 = p1->next;
}
}
// 最后一項沒有進行檢測,因此需要在次檢測
if ( (p1->next == NULL && p2->next == NULL) || (p2->next == NULL && p1->next != NULL))
{
if (AddOnePolyn(p1, p2))
return true;
else
return false;
}
// 當(dāng)?shù)谝粋€多項式結(jié)束,第二個多項式仍存在,則把第二個多項式的內(nèi)容追加在第一個多項式后邊
if (p1->next == NULL && p2->next != NULL)
{
p1->next = p2;
}
}
// 處理系數(shù)為零的情況
void DelZeroPolyn(ListNode &L)
{
// 判斷是否為空
if (IsNULL(L))
{
return;
}
ListNode p = L->next , fr;
// 處理第一項
if (p->coef == 0)
{
L->next = p->next;
}
while (p->next->next != NULL)
{
if (p->next->coef == 0)
{
fr = p->next;
p->next = fr->next;
free(fr);
}
p = p->next;
}
// 處理最后一項
if (p->next->coef == 0)
{
fr = p->next;
p->next = NULL;
free(fr);
}
}
// 多項式排序
void ListLink(ListNode &L, int length)
{
if (length < 0 || L->next == NULL) return;
int i = 0;
// 最多的可能項為 n-1
while (i < length)
{
SortPolyn(L);
i++;
}
}
// 插入刪除錯誤位置的元素
bool SortPolyn(ListNode &L)
{
if (IsNULL(L)) return false;
ListNode e;
if (!UnOrderPro(L, e)) // 獲取有問題的第一項
{
return false;
}
ListNode lo = L->next;
// 判斷第一項,lo是第一項
if (lo->expn >= e->expn)
{
e->next = lo;
L->next = e;
return true;
}
while (lo->next != NULL)
{
if (e->expn >= lo->expn && e->expn <= lo->next->expn)
// 中間某項,指數(shù)在本項和后一項之間,便插入
{
e->next = lo->next;
lo->next = e;
break;
return true;
}
lo = lo->next;
}
// 判斷最后一項
if (lo->next == NULL && lo->expn <= e->expn)
{
lo->next = e;
return true;
}
return false;
}
// 刪除書序有問題的指針,并返回該指針
bool UnOrderPro(ListNode &L,LNode * &e)
{
if (IsNULL(L)) return false; // 空的多項式
ListNode p = L->next;
// p 對應(yīng) 多項式的第一項
if (p->next == NULL) return false; // 若只有一項,直接返回
if ( p->expn > p->next->expn) // 判斷第一項是否合理
{
e = p; // 獲取第一項
L->next = p->next; // 刪除第一項
e->next = NULL; // 修改第一項的next指針,防止影響原多項式
return true;
}
// 除第一項和最后一項,中間第一個位置有問題的項
while (p->next->next != NULL)
{
// 比較連續(xù)三項的指數(shù)
if ( ( (p->expn < p->next->expn) && (p->next->expn > p->next->next->expn) ) // 中間項 大于 前一項 且 大于 后一項
|| (p->expn > p->next->expn) // 中間項 小于 前一項
)
{
e = p->next; // 獲取錯誤項
p->next = p->next->next; // 修改指針,刪除中間項
e->next = NULL; // 修改錯誤項的next指針,防止影響原多項式
return true;
}
p = p->next; // 遍歷到下一項
}
// 判斷最后一項是否正確
if (p->next->next == NULL && (p->expn > p->next->expn) )
{
//比較最后兩項,若最后一項系數(shù)不正確,修改倒數(shù)第二次項的next指針
e = p->next;
e->next = NULL; // 修改錯誤項的next指針,防止影響原多項式
p->next = NULL;
return true;
}
//當(dāng)順序正確,不刪除任何,進行初始化
return false;
}
// 多項式去重,前提條件,必須是有序多項式
void UnRepetition(ListNode &L)
{
if (IsNULL(L)) return;
ListNode q = L->next;
ListNode fr;
while (q->next != NULL)
{
if (q->expn == q->next->expn)
{
// 連續(xù)兩項指數(shù)相等,系數(shù)相加,刪除后一項,并釋放內(nèi)存空間
q->coef = q->coef + q->next->coef;
fr = q->next;
q->next = q->next->next;
free(fr);
}
else
{
q = q->next;
}
}
}
簡便方法:直接將兩個多項式,合并,不排序,不去重,把最后的合并式直接去重,不需要寫上邊折磨復(fù)雜,把兩個多項式一項一項拼接,感覺有好多bug
void s()
{
ListNode L1 = CreatePolyn(); // 創(chuàng)建多項式
cout << "_________________________" << endl;
ListNode L2 = CreatePolyn(); // 創(chuàng)建多項式
ListNode p = L1;
while (p->next != NULL)
{
p = p->next;
}
if(p->next == NULL)
p->next = L2->next;
cout << "_________________________" << endl;
cout << "L" << " = ";
FindPolyn(L1);
cout << "_________________________" << endl;
ListLink(L1, LengthPolyn(L1));
cout << "L" << " = ";
FindPolyn(L1);
cout << "_________________________" << endl;
UnRepetition(L1);
cout << "L" << " = ";
FindPolyn(L1);
}
現(xiàn)在處于學(xué)習(xí)階段,考慮問題時,可能不全面,程序可能存在Bug,沒有找到,歡迎指正,會及時處理并修改
個人感覺,還存在一些bug,寫的時候出現(xiàn)各種bug,處理起來都快吐了