1-1 一元多项式的乘法与加法运算 (25分) HBU-DS 实验
设计函数分别求两个一元多项式的乘积与和。
输入格式:
输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数(绝对值均为不超过1000的整数)。数字间以空格分隔。
输出格式:
输出分2行,分别以指数递降方式输出乘积多项式以及和多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。零多项式应输出0 0
。
输入样例:
4 3 4 -5 2 6 1 -2 0
3 5 20 -7 4 3 1
输出样例:
15 24 -25 22 30 21 -10 20 -21 8 35 6 -33 5 14 4 -15 3 18 2 -6 1
5 20 -4 4 -5 2 9 1 -2 0
~
这是很坎坷的一道题,第一次数据结构实验就开始写了,然后写了两节课不行,各种错误(刚开始是用链表),然后中午回宿舍用map+vector写了一下,也AC了。然后接下来的一个多星期也在写这个题,用链表,因为当时数据结构还没讲链表,我链表的操作都是靠大一上的记忆+翻一下大一上的c语言书,总之很坎坷。然后最后终于写完正确之后,又用数组写了一遍,还是数组方便,链表确实有点麻烦。
数组那个刚才又重写了一遍,还算好看。至于剩下俩个,年段比较久远,不太好看。
思路
主要就是写一个addData函数,把新的数据按照指数大小顺序(如果指数相同就系数相加)添加到数据集里。
代码_数组
#include <iostream>
#include <cstdlib>
using namespace std;
struct LNode
{
int data[1005][2];
int last;
};
typedef LNode *List;
List Read();
List JiaFa(List L1, List L2);
List ChengFa(List L1, List L2);
void AddDataToList(List L, int a, int);
void PrintList(List L);
int main()
{
List L1 = Read();
List L2 = Read();
List L3 = ChengFa(L1, L2);
List L4 = JiaFa(L1, L2);
PrintList(L3);
cout << endl;
PrintList(L4);
}
List Read()
{
int n;
int a, e;
List L = (List)malloc(sizeof(LNode));
L->last = -1;
cin >> n;
while (n--)
{
cin >> a >> e;
L->data[++L->last][0] = a;
L->data[L->last][1] = e;
}
return L;
}
List ChengFa(List L1, List L2)
{
List L3 = (List)malloc(sizeof(LNode));
L3->last = -1;
for (int i = 0; i <= L1->last; ++i)
{
for (int j = 0; j <= L2->last; ++j)
{
int a = L1->data[i][0] * L2->data[j][0];
int e = L1->data[i][1] + L2->data[j][1];
AddDataToList(L3, a, e);
}
}
return L3;
}
List JiaFa(List L1, List L2)
{
List L4 = (List)malloc(sizeof(LNode));
L4->last = -1;
for (int i = 0; i <= L1->last; ++i)
AddDataToList(L4, L1->data[i][0], L1->data[i][1]);
for (int i = 0; i <= L2->last; ++i)
AddDataToList(L4, L2->data[i][0], L2->data[i][1]);
return L4;
}
void AddDataToList(List L, int a, int e)
{
if (a == 0)
return;
int i;
for (i = 0; i <= L->last && L->data[i][1] > e; ++i)
;
//出循环 要么i现在时L-> last+ 1 那么前面的项 都>e
// 要么 现在这个数据结点的i<=e
if (i == L->last + 1)
{
L->data[++L->last][0] = a;
L->data[L->last][1] = e;
return;
}
//或者现在这个数据结点 相等
if (L->data[i][1] == e)
{
L->data[i][0] += a;
return;
}
//或者 这个还小:从这个开始到last都往右挪一个
for (int j = L->last; j >= i; --j)
{
L->data[j + 1][0] = L->data[j][0];
L->data[j + 1][1] = L->data[j][1];
}
L->data[i][0] = a;
L->data[i][1] = e;
L->last++;
return;
}
void PrintList(List L)
{
bool isAllZero = true;
for (int i = 0; i <= L->last; ++i)
{
if (L->data[i][0] != 0)
{
isAllZero = false;
break;
}
}
if (!isAllZero)
{
int cnt = -1;
for (int i = 0; i <= L->last; ++i)
{
if (L->data[i][0] == 0)
continue;
else
{
if ((++cnt) == 0)
cout << L->data[i][0] << " " << L->data[i][1];
else
cout << " " << L->data[i][0] << " " << L->data[i][1];
}
}
}
else
cout << "0 0";
}
代码_map+vector
#include <iostream>
#include <map>
#include <algorithm>
#include <vector>
using namespace std;
bool cmp(pair<int, int> p1, pair<int, int> p2)
{
return p1.first > p2.first;
}
int main()
{
int N1, N2;
map<int, int> m1, m2, m3, m4;
cin >> N1;
int a, b;
while (N1--)
{
cin >> a >> b;
m1[b] = a;
}
cin >> N2;
while (N2--)
{
cin >> a >> b;
m2[b] = a;
}
for (auto it1 = m1.begin(); it1 != m1.end(); it1++)
{
for (auto it2 = m2.begin(); it2 != m2.end(); it2++)
{
m3[it1->first + it2->first] += it1->second * it2->second;
}
}
//错误思路: 如果指数相等,相加:其实不用。直接相加,如果系数相等就+=,不相等直接等于
//先算出相等的项*-1 ,再全加起来,
for (auto it = m1.begin(); it != m1.end(); it++)
{
m4[it->first] += it->second;
}
for (auto it = m2.begin(); it != m2.end(); it++)
{
m4[it->first] += it->second;
}
vector<pair<int, int>> v1;
for (auto it = m3.begin(); it != m3.end(); it++)
{
v1.push_back(make_pair(it->first, it->second));
}
vector<pair<int, int>> v2;
for (auto it = m4.begin(); it != m4.end(); it++)
{
v2.push_back(make_pair(it->first, it->second));
}
sort(v1.begin(), v1.end(), cmp);
sort(v2.begin(), v2.end(), cmp);
int flag = -1;
for (int i = 0; i < v1.size(); i++)
{
if (v1[i].second != 0)
{
flag = 1;
}
}
if (flag == 1)
{
for (int i = 0; i < v1.size(); i++)
{
if (v1[i].second == 0)
;
else
{
if (!i)
cout << v1[i].second << " " << v1[i].first;
else
cout << " " << v1[i].second << " " << v1[i].first;
}
}
}
else
{
cout << "0 0";
}
flag = -1;
puts("");
for (int i = 0; i < v2.size(); i++)
{
if (v2[i].second != 0)
{
flag = 1;
}
}
if (flag == 1)
{
for (int i = 0; i < v2.size(); i++)
{
if (v2[i].second == 0)
;
else
{
if (!i)
cout << v2[i].second << " " << v2[i].first;
else
cout << " " << v2[i].second << " " << v2[i].first;
}
}
}
else
cout << "0 0";
}
代码_链表
#include <iostream>
#include <cstdlib>
using namespace std;
typedef struct Node *List;
struct Node
{
int zhishu;
int xishu;
List next;
};
List addData(List L, int xishu, int zhishu);
void PrintList(List L)
{
if (L == nullptr)
{
cout << "0 0";
return;
}
int flag = 0;
List temp = L;
while (temp)
{
if (temp->xishu != 0) //有非零项
{
flag = 1;
break;
}
temp = temp->next;
}
if (flag == 0)
{
cout << "0 0";
}
else
{
int count = 0;
temp = L;
while (temp)
{
if (temp->xishu == 0)
{
temp = temp->next;
continue;
//如果直接continue的话,将陷入死循环!
}
if (count++)
{
cout << " ";
}
cout << temp->xishu << " " << temp->zhishu;
temp = temp->next;
}
}
}
int main()
{
int N;
cin >> N;
List p1 = nullptr, temp = nullptr;
//将第一行数据输入链表
while (N--)
{
List currNode = (List)malloc(sizeof(Node));
int a, b;
cin >> a >> b;
currNode->xishu = a;
currNode->zhishu = b;
currNode->next = NULL;
if (p1 == nullptr)
{
p1 = currNode;
temp = p1;
}
else
{
temp->next = currNode;
temp = temp->next;
}
}
cin >> N;
List p2 = nullptr;
temp = nullptr;
while (N--)
{
List currNode = (List)malloc(sizeof(Node));
int a, b;
cin >> a >> b;
currNode->xishu = a;
currNode->zhishu = b;
currNode->next = NULL;
if (p2 == nullptr)
{
p2 = currNode;
temp = p2;
}
else
{
temp->next = currNode;
temp = temp->next;
}
}
//乘法
List p3 = nullptr;
temp = nullptr;
List temp1 = p1, temp2 = p2; //temp1 2分别指向p1 p2
while (temp1)
{
temp2 = p2;
while (temp2)
{
int xishu = temp1->xishu * temp2->xishu;
int zhishu = temp1->zhishu + temp2->zhishu;
p3 = addData(p3, zhishu, xishu);
temp2 = temp2->next;
}
temp1 = temp1->next;
}
//加法
List p4 = nullptr;
temp = p1;
while (temp)
{
int xishu = temp->xishu;
int zhishu = temp->zhishu;
if (xishu == 0)
continue;
//即使这样,也不能保证里面没有非0项
p4 = addData(p4, zhishu, xishu);
temp = temp->next;
}
temp = p2;
while (temp)
{
int xishu = temp->xishu;
int zhishu = temp->zhishu;
if (xishu == 0)
continue;
p4 = addData(p4, zhishu, xishu);
temp = temp->next;
}
PrintList(p3);
cout << endl;
PrintList(p4);
}
List addData(List head, int zhishu, int xishu)
{
List currNode = (List)malloc(sizeof(Node));
currNode->zhishu = zhishu;
currNode->xishu = xishu;
currNode->next = NULL;
if (head == nullptr)
{
head = currNode;
return head;
}
//不是空链表
List pr = head, temp = head; //这个问题temp =null为什么会错!
while (pr->next != nullptr && pr->zhishu > zhishu)
{
temp = pr;
pr = pr->next;
}
//如果是在中间插入的
if (pr->zhishu <= zhishu)
{
//如果已经存在的
if (pr->zhishu == zhishu)
{
pr->xishu += xishu;
}
//需要添加一个结点的
else
{
if (pr == head)
{
currNode->next = head;
head = currNode;
}
else
{
pr = temp;
currNode->next = pr->next;
pr->next = currNode;
}
}
}
//是在最后插入的
else
{
pr->next = currNode;
}
return head;
}