求一个可以计算加减乘除的程序(可以计算括号),要原创
求一个可以计算加减乘除的程序(可以计算括号),要原创
有GPT你不用?
#include <iostream>
#include <stack>
#include <string>
using namespace std;
int priority(char c) {
if (c == '+' || c == '-') return 1;
if (c == '*' || c == '/') return 2;
return 0;
}
double calculate(double a, double b, char op) {
switch (op) {
case '+': return a + b;
case '-': return a - b;
case '*': return a * b;
case '/': return a / b;
}
return 0;
}
double evaluate(string expression) {
stack<double> values;
stack<char> operators;
for (int i = 0; i < expression.length(); i++) {
if (expression[i] == ' ') continue;
if (isdigit(expression[i])) {
double value = 0;
while (i < expression.length() && isdigit(expression[i])) {
value = value * 10 + (expression[i] - '0');
i++;
}
values.push(value);
i--;
} else if (expression[i] == '(') {
operators.push(expression[i]);
} else if (expression[i] == ')') {
while (!operators.empty() && operators.top() != '(') {
double val2 = values.top();
values.pop();
double val1 = values.top();
values.pop();
char op = operators.top();
operators.pop();
values.push(calculate(val1, val2, op));
}
if (!operators.empty()) operators.pop();
} else {
while (!operators.empty() && priority(operators.top()) >= priority(expression[i])) {
double val2 = values.top();
values.pop();
double val1 = values.top();
values.pop();
char op = operators.top();
operators.pop();
values.push(calculate(val1, val2, op));
}
operators.push(expression[i]);
}
}
while (!operators.empty()) {
double val2 = values.top();
values.pop();
double val1 = values.top();
values.pop();
char op = operators.top();
operators.pop();
values.push(calculate(val1, val2, op));
}
return values.top();
}
int main() {
string expression;
cout << "请输入表达式:";
getline(cin, expression);
cout << "结果为:" << evaluate(expression) << endl;
return 0;
}
请参考!
支持括号和加减乘除计算(整数计算遵守C运算规则,比如3/2的结果是1,而不是1.5,如果需要按照实际运算,把代码中的int类型改成double类型即可),运行结果:
代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#define M 100
typedef enum {
OK = 1,
ERROR = 0
}Status;
typedef enum {
TRUE = 1,
FALSE = 0
}Bool;
//数据
typedef struct _datatype
{
int dt;
char dc;
}Datatype;
//链栈结构
typedef struct _stacknode {
Datatype data;
struct _stacknode* next;
}Stack;
Stack* Stack_init(Stack* pStack)
{
pStack = (Stack*)malloc(sizeof(Stack));
pStack->next = 0;
return pStack;
}
void Stack_Free(Stack* pStack)
{
Stack* p;
while (pStack)
{
p = pStack->next;
free(pStack);
pStack = p;
}
}
Bool Stack_IsEmpty(Stack* pStack)
{
if (pStack == 0 || pStack->next == 0)
return TRUE;
else
return FALSE;
}
Status Stack_GetTop(Stack* pStack, int f, int* d, char* c)
{
Stack* p = 0;
if (pStack == 0 || pStack->next == 0)
return ERROR;
p = pStack;
while (p->next)
{
p = p->next;
}
if (f == 0)
*d = p->data.dt;
else
*c = p->data.dc;
return OK;
}
Status Stack_Push(Stack* pStack, int d = 0, char c = 0)
{
Stack* p, * t;
t = (Stack*)malloc(sizeof(Stack));
t->next = 0;
if (c == 0)
t->data.dt = d;
else
t->data.dc = c;
if (pStack == 0)
{
pStack = t;
}
else
{
p = pStack;
while (p->next)
p = p->next;
p->next = t;
}
return OK;
}
//f=0表示int类型,其他值表示char
Status Stack_Pop(Stack* pStack)
{
Stack* p, * t;
if (pStack == 0 || pStack->next == 0)
return ERROR;
p = pStack;
t = p->next;
while (t->next)
{
p = p->next;
t = t->next;
}
p->next = 0;
free(t);
return OK;
}
/*功能:判断运算符的类型并分级
*参数:x是运算符的符号
*返回:字符所代表的级数
*/
int Judge(char x)
{
if (x == '(') {
return 4;
}
else if (x == '+' || x == '-') {
return 1;
}
else if (x == '*' || x == '/') {
return 2;
}
else if (x == '^') {
return 3;
}
else if (x == ')') {
return 0;
}
}
/*功能:执行计算
*参数:x1是第一个数字
x2是第二个数字
s是运算符
*返回:返回运算结果
*/
int Culculate(int x1, int x2, char s)
{
int result = 0;
switch (s) {
case '+': {
result = x1 + x2;
break;
}
case '-': {
result = x1 - x2;
break;
}
case '*': {
result = x1 * x2;
break;
}
case '/': {
result = x1 / x2;
break;
}
case '^': {
result = pow((double)x1, x2);
break;
}
}
return result;
}
/*功能:判断左右括号是否匹配
*参数:left是左括号,right是右括号
*返回:若左右括号匹配返回OK,否则返回ERROR
*/
Status Check(char left, char right)
{
if (left == '(' && right == ')')
{
return OK;
}
else
{
return ERROR;
}
}
/*功能:判断字符是运算符
*参数:c是字符
*返回:若c为运算符返回OK;否则返回ERROR
*/
Status CharIsSymbol(char c)
{
if (c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')' || c == '^')
{
return OK;
}
else
{
return ERROR;
}
}
/*功能:判断字符是数字
*参数:d是字符
*返回:若d是数字返回OK;否则返回ERROR
*/
Status CharIsNum(char d)
{
if (d >= '0' && d <= '9') {
return OK;
}
else
{
return ERROR;
}
}
/*功能:执行一行字符的计算
*参数:s[]是这一行字符串
*返回:返回运算结果
*/
int DoSingleOperation(char s[])
{
Stack* pIntStack = 0;/*这个栈存放数字*/
Stack* pSymbolStack = 0;/*这个栈存放除括号外的符号*/
Stack* pSymbolStack_2 = 0;/*这个栈存放括号*/
Status sta;
pIntStack = Stack_init(pIntStack);
pSymbolStack = Stack_init(pSymbolStack);
pSymbolStack_2 = Stack_init(pSymbolStack_2);
int len, n;
len = strlen(s);
s[len] = '#';
len++;
int i;
int a, b, c = 0, d = 0;
int topele_int;
char topele_c;
char x[M];
for (i = 0; i < len; i++)
{
if (s[i] == '(')
{
Stack_Push(pSymbolStack_2, 0, s[i]);
}
else if (s[i] == ')')
{
Stack_GetTop(pSymbolStack_2, 1, &topele_int, &topele_c);
if (Check(topele_c, s[i]) == 1)
{
Stack_Pop(pSymbolStack_2);
}
else
{
printf("括号不匹配"); /*判断括号是否匹配*/
return 0;
}
}
}
i = 0;
if (s[0] == '+' || s[0] == '-' || s[0] == '*' || s[0] == '/' || s[0] == '^')
{
printf("运算符不能在开头"); /*除括号外的运算符不能在字符串开始处*/
return 0;
}
while (s[i] != '#')
{
int x = 0;
if (CharIsNum(s[i]) == OK)
{
while (s[i] >= '0' && s[i] <= '9')
{
x *= 10;
x += s[i++] - '0';
}
Stack_Push(pIntStack, x);
continue;
}
else
{
char theta = s[i];
while (Stack_IsEmpty(pSymbolStack) == 0)
{
Stack_GetTop(pSymbolStack, 1, 0, &topele_c);
if (topele_c == '(' || Judge(topele_c) < Judge(s[i]))
break;
Stack_GetTop(pIntStack, 0, &a, 0);
Stack_Pop(pIntStack);
Stack_GetTop(pIntStack, 0, &b, 0);
Stack_Pop(pIntStack);
if (a == 0 && topele_c == '/') { //Stack_GetTop(pSymbolStack)
printf("除数不能为0\n"); /*判断除数是否为0,若为0则结束程序,否则继续运行*/
return 0;
}
c = Culculate(b, a, topele_c);//Stack_GetTop(pSymbolStack)
Stack_Push(pIntStack, c);
Stack_Pop(pSymbolStack);
}
sta = Stack_GetTop(pSymbolStack, 1, 0, &topele_c);
if (sta == OK && Judge(theta) == 0 && Judge(topele_c) == 4) {
Stack_Pop(pSymbolStack);
}
if (Judge(theta) != 0) {
Stack_Push(pSymbolStack, 0, theta);
}
i++;
}
}
while (Stack_IsEmpty(pSymbolStack) == 0)
{
Stack_GetTop(pSymbolStack, 1, 0, &topele_c);
Stack_GetTop(pIntStack, 0, &a, 0);
Stack_Pop(pIntStack);
Stack_GetTop(pIntStack, 0, &b, 0);
Stack_Pop(pIntStack);
if (a == 0 && topele_c == '/') {
printf("除数不能为0\n"); /*判断除数是否为0,若为0则结束程序,否则继续运行*/
return 0;
}
c = Culculate(b, a, topele_c);//Stack_GetTop(pSymbolStack)
Stack_Push(pIntStack, c);
Stack_Pop(pSymbolStack);
}
Stack_GetTop(pIntStack, 0, &a, 0);
//printf("%d\n", a);
return a;
}
int main()
{
char all[100] = { 0 };
int result = 0;
scanf("%s", all);
result = DoSingleOperation(all);
printf("%d\n", result);
return 0;
}
参考GPT:以下是一个可以计算加减乘除并且支持括号的C++程序。
#include <iostream>
#include <stack>
#include <vector>
using namespace std;
int priority(char c) {
if (c == '+' || c == '-') {
return 1;
} else if (c == '*' || c == '/') {
return 2;
} else {
return 0;
}
}
double calculate(double a, double b, char op) {
switch (op) {
case '+': return a + b;
case '-': return a - b;
case '*': return a * b;
case '/': return a / b;
default: return 0;
}
}
double evaluate(vector<string> expr) {
stack<double> nums;
stack<char> ops;
for (string token : expr) {
if (isdigit(token[0])) {
nums.push(stod(token));
} else if (token == "(") {
ops.push('(');
} else if (token == ")") {
while (ops.top() != '(') {
char op = ops.top();
ops.pop();
double b = nums.top();
nums.pop();
double a = nums.top();
nums.pop();
double result = calculate(a, b, op);
nums.push(result);
}
ops.pop(); // pop the left parenthesis
} else {
while (!ops.empty() && priority(ops.top()) >= priority(token[0])) {
char op = ops.top();
ops.pop();
double b = nums.top();
nums.pop();
double a = nums.top();
nums.pop();
double result = calculate(a, b, op);
nums.push(result);
}
ops.push(token[0]);
}
}
while (!ops.empty()) {
char op = ops.top();
ops.pop();
double b = nums.top();
nums.pop();
double a = nums.top();
nums.pop();
double result = calculate(a, b, op);
nums.push(result);
}
return nums.top();
}
vector<string> tokenize(string expr) {
vector<string> tokens;
string num = "";
for (char c : expr) {
if (isdigit(c) || c == '.') {
num += c;
} else {
if (!num.empty()) {
tokens.push_back(num);
num = "";
}
if (c != ' ') {
tokens.push_back(string(1, c));
}
}
}
if (!num.empty()) {
tokens.push_back(num);
}
return tokens;
}
int main() {
string expr;
cout << "Enter an expression: ";
getline(cin, expr);
vector<string> tokens = tokenize(expr);
double result = evaluate(tokens);
cout << "Result: " << result << endl;
return 0;
}
这个程序使用栈来实现算法。首先,将中缀表达式转换为后缀表达式。然后,使用栈来计算后缀表达式的值。在转换过程中,程序会处理带有括号的表达式,以确保正确的运算顺序。
可以先转化成后缀表达式,然后对后缀表达式求值
这个是整数运算
#include<stdio.h>
#include<string.h>
//返回与第一个左括号配对的右括号的地址
char * BracketMatch(const char * str) {
int count = 1; //未配对的左括号个数
str = strchr(str, '(');
if (str) {
//如果找到左括号,寻找配对的右括号,当未配对括号个数为0时,就找到了配对的右括号
while (count && *str++) {
if (*str == '(')count++;
else if (*str == ')')count--;
}
if (count) //没有配对的右括号
return NULL;
else
return (char*)str; //如果是c++程序,这一句改成“return const_cast<char*>str;”
} else {
//没有左括号
return NULL;
}
}
//将left和right确定的一段字符的指定运算符移到右边,不处理括号里的内容,仅交换位置,不改变字符串。
//这段字符需要经过预处理,否则会出错。signs必须是同级的,且从高到低调用
//lsigns指向优先级不高于sign的运算符,如果有需要,改一下逻辑,用空格作为分隔,可以不用这个参数
void cv(char *left, char *right, const char * signs, const char *lsigns) {
char *i, *j, t;
//i遍历这段字符
for (i = left; i != right; i++) {
if (*i == '(') {
//如果*i是左括号,则找到配对的右括号,并将括号以及括号里的内容复制到dest里
j = BracketMatch(i);
if (!j)return; //表达式有误,括号不成对
while (i != j)*left++ = *i++;
*left++ = *i; //括号也复制
} else if (strchr(signs, *i)) {
//如果*i是指定的运算符,则将运算符后面的,直至下一个运算符(跳过括号)或结束为止的部分复制(忽略左边的空格),再将运算符放在最后(加一个空格)
t = *i;
for (i = i + 2; i != right && !strchr(lsigns, *i); i++) {
if (*i == '(') {
j = BracketMatch(i);
if (!j)return; //表达式有误,括号不成对
while (i != j)*left++ = *i++;
}
*left++ = *i;
}
if (i == right) {
*left++ = ' ';
*left++ = t;
} else {
*left++ = t;
*left++ = ' ';
}
i--;
} else {
//不是括号也不是运算符,直接复制
*left++ = *i;
}
}
}
//预处理,运算符前后加空格
void expressionPreTreatment(char * str, const char*operators) {
//删'$',r移到str右端
char *l, *r;
r = str + strlen(str);
char temp[(r - str) * 2], *t = temp; //2倍一般够了
//遍历,找到运算符就加空格(如果已经有空格就不加了)
for (l = str; l != r; l++) {
if (strchr(operators, *l)) {
if (l[-1] != ' ')*t++ = ' ';
*t++ = *l;
if (l[1] != ' ')*t++ = ' ';
} else {
*t++ = *l;
}
}
*t = '\0';
strcpy(str, temp);
}
//中缀表达式转后缀表达式
void Convert(char *expression){
char *l, *r;//l和r分别指向表达式或子表达式(括号里的内容视为子表达式)的左右两端
expressionPreTreatment(expression, "+-*/");
l = expression;
r = l + strlen(l);
while (1) {
cv(l, r, "*/", "+-*/");
cv(l, r, "+-", "+-");
l = strchr(l, '(');
if (l) {
r = BracketMatch(l);
l++;
} else {
break;
}
}
//去掉括号
for (l = r = expression; *r; r++) {
if (*r != '(' && *r != ')')*l++ = *r;
}
*l = '\0';
}
int figure(int a,int b,char oper){
switch (oper) {
case '+':
return a+b;
case '-':
return a-b;
case '*':
return a*b;
case '/':
return a/b;
}
return 0;
}
int main(){
char expression[1000],*p;
int a[100],n,flag,t;
gets(expression);
Convert(expression);
n=t=flag=0;
for(p=expression;*p;p++){
if(*p>='0'&&*p<='9'){
flag=1;
t*=10;
t+=*p-'0';
}else{
if(flag)
a[n++]=t,t=0,flag=0;
if(strchr("+-*/",*p)){
n-=2;
a[n]=figure(a[n],a[n+1],*p);
n++;
}
}
}
printf("%d",a[0]);
return 0;
}
具体实现如下:
#include <iostream>
#include <stack>
#include <string>
using namespace std;
// 计算表达式中的一段(不包含括号)
int calculate(string::const_iterator & begin, string::const_iterator end)
{
stack<int> num_stack; // 存放数字的栈
stack<char> op_stack; // 存放运算符的栈
// 遍历表达式
while (begin != end)
{
char ch = *begin;
if (ch == ' ') // 空格直接跳过
{
begin++;
continue;
}
else if (isdigit(ch)) // 数字直接入栈
{
int num = 0;
while (begin != end && isdigit(*begin))
{
num = num * 10 + (*begin - '0');
begin++;
}
num_stack.push(num);
}
else if (ch == '(') // 左括号递归计算
{
begin++;
int num = calculate(begin, end);
num_stack.push(num);
}
else if (ch == '+' || ch == '-')
{
// 处理前面的表达式
while (!op_stack.empty() && op_stack.top() != '(')
{
int b = num_stack.top();
num_stack.pop();
int a = num_stack.top();
num_stack.pop();
char op = op_stack.top();
op_stack.pop();
if (op == '+')
num_stack.push(a + b);
else
num_stack.push(a - b);
}
// 当前操作符入栈
op_stack.push(ch);
begin++;
}
else if (ch == '*' || ch == '/')
{
// 处理前面的表达式,但不处理加减法
while (!op_stack.empty() && op_stack.top() != '(' && (op_stack.top() == '*' || op_stack.top() == '/'))
{
int b = num_stack.top();
num_stack.pop();
int a = num_stack.top();
num_stack.pop();
char op = op_stack.top();
op_stack.pop();
if (op == '*')
num_stack.push(a * b);
else
num_stack.push(a / b);
}
// 当前操作符入栈
op_stack.push(ch);
begin++;
}
else if (ch == ')')
{
// 处理前面的表达式
while (!op_stack.empty() && op_stack.top() != '(')
{
int b = num_stack.top();
num_stack.pop();
int a = num_stack.top();
num_stack.pop();
char op = op_stack.top();
op_stack.pop();
if (op == '+')
num_stack.push(a + b);
else if (op == '-')
num_stack.push(a - b);
else if (op == '*')
num_stack.push(a * b);
else if (op == '/')
num_stack.push(a / b);
}
if (!op_stack.empty() && op_stack.top() == '(')
op_stack.pop();
begin++;
}
else
{
// 非法字符
throw runtime_error("Invalid character.");
}
}
// 处理栈中剩余的表达式
while (!op_stack.empty())
{
int b = num_stack.top();
num_stack.pop();
int a = num_stack.top();
num_stack.pop();
char op = op_stack.top();
op_stack.pop();
if (op == '+')
num_stack.push(a + b);
else if (op == '-')
num_stack.push(a - b);
else if (op == '*')
num_stack.push(a * b);
else if (op == '/')
num_stack.push(a / b);
}
return num_stack.top();
}
int main()
{
string expr;
cout << "请输入表达式:" << endl;
getline(cin, expr);
try
{
auto begin = expr.begin();
int result = calculate(begin, expr.end());
cout << "计算结果为:" << result << endl;
} catch (exception & e)
{
cerr << "ERROR: " << e.what() << endl;
}
return 0;
}
这个程序可以递归地
支持原创,加油
最简单的是:
expression = input('请输入算式:')
result = eval(expression)
print('结果为:', result)
使用eval()方法将字符串转代码运行应该可行,
不行就得把字符串按照正则拆开了
参考GPT和自己的思路:
这是一个非常有趣的问题!为了实现一个可以计算加减乘除的程序,我们需要使用算法来解决。以下是一个可能的方法:
首先,我们需要将输入的字符串转换为一个可以理解的数据结构,例如用树来表达表达式。我们可以使用递归下降方法来实现这一步,例如使用分治算法来逐步将表达式分解为子问题。在这个过程中,我们会识别操作符和操作数,并将它们组合成一个树结构。
接下来,我们需要计算这个表达式。对于树中的每个节点,我们将其操作符对应的操作数进行计算,并将计算结果保存在该节点。这将最终导致根节点的值就是整个表达式的结果。
如果我们需要处理带有括号的表达式,我们可以使用递归的方法来实现。当我们在解析表达式时,如果遇到一个左括号,则我们需要递归地处理该括号内的所有操作,并将结果返回给父节点。这将导致该子表达式的根节点值更新为其计算结果。
使用这个方法,我们就可以实现一个可以计算加减乘除的程序(可以计算括号)。当然,我们还需要处理很多特殊情况,例如处理运算符优先级、处理除数为零等错误,但总的来说,这是一个节约时间且较为高效的算法。