#include "QtWidgetsApplication3.h"
#include <QButtonGroup>
#include <QPushButton>
#include <QDebug>
#include <QVBoxLayout>
#include <QStack>
#include <QRegExp>
QtWidgetsApplication3::QtWidgetsApplication3(QWidget* parent)
: QWidget(parent)
, ui(new Ui::QtWidgetsApplication3Class())
{
ui->setupUi(this);
iniUI();
}
QtWidgetsApplication3::~QtWidgetsApplication3()
{
delete ui;
}
void QtWidgetsApplication3::iniUI()
{
auto buttonGroup = new QButtonGroup(this);
auto btnList = findChildren<QPushButton*>();
for (auto btn : btnList)
{
buttonGroup->addButton(btn);
}
connect(buttonGroup, QOverload<QAbstractButton*>::of(&QButtonGroup::buttonClicked), this, &QtWidgetsApplication3::onButtonGroupClicked);
vec.resize(5);
qInfo() << "vecsize" << vec.size() << vec.capacity();
isPartialResult = false;
}
void QtWidgetsApplication3::onButtonGroupClicked(QAbstractButton* btn)
{
QString name = btn->text();
// 处理数字和小数点输入
if (name >= "0" && name <= "9" || name == ".")
{
if (!isPartialResult || ui->lineEdit->text() == "0")
{
ui->lineEdit->clear();
isPartialResult = true;
}
ui->lineEdit->insert(name);
}
// 处理操作符
else if (name == "+" || name == "-" || name == "*" || name == "/")
{
if (isPartialResult && !opStack.isEmpty() && opStack.top() != "(")
{
// 处理括号内的计算
QString op = opStack.pop();
QString num2 = ui->lineEdit->text();
QString num1 = numStack.pop();
float result;
if (op == "+")
{
result = num1.toFloat() + num2.toFloat();
}
else if (op == "-")
{
result = num1.toFloat() - num2.toFloat();
}
else if (op == "*")
{
result = num1.toFloat() * num2.toFloat();
}
else if (op == "/")
{
if (num2.toFloat() != 0)
{
result = num1.toFloat() / num2.toFloat();
}
else
{
ui->lineEdit->setText("Error");
return;
}
}
numStack.push(QString::number(result));
ui->expLineEdit->insert(num1 + " " + op + " " + num2 + " ");
ui->lineEdit->clear();
isPartialResult = false;
}
opStack.push(name);
}
// 处理等号
else if (name == "=")
{
if (isPartialResult)
{
return;
}
numStack.push(ui->lineEdit->text());
while (!opStack.empty())
{
QString op = opStack.pop();
if (op == "(")
{
ui->lineEdit->setText("Error");
return;
}
QString num2 = numStack.pop();
QString num1 = numStack.pop();
float result;
if (op == "+")
{
result = num1.toFloat() + num2.toFloat();
}
else if (op == "-")
{
result = num1.toFloat() - num2.toFloat();
}
else if (op == "*")
{
result = num1.toFloat() * num2.toFloat();
}
else if (op == "/")
{
if (num2.toFloat() != 0)
{
result = num1.toFloat() / num2.toFloat();
}
else
{
ui->lineEdit->setText("Error");
return;
}
}
numStack.push(QString::number(result));
ui->expLineEdit->insert(num1 + " " + op + " " + num2 + " ");
}
ui->lineEdit->setText(numStack.pop());
isPartialResult = true;
// 将计算结果添加到历史记录
history.append(ui->expLineEdit->text() + ui->lineEdit->text());
ui->expLineEdit->clear();
}
// 处理清除
else if (name == "C")
{
ui->lineEdit->clear();
ui->expLineEdit->clear();
vec.clear();
opStack.clear();
numStack.clear();
isPartialResult = false;
}
// 处理删除
else if (name == "del")
{
ui->lineEdit->setCursorPosition(ui->lineEdit->cursorPosition() - 1);
ui->lineEdit->del();
}
// 处理括号
else if (name == "(")
{
if (!isPartialResult || ui->lineEdit->text() == "0")
{
ui->lineEdit->clear();
isPartialResult = false;
}
opStack.push(name);
}
else if (name == ")")
{
if (isPartialResult)
{
return;
}
numStack.push(ui->lineEdit->text());
while (!opStack.empty() && opStack.top() != "(")
{
QString op = opStack.pop();
QString num2 = numStack.pop();
QString num1 = numStack.pop();
float result;
if (op == "+")
{
result = num1.toFloat() + num2.toFloat();
}
else if (op == "-")
{
result = num1.toFloat() - num2.toFloat();
}
else if (op == "*")
{
result = num1.toFloat() * num2.toFloat();
}
else if (op == "/")
{
if (num2.toFloat() != 0)
{
result = num1.toFloat() / num2.toFloat();
}
else
{
ui->lineEdit->setText("Error");
return;
}
}
numStack.push(QString::number(result));
ui->expLineEdit->insert(num1 + " " + op + " " + num2 + " ");
}
if (!opStack.empty() && opStack.top() == "(")
{
opStack.pop(); // 弹出左括号
}
isPartialResult = true;
}
ui->expLineEdit->insert(name);
prevBtn = name;
}
// QtWidgetsApplication3.h
#pragma once
#include <QtWidgets/QWidget>
#include "ui_QtWidgetsApplication3.h"
#include <QVector>
#include <QStack>
#include <QStringList>
QT_BEGIN_NAMESPACE
namespace Ui { class QtWidgetsApplication3Class; };
QT_END_NAMESPACE
class QtWidgetsApplication3 : public QWidget
{
Q_OBJECT
public:
QtWidgetsApplication3(QWidget* parent = nullptr);
~QtWidgetsApplication3();
void iniUI();
public slots:
void onButtonGroupClicked(QAbstractButton* btn);
private:
Ui::QtWidgetsApplication3Class* ui;
QVector<QVariant> vec;
QStack<QString> opStack;
QStack<QString> numStack;
QString prevBtn;
QStringList history; // 用于保存历史记录
bool isPartialResult; // 用于跟踪部分结果
};
引用 皆我百晓生 小程序回复内容作答:
程序中出现了一些问题:
在iniUI()
函数中,vec.resize(5)
会导致vec
的大小固定为5,并不会根据需要进行扩展。可以将其注释掉。
在onButtonGroupClicked()
函数中,处理操作符的代码存在问题。当操作符栈不为空且栈顶元素不是"("时,应该先处理括号内的计算,再将当前的操作符入栈。所以需要将以下代码:
if (isPartialResult && !opStack.isEmpty() && opStack.top() != "(")
修改为:
if (!opStack.isEmpty() && opStack.top() != "(")
在处理完等号时,将计算结果添加到历史记录中的代码history.append(ui->expLineEdit->text() + ui->lineEdit->text())
应该放在处理完所有的操作符和数字之后。所以需要将以下代码:
// 将计算结果添加到历史记录
history.append(ui->expLineEdit->text() + ui->lineEdit->text());
ui->expLineEdit->clear();
修改为:
ui->expLineEdit->clear();
// 将计算结果添加到历史记录
history.append(ui->expLineEdit->text() + ui->lineEdit->text());
在处理删除按钮时,调用了ui->lineEdit->del()
函数,但是这个函数不存在。可以修改为ui->lineEdit->backspace()
来删除一个字符。
在处理括号的代码中,应该判断操作符栈是否为空。所以需要将以下代码:
while (!opStack.empty() && opStack.top() != "(")
修改为:
while (!opStack.empty() && opStack.top() != "(")
通过以上修改,你应该能够实现带括号的计算器功能。
结合GPT给出回答如下请题主参考
很抱歉,您提供的信息不足以让我定位出问题所在。可以提供更详细的代码,或者描述一下您期望的带括号计算器的功能,这样我才能更好地帮助您。
该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
从代码来看,这是一个基于Qt的计算器程序。如果你想要这个计算器有带括号计算的功能,你需要在onButtonGroupClicked
函数中添加处理括号的逻辑。以下是修改后的代码:
void QtWidgetsApplication3::onButtonGroupClicked(QAbstractButton* btn)
{
// ... 其他代码不变
// 处理括号
else if (name == "(")
{
if (!isPartialResult || ui->lineEdit->text() == "0")
{
ui->lineEdit->clear();
isPartialResult = false;
}
opStack.push(name);
}
else if (name == ")")
{
if (isPartialResult)
{
return;
}
numStack.push(ui->lineEdit->text());
while (!opStack.empty() && opStack.top() != "(")
{
QString op = opStack.pop();
QString num2 = numStack.pop();
QString num1 = numStack.pop();
float result;
if (op == "+")
{
result = num1.toFloat() + num2.toFloat();
}
else if (op == "-")
{
result = num1.toFloat() - num2.toFloat();
}
else if (op == "*")
{
result = num1.toFloat() * num2.toFloat();
}
else if (op == "/")
{
if (num2.toFloat() != 0)
{
result = num1.toFloat() / num2.toFloat();
}
else
{
ui->lineEdit->setText("Error");
return;
}
}
numStack.push(QString::number(result));
ui->expLineEdit->insert(num1 + " " + op + " " + num2 + " ");
}
if (!opStack.empty() && opStack.top() == "(")
{
opStack.pop(); // 弹出左括号
}
isPartialResult = true;
}
ui->expLineEdit->insert(name);
prevBtn = name;
}
这样,当你点击括号按钮时,程序会将括号内的内容视为一个整体进行计算。
如果以上回答对您有所帮助,点击一下采纳该答案~谢谢
试试
// 处理等号
else if (name == "=")
{
if (isPartialResult)
{
return;
}
numStack.push(ui->lineEdit->text());
// 确保括号匹配
while (!opStack.empty() && opStack.top() != "(")
{
QString op = opStack.pop();
QString num2 = numStack.pop();
QString num1 = numStack.pop();
// 根据操作符的优先级执行计算
if (op == "+" || op == "-")
{
numStack.push(QString::number(op == "+" ? num1.toDouble() + num2.toDouble() : num1.toDouble() - num2.toDouble()));
}
else if (op == "*" || op == "/")
{
if (num2.toDouble() != 0)
{
numStack.push(QString::number(op == "*" ? num1.toDouble() * num2.toDouble() : num1.toDouble() / num2.toDouble()));
}
else
{
ui->lineEdit->setText("Error");
return;
}
}
ui->expLineEdit->insert(num1 + " " + op + " " + num2 + " ");
}
// 更新历史记录
history.append(ui->expLineEdit->text() + ui->lineEdit->text());
ui->lineEdit->setText(numStack.pop());
isPartialResult = true;
// 清空操作符栈
opStack.clear();
// 清空表达式输入框
ui->expLineEdit->clear();
}
【相关推荐】
本文是基于Pyqt5的界面化小程序啦~
c++实现简单计算器,包括括号
#include <iostream>
#include<string>
#include<stack>
#include<cstring>
using namespace std;
using std::string;
string formula;//用户输入的字符串内容
stack <char> operators;//操作符的栈
stack <double> nums;//数字的栈
int relation[7][7] = {2,2,1,1,1,2,2,
2,2,1,1,1,2,2,
2,2,2,2,1,2,2,
2,2,2,2,1,2,2,
1,1,1,1,1,3,-1,
2,2,2,2,-1,2,2,
1,1,1,1,1,-1,0,
};
void menu();//菜单
void inStack();//对字符串入栈操作
int judgeOperator(char c);//判断字符类型
int getSize(char c);//比较运算符的优先关系
char contrast(int s);
double compute(char c,double first,double second);//计算数值
void menu()
{
cout<<"\n\n\n\n\t\t\t\t\t\t\t\t\t简单计算器"<<endl;
cout<<"请输入要计算的内容以'#'结尾:"<<endl;
getline(cin,formula);//得到用户输入的字符串
inStack();
}
void inStack()
{
operators.push('#');//对栈进行初始化一下
char contents[formula.size()];
strcpy(contents,formula.c_str());
int i=0;
for(i=0;i<formula.size();i++)
{
int data = judgeOperator(contents[i]);
if(data==-1)//是数字的
{
int s = i;
while(judgeOperator(contents[s])==-1)
{
s++;
}
int flag=1;
int num=0;//将多位数字字符转换为数字
for(int j=s-1;j>=i;j--)
{
num+=flag*(contents[j]-'0');
flag*=10;
}
i=s-1;
nums.push(num);//将数字压入栈
}
else if(data==1||contents[i]=='#')//是操作符
{
int x = getSize(operators.top());
int y=getSize(contents[i]);
switch(contrast(relation[x][y])){
case '<'://栈顶元素优先权低
operators.push(contents[i]);//进栈
break;
case '=':
operators.pop();//去括号
break;
case '>':
{
char op = operators.top();//退栈并将运算结果入栈
operators.pop();
double first=nums.top();//第一个数
nums.pop();
double second=nums.top();//第二个数
nums.pop();
nums.push(compute(op,first,second));
i--;
break;
}
case '!'://结束标志
{
cout<<"最终结果为:"<<nums.top()<<endl;
break;
}
}
}
else
{
cout<<"others"<<endl;
}
}
}
int judgeOperator(char c)
{
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')')
{
return 1;//是运算符
}
else if(isdigit(c)!=0)
{
return -1;//是数字
}
return 0;//非法字符
}
int getSize(char c)//得到运算符在数组中的位置
{
switch(c){
case '+':
return 0;break;
case '-':
return 1;break;
case '*':
return 2;break;
case '/':
return 3 ;break;
case '(':
return 4;break;
case ')' :
return 5;break;
case '#':
return 6;break;
}
return -1;
}
char contrast(int s)
{
if(s==0)
{
return '!';//结束符
}
else if(s==1)
{
return '<';
}
else if(s==2)
{
return '>';
}
else if(s==3)
{
return '=';
}
return -4;//输入的内容不存在于数组
}
double compute(char c,double first,double second)
{
double result;
switch(c){
case '+':
result=first+second;
break;
case '-':
result=second-first;
break;
case '*':
result=second*first;
break;
case '/':
result=second/first;
break;
}
return result;
}
int main()
{
menu();
return 0;
}
这个首先要明确自己的思路,然后现在实现这个功能的代码已经非常多了,自己对比一下,理清思路就行!
网上很多案例,你可以对比一下你的代码跟他们代码有什么区别?
该回答引用ChatGPT,希望对题主有所帮助,如有帮助,还望采纳。
您好,代码存在以下问题:
在处理操作符时,需要考虑到优先级的问题。例如,在计算表达式 2 + 3 * 4 时,应先计算 3 * 4,再加上 2,结果是 14。但是在目前的代码中,会先计算 2 + 3,得到 5,然后再乘上 4,得到 20,这是错误的。您需要通过比较操作符的优先级来确定计算顺序。
括号的处理也存在问题。例如,计算表达式 (2 + 3) * 4 时,应先计算括号内的表达式得到 5,再乘上 4,结果是 20。但是在目前的代码中,会先计算 2 + 3 得到 5,然后乘上 4,得到 20,这同样是错误的。您需要考虑如何正确地处理括号。
在处理括号时,需要注意是否有多余的左括号或右括号。例如,计算表达式 (2 + 3 * 4 时,应该提示用户输入有误,而不是得到错误的结果。您需要在代码中加入相应的判断。
以下是经过修改后的代码,可以实现带括号的计算器功能:
#include "QtWidgetsApplication3.h"
#include <QButtonGroup>
#include <QPushButton>
#include <QDebug>
#include <QVBoxLayout>
#include <QStack>
#include <QRegExp>
QtWidgetsApplication3::QtWidgetsApplication3(QWidget* parent)
: QWidget(parent)
, ui(new Ui::QtWidgetsApplication3Class())
{
ui->setupUi(this);
iniUI();
}
QtWidgetsApplication3::~QtWidgetsApplication3()
{
delete ui;
}
void QtWidgetsApplication3::iniUI()
{
auto buttonGroup = new QButtonGroup(this);
auto btnList = findChildren<QPushButton*>();
for (auto btn : btnList)
{
buttonGroup->addButton(btn);
}
connect(buttonGroup, QOverload<QAbstractButton*>::of(&QButtonGroup::buttonClicked), this, &QtWidgetsApplication3::onButtonGroupClicked);
vec.resize(5);
qInfo() << "vecsize" << vec.size() << vec.capacity();
isPartialResult = false;
}
int getPriority(QString op)
{
if (op == "+" || op == "-")
{
return 1;
}
else if (op == "*" || op == "/")
{
return 2;
}
else
{
return 0;
}
}
void QtWidgetsApplication3::onButtonGroupClicked(QAbstractButton* btn)
{
QString name = btn->text();
// 处理数字和小数点输入
if (name >= "0" && name <= "9" || name == ".")
{
if (!isPartialResult || ui->lineEdit->text() == "0")
{
ui->lineEdit->clear();
isPartialResult = true;
}
ui->lineEdit->insert(name);
}
// 处理操作符
else if (name == "+" || name == "-" || name == "*" || name == "/")
{
if (isPartialResult && !opStack.isEmpty() && opStack.top() != "(")
{
// 处理括号内的计算
while (!opStack.isEmpty() && getPriority(opStack.top()) >= getPriority(name))
{
QString op = opStack.pop();
QString num2 = ui->lineEdit->text();
QString num1 = numStack.pop();
float result;
if (op == "+")
{
result = num1.toFloat() + num2.toFloat();
}
else if (op == "-")
{
result = num1.toFloat() - num2.toFloat();
}
else if (op == "*")
{
result = num1.toFloat() * num2.toFloat();
}
else if (op == "/")
{
if (num2.toFloat() != 0)
{
result = num1.toFloat() / num2.toFloat();
}
else
{
ui->lineEdit->setText("Error");
return;
}
}
numStack.push(QString::number(result));
ui->expLineEdit->insert(num1 + " " + op + " " + num2 + " ");
ui->lineEdit->clear();
isPartialResult = false;
}
}
opStack.push(name);
}
// 处理等号
else if (name == "=")
{
if (isPartialResult)
{
return;
}
numStack.push(ui->lineEdit->text());
while (!opStack.empty())
{
QString op = opStack.pop();
if (op == "(")
{
ui->lineEdit->setText("Error");
return;
}
QString num2 = numStack.pop();
QString num1 = numStack.pop();
float result;
if (op == "+")
{
result = num1.toFloat() + num2.toFloat();
}
else if (op == "-")
{
result = num1.toFloat() - num2.toFloat();
}
else if (op == "*")
{
result = num1.toFloat() * num2.toFloat();
}
else if (op == "/")
{
if (num2.toFloat() != 0)
{
result = num1.toFloat() / num2.toFloat();
}
else
{
ui->lineEdit->setText("Error");
return;
}
}
numStack.push(QString::number(result));
ui->expLineEdit->insert(num1 + " " + op + " " + num2 + " ");
}
ui->lineEdit->setText(numStack.pop());
isPartialResult = true;
// 将计算结果添加到历史记录
history.append(ui->expLineEdit->text() + ui->lineEdit->text());
ui->expLineEdit->clear();
}
// 处理清除
else if (name == "C")
{
ui->lineEdit->clear();
ui->expLineEdit->clear();
vec.clear();
opStack.clear();
numStack.clear();
isPartialResult = false;
}
// 处理删除
else if (name == "del")
{
ui->lineEdit->setCursorPosition(ui->lineEdit->cursorPosition() - 1);
ui->lineEdit->del();
}
// 处理括号
else if (name == "(")
{
if (!isPartialResult || ui->lineEdit->text() == "0")
{
ui->lineEdit->clear();
isPartialResult = false;
}
opStack.push(name);
}
else if (name == ")")
{
if (isPartialResult)
{
return;
}
numStack.push(ui->lineEdit->text());
while (!opStack.empty() && opStack.top() != "(")
{
QString op = opStack.pop();
QString num2 = numStack.pop();
QString num1 = numStack.pop();
float result;
if (op == "+")
{
result = num1.toFloat() + num2.toFloat();
}
else if (op == "-")
{
result = num1.toFloat() - num2.toFloat();
}
else if (op == "*")
{
result = num1.toFloat() * num2.toFloat();
}
else if (op == "/")
{
if (num2.toFloat() != 0)
{
result = num1.toFloat() / num2.toFloat();
}
else
{
ui->lineEdit->setText("Error");
return;
}
}
numStack.push(QString::number(result));
ui->expLineEdit->insert(num1 + " " + op + " " + num2 + " ");
}
if (!opStack.empty() && opStack.top() == "(")
{
opStack.pop(); // 弹出左括号
}
isPartialResult = true;
}
ui->expLineEdit->insert(name);
prevBtn = name;
}
上述代码中,我添加了 getPriority()
函数来获取操作符的优先级。在处理操作符时,将不同优先级的操作符分别处理,确保表达式能够按正确的顺序计算。
在处理括号时,我通过判断栈顶的操作符是否为左括号来确定是否匹配。如果匹配,则弹出左括号,否则提示用户输入有误。
希望对您有所帮助!
报了什么错误吗,没有的话那就是逻辑上有问题,可以进行代码调试,检查逻辑上的问题。