Qt用widget加上数据结构做一个简单的一元稀疏多项式计算器

这是我第一次写博客,肯定会有诸多不足,还请见谅。同时我也是想记录下来,以便以后查询。接下来是简单的介绍:

  1. 这是我数据结构课程的一个小作业,要求是采用一种数据结构与实际生活相结 合,自由发挥写一个比较有用的小程序。

  2. 算法部分采用了单链表实现,参考了一些网上的代码。

程序结果展示

1、主界面

程序主界面

2、主要功能和操作方式介绍

1、操作方式介绍

  1. 输入:需要分为两个多项式分别输入。点击L1进行第一个多项式的输入,同理第二个多项式也是。每次只能输入一个多项式,且在输入一个多项式时一次只能输入一项,输入一项后点击input即为输入成功,期间可点击C退格。接着可继续输入第二个多项式或进行计算

  2. 输出:计算功能包括多项式加法(+),多项式减法(-),多项式乘法(*),多项式求导(d(L1),d(L2))。首先点击COMPUTE后输出栏可显示,点击运算符后显示相关式子,点击等于即可得出相关结果。注:运算一次后需要点击清空AC

2、功能展示

  1. 输入:

输入
3. 计算:
①加法:
加法
②减法:
减法
③乘法:
乘法
④求导:
求导

3、代码部分

  1. 头文件widget.h:
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <iostream>
using namespace std;

typedef struct
 {
    double coef;//系数
    int expn;//指数
}Term;
typedef struct ploynomial
{
    Term term;
    ploynomial *next;
}ploynomial,*LinkList;


namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();

    void InitList(LinkList &L);

    int cmp(Term a,Term b);

    void insertNode(LinkList &L,Term e);

    void visitList(LinkList L, QString& string);

    void addPolyn(LinkList &l,LinkList l1,LinkList l2);

    void multiplyPolyn(LinkList &l,LinkList l1,LinkList l2);   //返回L1*L2

    void SubtracatPolyn(LinkList &l,LinkList l1,LinkList l2);   //返回L1-L2的结果

    void derivativePolyn(LinkList &l,LinkList l1);

private slots:
    void on_pB_number1_clicked();

    void on_pB_number2_clicked();

    void on_pB_number3_clicked();

    void on_pB_number4_clicked();

    void on_pB_number5_clicked();

    void on_pB_number6_clicked();

    void on_pB_number7_clicked();

    void on_pB_number8_clicked();

    void on_pB_number9_clicked();

    void on_pB_number0_clicked();

    void on_pB_charDot_clicked();

    void on_pB_charPower_clicked();

    void on_pB_unNumber_clicked();

    void on_pB_delete_clicked();

    void on_pB_deleteAll_clicked();

    void on_pB_positive_clicked();

    void on_pB_negetive_clicked();

    void on_pB_Input_clicked();

    void on_pB_l1_clicked();

    void on_pB_l2_clicked();

    void on_pB_compute_clicked();

    void on_pB_equals_clicked();

    void on_pB_multiply_clicked();

    void on_pB_Derivatives_clicked();

    void on_pB_Derivatives2_clicked();

private:
    Ui::Widget *ui;

public:
    LinkList L1,L2,L3;
};

#endif // WIDGET_H

  1. 源文件widget.cpp,这部分代码500行左右,看似多,但多数都是类似的。
#include "widget.h"
#include "ui_widget.h"
#include "QString"
#include <QMessageBox>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    ui->showPolyn->setReadOnly(true);
    ui->showPolyn2->setReadOnly(true);
    ui->Result->setReadOnly(true);
    this->ui->showPolyn->setEnabled(false);
    this->ui->showPolyn2->setEnabled(false);
    this->ui->Result->setEnabled(false);
    InitList(L1);
    InitList(L2);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_pB_number1_clicked()
{
    if(this->ui->showPolyn->isEnabled())
        this->ui->showPolyn->insert("1");
    else if(this->ui->showPolyn2->isEnabled())
        this->ui->showPolyn2->insert("1");
}

void Widget::on_pB_number2_clicked()
{
    if(this->ui->showPolyn->isEnabled())
        this->ui->showPolyn->insert("2");
    else if(this->ui->showPolyn2->isEnabled())
        this->ui->showPolyn2->insert("2");
}

void Widget::on_pB_number3_clicked()
{
    if(this->ui->showPolyn->isEnabled())
        this->ui->showPolyn->insert("3");
    else if(this->ui->showPolyn2->isEnabled())
        this->ui->showPolyn2->insert("3");
}

void Widget::on_pB_number4_clicked()
{
    if(this->ui->showPolyn->isEnabled())
        this->ui->showPolyn->insert("4");
    else if(this->ui->showPolyn2->isEnabled())
        this->ui->showPolyn2->insert("4");
}

void Widget::on_pB_number5_clicked()
{
    if(this->ui->showPolyn->isEnabled())
        this->ui->showPolyn->insert("5");
    else if(this->ui->showPolyn2->isEnabled())
        this->ui->showPolyn2->insert("5");
}

void Widget::on_pB_number6_clicked()
{
    if(this->ui->showPolyn->isEnabled())
        this->ui->showPolyn->insert("6");
    else if(this->ui->showPolyn2->isEnabled())
        this->ui->showPolyn2->insert("6");
}

void Widget::on_pB_number7_clicked()
{
    if(this->ui->showPolyn->isEnabled())
        this->ui->showPolyn->insert("7");
    else
        this->ui->showPolyn2->insert("7");
}

void Widget::on_pB_number8_clicked()
{
    if(this->ui->showPolyn->isEnabled())
        this->ui->showPolyn->insert("8");
    else if(this->ui->showPolyn2->isEnabled())
        this->ui->showPolyn2->insert("8");
}

void Widget::on_pB_number9_clicked()
{
    if(this->ui->showPolyn->isEnabled())
        this->ui->showPolyn->insert("9");
    else if(this->ui->showPolyn2->isEnabled())
        this->ui->showPolyn2->insert("9");
}

void Widget::on_pB_number0_clicked()
{
    if(this->ui->showPolyn->isEnabled())
        this->ui->showPolyn->insert("0");
    else if(this->ui->showPolyn2->isEnabled())
        this->ui->showPolyn2->insert("0");
}

void Widget::on_pB_charDot_clicked()
{
    if(this->ui->showPolyn->isEnabled())
        this->ui->showPolyn->insert(".");
    else if(this->ui->showPolyn2->isEnabled())
        this->ui->showPolyn2->insert(".");
}

void Widget::on_pB_charPower_clicked()
{
    if(this->ui->showPolyn->isEnabled())
        this->ui->showPolyn->insert("^");
    else if(this->ui->showPolyn2->isEnabled())
        this->ui->showPolyn2->insert("^");
}

void Widget::on_pB_unNumber_clicked()
{
    if(this->ui->showPolyn->isEnabled())
        this->ui->showPolyn->insert("x");
    else if(this->ui->showPolyn2->isEnabled())
        this->ui->showPolyn2->insert("x");
}

void Widget::on_pB_delete_clicked()
{
    if(this->ui->showPolyn->isEnabled())
        this->ui->showPolyn->backspace();
    else if(this->ui->showPolyn2->isEnabled())
        this->ui->showPolyn2->backspace();
    else if(this->ui->Result->isEnabled())
        this->ui->Result->setText("");
}

void Widget::on_pB_deleteAll_clicked()
{
    if(this->ui->showPolyn->isEnabled())
        this->ui->showPolyn->setText("");
    else if(this->ui->showPolyn2->isEnabled())
        this->ui->showPolyn2->setText("");
    else if(this->ui->Result->isEnabled())
        this->ui->Result->setText("");
}

void Widget::on_pB_positive_clicked()
{
    if(this->ui->showPolyn->isEnabled())
        this->ui->showPolyn->insert("+");
    else if(this->ui->showPolyn2->isEnabled())
        this->ui->showPolyn2->insert("+");
    else {
        QString string1, string2;
        visitList(L1,string1);
        this->ui->Result->insert("(" + string1 + ")");
        this->ui->Result->insert(" + ");
        visitList(L2,string2);
        this->ui->Result->insert("(" + string2 + ")");
    }
}

void Widget::on_pB_negetive_clicked()
{
    if(this->ui->showPolyn->isEnabled())
        this->ui->showPolyn->insert("-");
    else if(this->ui->showPolyn2->isEnabled())
        this->ui->showPolyn2->insert("-");
    else {
        QString string1, string2;
        visitList(L1,string1);
        this->ui->Result->insert("(" + string1 + ")");
        this->ui->Result->insert(" - ");
        visitList(L2,string2);
        this->ui->Result->insert("(" + string2 + ")");
    }
}

void Widget::InitList(LinkList &L)  //链表初始化
{
    L=(ploynomial*)malloc(sizeof(ploynomial));//头结点
    L->term.coef=0.0;
    L->term.expn=-1;
    L->next=NULL;
}

int Widget::cmp(Term a,Term b)   //比较结点的指数大小
{
    if(a.expn>b.expn)
        return -1;
    else if (a.expn==b.expn)
        return 0;
    else
        return 1;
}

void Widget::insertNode(LinkList &L,Term e){
    ploynomial* q=L;
    while(q->next!=NULL)
    {
        if(cmp(q->next->term,e)<0)//如果当前结点q的下一个结点的指数大于要插入的结点指数
            q=q->next;//q指向下一个结点
        else break;
    }
    if(q->next!=NULL&&cmp(q->next->term,e)==0)//指数相同,系数相加
    {
        q->next->term.coef+=e.coef;
    }
    else
    {
        ploynomial* node = (ploynomial*) malloc(sizeof(ploynomial));
        node->term.coef=e.coef;
        node->term.expn=e.expn;
        if(q->next==NULL)
            node->next=NULL;
        else
            node->next=q->next;
        q->next=node;
    }
}

void Widget::visitList(LinkList L,QString& string)   //打印出一元多项式
{
    ploynomial *q=L;
    int flag;
    while(q->next!=NULL)
    {
        q=q->next;
        flag=1;
        if(q->term.coef==0) continue; //系数为0,不输出
        if(q->term.expn==0&&flag==1)//指数为1
        {
            if(q->term.coef>0)
                string.append("+" + QString::number(q->term.coef));//cout<<"+"<<q->term.coef;
            else
                string.append(QString::number(q->term.coef));//cout<<q->term.coef;
            flag=0;
        }
        if((q->term.coef==1 || q->term.coef==-1)&&flag==1)//系数为1
        {
            if(q->term.expn==1){
                if(q->term.coef==1)
                    string.append("+X");//cout<<"+X";
                else
                    string.append("-X");//cout<<"-X";
            }
            else{
                if(q->term.coef == 1)
                    string.append("+X^" + QString::number(q->term.expn));//cout<<"+X^"<<q->term.expn;
                else
                    string.append("-X^" + q->term.expn);//cout<<"-X^"<<q->term.expn;
            }
            flag=0;
        }
        if(flag==1)
        {
            if(q->term.coef>0)
                string.append("+" + QString::number(q->term.coef) + "X^" + QString::number(q->term.expn));//cout<<"+"<<q->term.coef<<"X^"<<q->term.expn;
            else
                string.append(QString::number(q->term.coef) + "X^" + QString::number(q->term.expn));//cout<<q->term.coef<<"X^"<<q->term.expn;
        }
    }
    //cout<<endl;
}

void Widget::addPolyn(LinkList &l,LinkList l1,LinkList l2)   //返回L1+L2的结果
{
    ploynomial *q;
    for(q=l1->next;q!=NULL;q=q->next)//将L1的每一项插入到L中
    {
        insertNode(l,q->term);
    }
    for(q=l2->next;q!=NULL;q=q->next)//将L2的每一项插入到L中
    {
    insertNode(l,q->term);
    }
}

void Widget::SubtracatPolyn(LinkList &l,LinkList l1,LinkList l2)   //返回L1-L2的结果
{
    ploynomial *q;
    for(q=l1->next;q!=NULL;q=q->next)//将L1的每一项插入到L中
    {
        insertNode(l,q->term);
    }
    for(q=l2->next;q!=NULL;q=q->next)
    {
        q->term.coef= -(q->term.coef);//将系数变成相反数,再进行相加,即L1-L2
        insertNode(l,q->term);//将L2的每一项插入到L中
    }
}

void Widget::multiplyPolyn(LinkList &l,LinkList l1,LinkList l2)   //返回L1*L2
{
        ploynomial *q,*p;
        Term term;
        term.coef=0.0;
        term.expn=0;
        for(q=l1->next;q!=NULL;q=q->next)
        {
            for(p=l2->next;p!=NULL;p=p->next)
            {
                term.coef=(q->term.coef)*(p->term.coef);//系数相乘
                term.expn=(q->term.expn)+(p->term.expn);//指数相加
                insertNode(l,term);
            }
        }
}

void Widget::derivativePolyn(LinkList &l,LinkList l1)   //返回L1的导数
{
    ploynomial *p;
    Term term;
    for(p=l1->next;p!=NULL;p=p->next)
    {
        if(p->term.expn==0)
        {
            continue;//指数为0,导数为0
        }
        else
        {
            term.coef=(p->term.coef)*(p->term.expn);//系数乘以指数
            term.expn=(p->term.expn)-1;//指数减1
            insertNode(l,term);
        }
    }
}

void Widget::on_pB_Input_clicked()
{
    Term term;
    QString temp1, temp2;
    if(this->ui->showPolyn->isEnabled() && !this->ui->showPolyn->text().isEmpty()){
        QString content = this->ui->showPolyn->text();
        for(int i = 0; i < content.length(); i++){
            if(content.contains('x',Qt::CaseSensitive) && content.contains('^',Qt::CaseSensitive)){
                /*if(i < content.indexOf('x') )*/
                if(i <= content.indexOf('x')){
                    if(i == 0 && content.at(0) == 'x'){
                        temp1.append("1");
                    }
                    /*else if(i == 0 && content.at(0) == '-' && content.at(1) == 'x'){
                        temp1.append("-");
                        temp1.append("1");
                    }*/

                    else if(i != content.indexOf('x') ){
                       temp1.append(content.at(i));
                    }
                }
                else if(i > content.indexOf('^'))
                    temp2.append(content.at(i));
            }
            else if(content.contains('x',Qt::CaseSensitive) && !content.contains('^',Qt::CaseSensitive)){
                if(i <= content.indexOf('x')){
                    if(i == 0 && content.at(0) == 'x'){
                        temp1.append("1");
                    }
                    /*else if(i == 0 && content.at(0) == '-' && content.at(1) == 'x')
                        temp1.append("-1");*/
                    else if(i != content.indexOf('x')){
                       temp1.append(content.at(i));
                    }
                }
             if(i == 0)
                temp2.append("1");
            }
            else if(!content.contains('x',Qt::CaseSensitive) && !content.contains('^',Qt::CaseSensitive)){
                if( content.at(0) != '.')
                    temp1.append(content.at(i));
                else
                    QMessageBox::warning(this, "提示", "输入错误!", "OK");
            }
        }
        term.coef = temp1.toDouble();
        term.expn = temp2.toInt();
        insertNode(L1,term);
        this->ui->showPolyn->setText("");
        QMessageBox::information(this, "提示", "输入成功!请输入下一项或进行其他操作", "OK");
    }
    else if(this->ui->showPolyn2->isEnabled() && !this->ui->showPolyn2->text().isEmpty()){
        QString content = this->ui->showPolyn2->text();
        for(int i = 0; i < content.length(); i++){
            if(content.contains('x',Qt::CaseSensitive) && content.contains('^',Qt::CaseSensitive)){
                /*if(i < content.indexOf('x') )*/
                if(i <= content.indexOf('x')){
                    if(i == 0 && content.at(0) == 'x'){
                        temp1.append("1");
                    }
                    /*else if(i == 0 && content.at(0) == '-' && content.at(1) == 'x'){
                        temp1.append("-");
                        temp1.append("1");
                    }*/

                    else if(i != content.indexOf('x') ){
                       temp1.append(content.at(i));
                    }
                }
                else if(i > content.indexOf('^'))
                    temp2.append(content.at(i));
            }
            else if(content.contains('x',Qt::CaseSensitive) && !content.contains('^',Qt::CaseSensitive)){
                if(i <= content.indexOf('x')){
                    if(i == 0 && content.at(0) == 'x'){
                        temp1.append("1");
                    }
                    /*else if(i == 0 && content.at(0) == '-' && content.at(1) == 'x')
                        temp1.append("-1");*/
                    else if(i != content.indexOf('x')){
                       temp1.append(content.at(i));
                    }
                }
             if(i == 0)
                temp2.append("1");
            }
            else if(!content.contains('x',Qt::CaseSensitive) && !content.contains('^',Qt::CaseSensitive)){
                if( content.at(0) != '.')
                    temp1.append(content.at(i));
                else
                    QMessageBox::warning(this, "提示", "输入错误!", "OK");
            }
        }
        term.coef = temp1.toDouble();
        term.expn = temp2.toInt();
        insertNode(L2,term);
        this->ui->showPolyn2->setText("");
        QMessageBox::information(this, "提示", "输入成功!请输入下一项或进行其他操作", "OK");
    }
    else if(this->ui->showPolyn->text().isEmpty() || this->ui->showPolyn2->text().isEmpty()){
        QMessageBox::warning(this, "提示", "请输入内容!", "OK");
    }
}

void Widget::on_pB_l1_clicked()
{
    if(this->ui->showPolyn->text().isEmpty()){
        InitList(L1);
        QMessageBox::information(this, "提示", "第一个多项式已清空,请依次输入其每一项", "OK");
    }
    else
        QMessageBox::information(this, "提示", "请依次输入第一个多项式的每一项", "OK");
    this->ui->showPolyn->setEnabled(true);
    this->ui->showPolyn2->setEnabled(false);
    this->ui->showPolyn2->setText("");
    this->ui->Result->setEnabled(false);
    this->ui->Result->setText("");
}

void Widget::on_pB_l2_clicked()
{
    if(this->ui->showPolyn2->text().isEmpty()){
        InitList(L2);
        QMessageBox::information(this, "提示", "第二个多项式已清空,请依次输入其每一项", "OK");
    }
    else
        QMessageBox::information(this, "提示", "请依次输入第二个多项式的每一项", "OK");
    this->ui->showPolyn2->setEnabled(true);
    this->ui->showPolyn->setEnabled(false);
    this->ui->showPolyn->setText("");
    this->ui->Result->setEnabled(false);
    this->ui->Result->setText("");
}

void Widget::on_pB_compute_clicked()
{
    if(L1->next != NULL || L2->next != NULL){
        QMessageBox::information(this, "提示", "请点击运算符进行计算", "OK");
        this->ui->Result->setEnabled(true);
        this->ui->showPolyn2->setEnabled(false);
        this->ui->showPolyn2->setText("");
        this->ui->showPolyn->setEnabled(false);
        this->ui->showPolyn->setText("");
    }
    else if(L1->next == NULL && L2->next == NULL)
        QMessageBox::warning(this, "提示", "请先输入多项式!", "OK");
}

void Widget::on_pB_equals_clicked()
{
    InitList(L3);
    if(!this->ui->Result->text().isEmpty()){
        QString expression = this->ui->Result->text();
        QChar op;
        for(int i = 0; i < expression.length(); i++){
            if(i == expression.indexOf(" "))
                op = expression.at(i + 1);
        }
        if(op == '+'){
            QString string;
            addPolyn(L3,L1,L2);
            visitList(L3,string);
            this->ui->Result->insert(" = " + string);
        }
        else if(op == '-'){
            QString string;
            SubtracatPolyn(L3,L1,L2);
            visitList(L3,string);
            this->ui->Result->insert(" = " + string);
        }
        else if(op == '*'){
            QString string;
            multiplyPolyn(L3,L1,L2);
            visitList(L3,string);
            this->ui->Result->insert(" = " + string);
        }
        else if(expression.at(0) == 'd'){
            QString string;
            InitList(L3);
            if(expression.at(3) == '1')
                derivativePolyn(L3,L1);
            else
                derivativePolyn(L3,L2);
                visitList(L3,string);
            this->ui->Result->insert(" = " + string);
        }
    }
    else if(this->ui->Result->text().isEmpty()){
        QMessageBox::warning(this, "提示", "请先输入运算符!", "OK");
    }
}

void Widget::on_pB_multiply_clicked()
{
    if(!this->ui->showPolyn->isEnabled() && !this->ui->showPolyn2->isEnabled() && this->ui->Result->isEnabled()) {
        QString string1, string2;
        visitList(L1,string1);
        this->ui->Result->insert("(" + string1 + ")");
        this->ui->Result->insert(" * ");
        visitList(L2,string2);
        this->ui->Result->insert("(" + string2 + ")");
    }
}

void Widget::on_pB_Derivatives_clicked()
{
    if(!this->ui->showPolyn->isEnabled() && !this->ui->showPolyn2->isEnabled() && this->ui->Result->isEnabled()) {
        QString string1;
        visitList(L1,string1);
        this->ui->Result->insert("d(L1) = d(" + string1 + ")");
    }
}

void Widget::on_pB_Derivatives2_clicked()
{
    if(!this->ui->showPolyn->isEnabled() && !this->ui->showPolyn2->isEnabled() && this->ui->Result->isEnabled()) {
        QString string1;
        visitList(L2,string1);
        this->ui->Result->insert("d(L2) = d(" + string1 + ")");
    }
}

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
最后来个小总结:
1.在写这个的时候,算法部分来自网上(因时间紧迫),忘记出处了,如找到,我会及时注明。

2.在这个过程中,需要了解到Qt的基本机制,也就是信号和槽,以及对相关控件的的信号及其槽函数的了解。但是还好,在这个当中,用到的都是最基本的。

3.过程当中,遇到的难题就是如何将字符界面的程序,与可视化进行结合起来,相关操作的细化,需要花时间。

4.这是个十分简单的小程序,有很多功能都不完善,还有些小地方是有错误的,后面有时间会继续改善的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值