支持多位数,括号,四则运算,的计算器算法c++实现

#include<iostream>

#include<string>

#include<stack>

#include<stdio.h>

using namespace std;

//23+(34*45)/(5+6+7)

//2+3*5+6+7

int priority(char c)

{

if (c == ')')

{

return 4;

}

else if (c == '^')

{

return 3;

}

else if (c == '*' || c == '/' || c == '%')

{

return 2;

}

else if (c == '+' || c == '-')

{

return 1;

}

else if (c == '(')

{

return 0;

}

else

{

cout << "不符合要求的字符!" << endl;

return -1;

}

} //返回字符c的优先级

bool isNumber(char c)

{

if (c >= '0'&& c <= '9')

{

return true;

}

else

{

return false;

}

}

bool isOperator(char c)

{

if (c == '+' || c == '-' || c == '*' || c == '/' || c == '%')

{

return true;

}

else

{

return false;

}

}

bool isBracket(char c)

{

if (c == '(' || c == ')')

{

return true;

}

else

{

return false;

}

}

double charToDouble(char c)

{

return (double)(c - '0');

}

double stringToDouble(string s)

{

return atof(s.c_str());

}

int stringToInt(string s)

{

return atoi(s.c_str());

}

char doubleToChar(double d)

{

return (char)(d + 48);

}

string doubleToString(double d)

{

return to_string(d);

}

double charBasicCalculate(char left, char op, char right)

{

if (isNumber(left) && isNumber(right))

{

if (op == '+')

{

return (charToDouble(left) + charToDouble(right));

}

else if (op == '-')

{

return (charToDouble(left) - charToDouble(right));

}

else if (op == '*')

{

return (charToDouble(left) * charToDouble(right));

}

else if (op == '/')

{

return (charToDouble(left) / charToDouble(right));

}

else if (op == '%')

{

return (left - '0') % (right - '0');

}

else

{

cout << "操作符错误!";

return -1;

}

}

else

{

cout << "错误运算参数";

return -1;

}

}//返回double 的基本计算函数

double doubleBasicCalculate(double left, char op, double right)

{

if (op == '+')

{

return left + right;

}

else if (op == '-')

{

return left - right;

}

else if (op == '*')

{

return left*right;

}

else if (op == '/')

{

return left / right;

}

else if (op == '%')

{

return (int)left % (int)right;

}

else

{

cout << "操作符错误!";

return -1;

}

}

double stringBasicCalculate(string left, char op, string right)

{

if (op == '+')

{

return (stringToDouble(left) + stringToDouble(right));

}

else if (op == '-')

{

return (stringToDouble(left) - stringToDouble(right));

}

else if (op == '*')

{

return (stringToDouble(left) * stringToDouble(right));

}

else if (op == '/')

{

return (stringToDouble(left) / stringToDouble(right));

}

else if (op == '%')

{

return (stringToInt(left)) % (stringToInt(right));

}

else

{

cout << "操作符错误!";

return -1;

}

}

bool isExpression(const char* expression)//判断表达式是否合法

{

int i = 0;

int leftBracket=0;//记录左括号个数

int rightBracket=0;//记录右括号个数

while (expression[i] != '\0')

{

if (expression[i] == ' ')

{

cout << "不要输入空格!";

return false;

}

if (i == 0 && !(isNumber(expression[i]) || isBracket(expression[i])))//第一个元素不是数字或者左括号

{

cout << "异常1";

return false;

}

if (!(isNumber(expression[i]) || isOperator(expression[i]) || isBracket(expression[i])))//其它符合要求的字符

{

cout << "异常2";

return false;

}

if (i != 0 && isOperator(expression[i - 1]) && (isOperator(expression[i]) || expression[i] == ')'))//操作符后还是操作符或右括号不合法

{

cout << "异常3";

return false;

}

if (i!=0 && expression[i-1] == '(' && !isNumber(expression[i]))//左括号右边不是数字debug2(i-1误写i)

{

cout << "异常4";

return false;

}

else

{

if (expression[i] == '(')

leftBracket++;

if (expression[i] == ')')

rightBracket++;

}

i++;//debug1添加上i++;

}

if (leftBracket == rightBracket)

{

return true;//表达式合理

}

else

{

cout << "异常5";

return false;

}

}

string dealBasicChar(char c, int n)//c表示位上的字符,n表示位级别,234,中c=2时n=2,c=3时,n=1,c=4时,n=0每个字符拆成0-9内

{

string temp;

temp.append(1,c);

for (int i = 0; i < n; i++)

{

temp.append("*(9+1)");

}

/*cout << "dealBasicChar" << temp << endl;*/

return temp;

}

string dealBasicString(string s)

{

string temp;

temp.append("(");

int size = s.size();

for (int i = 0;i

{

temp.append(dealBasicChar(s.at(i), size - i - 1));

if (i != size - 1)//不是最后,添加"+";

{

temp.append("+");

}

}

temp.append(")");

/*cout << "dealBasciString" << temp << endl;*/

return temp;

}

string dealExpression(const char* expression)//化为0-9以内的表达式:23+12:(9+1+9+1+3)+(9+1+2)

{

string temp = expression;

string temp2;

string texpression;

int i=0;

while(i

{

if (i!=temp.size()-1 && isNumber(temp.at(i)) && isNumber(temp.at(i+1)))//探测是否是多位数//debug当i=temp.size()-1时调用temp.at(i+1)发生越界,加上条件,i!=temp.size()-1,当i=temp.size()-1时由&&的处理原则,前面不成立不会执行后面条件.

{

/*cout << i<

int j;

for ( j = 0; isNumber(temp.at(i + j)); j++)

{

temp2.append(1,temp.at(i+j));//获得多位数存储在temp2中

}

texpression.append(dealBasicString(temp2));//转化为标准表达式并加入texpression中。

temp2.clear();//debug1:temp2为归零导致错误.

/*cout << texpression << endl;*/

i = i + j ;

}

else

{

texpression.append(1,temp.at(i));

i++;

}

}

/*cout << texpression<

return texpression;

}

double infixCalculate(const char* expression)//直接计算中缀表达式debug1括号括号优先级设置出错 OK

{

stack opStack;

stack nuStack;

for (int i = 0; expression[i] != '\0'; i++)

{

if (isNumber(expression[i]))

{

cout << "isNumber" << endl;

nuStack.push(string(1,expression[i]));//转化为string

}

else if (isOperator(expression[i]))

{

cout << "isOperator" << endl;

if (opStack.empty())//栈为空直接将操作符压入

{

cout << "empty()" << endl;

opStack.push(expression[i]);

}

else//区分优先级

{

cout << "not empty()" << endl;

if (priority(opStack.top()) < priority(expression[i]))

{

cout << "priority" << endl;

opStack.push(expression[i]);

}

else

{

cout << "not priority" << endl;

char op=opStack.top();//stack.top返回顶端元素不删除,stack.pop无返回值只删除顶端元素

opStack.pop();

string left = nuStack.top();

nuStack.pop();

string right = nuStack.top();

nuStack.pop();

nuStack.push(doubleToString(stringBasicCalculate(left, op, right)));

opStack.push(expression[i]);

}

}

}

else if (expression[i] == '(')

{

cout << "左括号" << endl;

opStack.push(expression[i]);

}

else if (expression[i] == ')')

{

cout << "右括号" << endl;

while (1)

{

if (opStack.top() == '(')

{

opStack.pop();//弹出左括号结束

break;

}

else

{

char op = opStack.top();

opStack.pop();

string left = nuStack.top();

nuStack.pop();

string right = nuStack.top();

nuStack.pop();

nuStack.push(doubleToString(stringBasicCalculate(left, op, right)));

}

}

}

else

{

cout << "符号错误!" << endl;

}

}

while (1)//计算剩余操作符

{

if (opStack.empty())

{

break;

}

else

{

char op = opStack.top();

opStack.pop();

string left = nuStack.top();

nuStack.pop();

string right = nuStack.top();

nuStack.pop();

nuStack.push(doubleToString(stringBasicCalculate(left, op, right)));

}

}

return stringToDouble(nuStack.top());

}

double postfixCalculate(const char* expression)

{

stack nuStack;

for (int i = 0; expression[i] != '\0'; i++)

{

if (isNumber(expression[i]))

{

nuStack.push(string(1, expression[i]));

}

else if (isOperator(expression[i]))

{

char op = expression[i];

string left = nuStack.top();

nuStack.pop();

string right = nuStack.top();

nuStack.pop();

nuStack.push(doubleToString(stringBasicCalculate(left, op, right)));

}

else

{

cout << "符号错误!" << endl;

}

}

return stringToDouble(nuStack.top());

}

string infixTranPostfix(const char* expressionIn)

{

stack opStack;

string temp;

for (int i = 0; expressionIn[i] != '\0'; i++)

{

if (isNumber(expressionIn[i]))

{

temp.append(1, expressionIn[i]);

}

else if (isOperator(expressionIn[i]))

{

if (opStack.empty())

{

opStack.push(expressionIn[i]);

}

else

{

if (priority(opStack.top()) < priority(expressionIn[i]))

{

opStack.push(expressionIn[i]);

}

else

{

temp.append(1, opStack.top());

opStack.pop();

opStack.push(expressionIn[i]);

}

}

}

else if (expressionIn[i] == '(')

{

opStack.push(expressionIn[i]);

}

else if (expressionIn[i] == ')')

{

while (1)

{

if (opStack.top() == '(')

{

opStack.pop();

break;

}

else

{

temp.append(1, opStack.top());

opStack.pop();

}

}

}

else

{

cout << "符号错误!";

}

}

while (1)

{

if (opStack.empty())

{

break;

}

else

{

temp.append(1, opStack.top());

opStack.pop();

}

}

return temp;

}

double calculate1(const char* expression)

{

if (isExpression(expression))

{

string tExpression = dealExpression(expression);

string ttExpression = infixTranPostfix(tExpression.c_str());

return postfixCalculate(ttExpression.c_str());

}

else

{

cout << "表达式错误!" << endl;

}

}

double calculate2(const char* expression)

{

if (isExpression(expression))

{

string s = dealExpression(expression);

return infixCalculate(s.c_str());

}

else

{

cout << "表达式错误!" << endl;

}

}

int main()

{

cout << "输入一个表达式:" << endl;

string expression;

cin >> expression;

cout << "计算结果为:" << endl;

cout << calculate2(expression.c_str())<

/*cout << "请输入表达式:" << endl;

string expression;

cin >> expression;

cout << "计算结果为:" << endl;

cout << calculate(expression.c_str())<

/*cout << "测试6:postfixCalculate" << endl; OK

string s1 = "1+2+2*3+4+(1+2*3)";

cout << infixTranPostfix(s1.c_str());*/

//5 测试 infixCalculate OK

//4 测试deal expression() Ok

/*string expression;

cin >> expression;

cout << dealExpression(expression);*/

/*char* expression;

double result;

cout << "输入表达式:" << endl;

cin >> expression;*/

//1 测试isNumber(),isOperator(),isBracket()  OK

//char c;

//cin >> c;

//if (isNumber(c))

//cout << "数字";

//else if (isOperator(c))

//cout << "操作符";

//else if (isBracket(c))

//cout << "括号";

//else

//cout << "其它字符";

//2 测试isExpression()  OK

//char expression[100];

//cin >> expression;

//if (isExpression(expression))

//cout << "是表达式" << endl;

//else

//cout << "不是表达式" << endl;

//3 测试basicCalculat()   OK

/*cout << basicCalculate('3', '%', '5');*/

/*int a = toascii('s');

int b = 's' - '0'+48;

cout << a << endl << b << endl;*/

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,425评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,058评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,186评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,848评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,249评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,554评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,830评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,536评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,239评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,505评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,004评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,346评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,999评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,060评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,821评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,574评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,480评论 2 267

推荐阅读更多精彩内容