这是我第一次写博客,肯定会有诸多不足,还请见谅。同时我也是想记录下来,以便以后查询。接下来是简单的介绍:
-
这是我数据结构课程的一个小作业,要求是采用一种数据结构与实际生活相结 合,自由发挥写一个比较有用的小程序。
-
算法部分采用了单链表实现,参考了一些网上的代码。
程序结果展示
1、主界面
2、主要功能和操作方式介绍
1、操作方式介绍
-
输入:需要分为两个多项式分别输入。点击L1进行第一个多项式的输入,同理第二个多项式也是。每次只能输入一个多项式,且在输入一个多项式时一次只能输入一项,输入一项后点击input即为输入成功,期间可点击C退格。接着可继续输入第二个多项式或进行计算
-
输出:计算功能包括多项式加法(+),多项式减法(-),多项式乘法(*),多项式求导(d(L1),d(L2))。首先点击COMPUTE后输出栏可显示,点击运算符后显示相关式子,点击等于即可得出相关结果。注:运算一次后需要点击清空AC
2、功能展示
- 输入:
3. 计算:
①加法:
②减法:
③乘法:
④求导:
3、代码部分
- 头文件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
- 源文件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.这是个十分简单的小程序,有很多功能都不完善,还有些小地方是有错误的,后面有时间会继续改善的。