C++实现一个一元稀疏多项式简单计算器 数据结构

一、需求分析:包含题目要求,程序功能,运行方式,测试数据等

输入并建立多项式:建立一个多项式并保证输入和输出正确。

以类数学表达式的形式输出多项式:这里要注意输出形式,遇到常数项时不能输出x,第一项不能输出+号,系数值为1的非零次项的输出形式中略去系数1。

多项式a和b相加:建立多项式a+b。要把两个链表中对应相同指数相加,同时输出要正确,不能改变多项式顺序。

多项式a和b相减,建立多项式a-b:同多项式a和b相加,要把加法转变为减法,可以通过把每一项的系数换为相反数,再运行相加的函数去输出结果,这样不容易报错,同时让程序变得简单高效。

计算多项式在x=x0处的值:要把x0的值带入多项式的每一位,要注意计算的法则和常数项等特殊情况。

求多项式a的导数函数a’:通过把每一项的系数与指数相乘,再把指数减一完成,但也要注意常数项求导等于0时候,要把节点跳过。

通过主函数设计switch函数和dowhile循环多次运行对应函数,一次运行代码可以做到多次输出1-5的不同结果。

二、概要设计:包含抽象数据类型定义,程序模块等

把结构体定义float系数,int指数,对应程序要求,命名为PNode,*Polynomial指针。

typedef struct PNode{
    float coef;//系数
    int expn;//指数
    struct PNode *next;
}PNode,*Polynomial;

创建CreatePolyn函数作为多项式链表初始化函数,定义输入语句while循环输入不同节点对应数据。并将数据按指数大小排序。

创建display函数作为输出函数,输出每一个结点对应系数和指数并加上x,同时注意不要错误输出特殊项,如首项,指数为0常数项,负系数项。

创建AddPolyn作加法函数,设对应指针辅助,在正确条件时对节点系数进行相加,并赋值对应要输出的链表,同时定义SubPolyn作减法函数,将每一项系数赋值为其相反数,再作加法函数,达到对应目标。

创建CalPolyn函数作求对应x0的值,要同时做到求和与对应值正确。把每一项求值再求和,当x0=0时候要正确输出0或者常数项的和。

创建DerPolyn函数作求导函数,将指数与系数相乘得到节点的系数,指数再减1,然后循环这个方法直到每项都求导,并要注意指数为0时常数项求导等于0,应该跳过,并正确赋值,然后显示求导后多项式链表。

三、测试结果

测试数据1,结果正确: 

测试数据2,结果正确: 

测试数据3,结果正确:

 

 测试数据2改为多项式相减,结果正确:

X=x0求值,x为2,但多项式系数改为负数,结果正确: 

 对正的多项式求导,结果正确:

对负的多项式求导,结果正确: 

四、完整代码

#include <iostream>
#include <stdlib.h>
#include <math.h>
using namespace std;

typedef struct PNode{
    float coef;//系数
    int expn;//指数
    struct PNode *next;
}PNode,*Polynomial;

void CreatePolyn(Polynomial &P,int n){
    P = new PNode;
    P->next = NULL;//建立头结点单链表
    for(int i = 0;i<n;++i){//依次输入n个非0项
        Polynomial s = new PNode;//初始化节点
        cout<<"请输入第"<<i+1<<"个项系数和指数:";
        cin>>s->coef>>s->expn;//输入系数和指数
        Polynomial pre = P;//pre保存q的前驱,初始值为头结点
        Polynomial q = P->next;//q初始化,指向首元结点
        while (q&&q->expn<s->expn) {//通过比较指数找到第一个大于输入项指数的q
            pre = q;//pre指向q
            q = q->next;//q指向下一位
        }
        s->next = q;//输入项插入到q和前驱节点之间
        pre->next = s;
    }
}

void display(Polynomial &P){
    PNode *p = P->next;//建立头结点单链表
    cout<<"多项式为:";
    if(p == NULL)//当为空节点时直接输出0
        cout<<"0";
    if(p->expn == 0&&p->coef == 0){//指数系数为0时候直接跳向下一个节点
        p = p->next;
    }
    if(p->expn == 0)//指数为0输出系数,即常数项
        cout<<p->coef;
    else if (p->expn == 1) {//讨论指数为1时
        if(p->coef == 1){//指数系数同时为1时首项直接输出x
            cout<<"x";
        }
        else if (p->coef == -1) {//系数为-1时直接输出-x
            cout<<"-x";
        }
        else if (p->coef < 0) {//系数小于1时,输出系数并加上x
            cout<<p->coef<<"x";
        }
        else {
            cout<<p->coef<<"x";//系数大于0时,同理
        }
    }
    else {//讨论指数非0且非1的其他情况
        if(p->coef == 1){//系数为1直接输出x^
            cout<<"x^"<<p->expn;
        }
        else if (p->coef == -1) {//为-1直接输出-x^
            cout<<"-x^"<<p->expn;
        }
        else if (p->coef < 0) {//小于0正常输出系数指数并加上系数指数
            cout<<p->coef<<"x^"<<p->expn;
        }
        else {//其他情况同理
            cout<<p->coef<<"x^"<<p->expn;
        }
    }
    p = p->next;//指向下一个节点
    /*处理完首项特殊情况,再输出后面项的常规情况,
     * 只需要讨论将x前面加上+号或数前面加上加号,其余情况相同*/
    while(p){
        if(p->expn == 0&&p->coef == 0)
            p = p->next;
        if(p->expn == 0)
            cout<<p->coef;
        else if (p->expn == 1) {
            if(p->coef == 1){
                cout<<"+x";
            }
            else if (p->coef == -1) {
                cout<<"-x";
            }
            else if (p->coef < 0) {
                cout<<p->coef<<"x";
            }
            else {
                cout<<"+"<<p->coef<<"x";
            }
        }
        else {
            if(p->coef == 1){
                cout<<"+x^"<<p->expn;
            }
            else if (p->coef == -1) {
                cout<<"-x^"<<p->expn;
            }
            else if (p->coef < 0) {
                cout<<p->coef<<"x^"<<p->expn;
            }
            else {
                cout<<"+"<<p->coef<<"x^"<<p->expn;
            }
        }
        p = p->next;
    }
}

void AddPolyn(Polynomial &Pa,Polynomial &Pb){
    Polynomial p1,p2,p3,r;//初始化
    p1 = Pa->next;p2 = Pb->next;//指向首元结点
    p3 = Pa;//指向当前结点,初始值为pa
    while (p1&&p2) {//p2,p1非空时
        if(p1->expn == p2->expn){//指数相等
            float sum = p1->coef+p2->coef;//保存系数和
            if(sum != 0){//系数和不为0
                p1->coef = sum;//修改当前结点的系数值为和
                p3->next = p1; p3=p1;//修改后的pa当前结点连接在p3之后,p3指向p1
                p1 = p1->next;//p1指向后一项
                r = p2; p2 = p2->next; delete r;//删除pb当前结点,p2指向后一项
            }
            else {//系数和为0
                r = p1; p1 = p1->next; delete r;//删除pa前结点,p2指向后一项
                r = p2; p2 = p2->next; delete r;//删除pb当前结点,p2指向后一项
            }
        }
        else if (p1->expn<p2->expn) {//pa当前结点指数小
            p3->next = p1;//p3链在p1之后
            p3 = p1;//p3指向p1
            p1 = p1->next;//p1指向后一项
        }
        else {//pb当前结点小
            p3->next = p2;//p3链在p2之后
            p3 = p2;//p3指向p2
            p2 = p2->next;//p2指向后一项
        }
    }
    p3->next = p1?p1:p2;//插入非空多项式的剩余段
    delete Pb;//释放头结点
    display(Pa);
}

void SubPolyn(Polynomial &Pa,Polynomial &Pb){
    Polynomial p2;//初始化
    p2 = Pb->next;//指向首元结点
    while (p2) {//将减数每一项系数等于其相反数
        p2->coef = -(p2->coef);
        p2 = p2->next;
    }
    AddPolyn(Pa,Pb);//再运行加法函数。
}

void CalPolyn(Polynomial &Pa){
    Polynomial p1;//初始化
    p1 = Pa->next;//指向首元结点
    float x,sum = 0,sumAll = 0;//创建x0,结点和sum,总和sumAll
    cout<<"请输入x:";
    cin>>x;    
    while (p1) {//链表非空时
        sum = pow(x,p1->expn);//通过使用pow函数求x的次方
        sum = p1->coef*sum;//结点x0结果等于次方后再乘以系数
        sumAll = sum+sumAll;//把结果累加进总和
        p1 = p1->next;//指向下一个结点
    }
    display(Pa);//显示多项式
    cout<<"结果为:"<<sumAll;
}

void DerPolyn(Polynomial &Pa){
     Polynomial p1;//初始化
     p1 = Pa->next;//指向首元结点
     cout<<"求导前:";
     display(Pa);
     while (p1) {//链表非空时
        if(p1->expn == 0){//指数为0时候,即是常数求导
            p1->coef = 0;//常数求导等于0,系数等于0
            p1 = p1->next;//指向下一个结点
        }
        p1->coef = p1->coef*p1->expn;//系数等于指数乘以系数
        p1->expn = p1->expn-1;//系数减一
        p1 = p1->next;//指向下一个结点
     }
     cout<<"求导后:";
     display(Pa);
}

void userGuide(){
    cout<<"输入1,多项式相加"<<endl;
    cout<<"输入2,多项式相减"<<endl;
    cout<<"输入3,计算多项式在x=x0处的值"<<endl;
    cout<<"输入4,求多项式a的导数函数a’"<<endl;
    cout<<"输入5,输出一个多项式"<<endl;
    cout<<"输入你要做的操作:";
}

int main()
{
    int t,type,n1,n2;
    Polynomial p1,p2;
    do{
        userGuide();
        cin>>type;
        if(type>5||type<0){
            cout<<"输入错误!";
            exit(0);
        }
        switch (type) {
        case 1:
            cout<<"输入多项式1的项数:";
            cin>>n1;
            cout<<"输入多项式2的项数:";
            cin>>n2;
            CreatePolyn(p1,n1);
            CreatePolyn(p2,n2);
            AddPolyn(p1,p2);
            break;
        case 2:
            cout<<"输入多项式1的项数:";
            cin>>n1;
            cout<<"输入多项式2的项数:";
            cin>>n2;
            CreatePolyn(p1,n1);
            CreatePolyn(p2,n2);
            SubPolyn(p1,p2);
            break;
        case 3:
            cout<<"输入多项式1的项数:";
            cin>>n1;
            CreatePolyn(p1,n1);
            CalPolyn(p1);
            break;
        case 4:
            cout<<"输入多项式1的项数:";
            cin>>n1;
            CreatePolyn(p1,n1);
            DerPolyn(p1);
            break;
        case 5:
            cout<<"输入多项式1的项数:";
            cin>>n1;
            CreatePolyn(p1,n1);
            display(p1);
            break;
        }
        cout<<endl;
        cout<<"如需进行其他操作,请输入1:";
        cin>>t;
    }while (t == 1);
    return 0;
}

  • 10
    点赞
  • 78
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
下面是一个简单的一元稀疏多项式计算器的C++实现: ```cpp #include <iostream> #include <map> using namespace std; // 多项式项 struct Term { int coeff; // 系数 int exp; // 指数 }; // 多项式 class Polynomial { private: map<int, int> terms; // 用map存储多项式的项,键为指数,值为系数 public: // 构造函数 Polynomial() {} // 添加一个项 void add_term(int coeff, int exp) { if (coeff == 0) return; // 系数为0直接返回 if (terms.find(exp) != terms.end()) { // 指数已经存在 terms[exp] += coeff; // 系数相加 if (terms[exp] == 0) // 系数为0则删除该项 terms.erase(exp); } else { // 指数不存在 terms[exp] = coeff; } } // 求导 void differentiate() { for (auto it = terms.begin(); it != terms.end(); ++it) { int exp = it->first; int coeff = it->second; if (exp == 0) { // 常数项 it->second = 0; } else { // 非常数项 it->second = coeff * exp; it->first = exp - 1; } } } // 求值 int evaluate(int x) { int result = 0; for (auto it = terms.begin(); it != terms.end(); ++it) { int exp = it->first; int coeff = it->second; result += coeff * pow(x, exp); } return result; } // 输出多项式 void print() { bool first = true; for (auto it = terms.rbegin(); it != terms.rend(); ++it) { int exp = it->first; int coeff = it->second; if (coeff > 0) { if (!first) cout << "+"; } else { cout << "-"; } first = false; if (abs(coeff) != 1 || exp == 0) cout << abs(coeff); if (exp > 0) cout << "x"; if (exp > 1) cout << "^" << exp; } cout << endl; } }; // 主函数 int main() { Polynomial p; // 读入多项式 int coeff, exp; while (cin >> coeff >> exp) { p.add_term(coeff, exp); } // 输出多项式 p.print(); // 求导并输出 p.differentiate(); cout << "The derivative is: "; p.print(); // 求值并输出 int x; cout << "Enter the value of x: "; cin >> x; int result = p.evaluate(x); cout << "The value of the polynomial at x = " << x << " is: " << result << endl; return 0; } ``` 这个计算器支持读入一元稀疏多项式,求导,求值等操作。在实现中,使用了map来存储多项式的项,键为指数,值为系数。添加项时,如果指数已经存在,则将新系数加到原系数上;如果指数不存在,则直接插入新项。求导时,对于每一项,系数变为原系数乘以指数,指数减1;对于常数项,将系数设为0。求值时,遍历所有项,将每一项的系数乘以x的指数次方,然后累加到结果中。输出多项式时,从高到低遍历所有项,根据系数的正负和指数的大小输出不同的符号和系数的绝对值,指数为0时不输出x,指数为1时不输出指数的符号。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kun.A.A

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值