basic4android计算器,简单字符串计算器Basic Calculator

Basic Calculator

简单字符串计算器的实现

1.题目说明

本题大意为要求我们实现对有且只有加减号、括号作为运算符的字符串进行数学运算得出结果。

2.题意理解

由于本题只要求在字符串中有加减号而没有乘除号,这就使我们可以永远通过括号内优先作为优先级判断标准,从而不需要逆波兰表达式存储,也即不需要压栈、退栈等操作。然而,由于想将此题封装为一个通用的算法,并希望配合练习带有加减乘除、括号等所有运算符的逆波兰表达式计算问题,此题本人仍使用逆波兰表达式方法。虽然算法复杂度高于此题需要,但可以为后续使用作准备

3. 算法描述

此部分算法描述大可略过,因为想必读者均已熟悉如下套路:

通过栈结构将输入字符串转化为逆波兰表达式;

通过栈结构将波兰表达式计算成结果。

此算法毕竟是说起来简单,做起来难。因为其中有很多地方容易出错,造成编程者在Debug时所用的时间远大于编程时间。下面就对逆波兰表达式算法部分的关键之处进行剖析。

优先级判定:本人推荐使用7阶二维矩阵,直接存储’>’,’

数字存储:本例暂时只对正数进行运算,在防止出现两位数情况时,在遇到数字时设立标志位,若下一个字符还是数字,便将前一数字一同存储为数字元素,依此类推。

压栈退栈:若当前运算符优先级大于栈顶运算符优先级,将当前运算符压入;若小于,则将栈内所有比当前运算符优先级小的运算符弹出;若等于,说明是括号相遇,同时退栈。

class Solution

{

public:

static char Prior[7][7];//运算符优先级矩阵

int CodeOfOpnd(char

opnd)//运算符代号

{

switch (opnd)

{

case '+':

return 0;

case '-':

return 1;

case '*':

return 2;

case '/':

return 3;

case '(':

return 4;

case ')':

return 5;

case '#':

return 6;

}

}

double MathCalculate(int

op1, int op2,

char opnd)//运算符运算方法

{

switch (opnd)

{

case '+':

return op1 +

op2;

case '-':

return op2 -

op1;

case '*':

return op1 *

op2;

case '/':

return op2 /

op1;

}

}

int calculate(string

s)//计算函数

{

s.push_back('#');

stack<char>opnd;

opnd.push('#');

vector<int>save;

bool pre_is_num = false;

//逆波兰表达式建立

for (int i =

0; i <

s.size(); i++)

{

if (s[i]

>= '0' &&

s[i] <= '9')

{

if (pre_is_num == false)

{

save.push_back(s[i]

- '0');

}

else

{

save[save.size()

- 1]

= save[save.size()

- 1]

* 10 +

s[i]

- '0';

}

pre_is_num = true;//数字标志位

}

else if (s[i] ==

'+' || s[i] ==

'-' || s[i] ==

'*' || s[i] ==

'/' || s[i] ==

'(' || s[i] ==

')' || s[i] ==

'#')

{

while (Prior[CodeOfOpnd(opnd.top())][CodeOfOpnd(s[i])]

== '>')//若当前运算符优先级小于栈顶运算符优先级

{

save.push_back(opnd.top());//将弹出的运算符存入逆波兰表达式

opnd.pop();//不断弹出

}

if (Prior[CodeOfOpnd(opnd.top())][CodeOfOpnd(s[i])]

== '

{

opnd.push(s[i]);//压入当前运算符

}

if (Prior[CodeOfOpnd(opnd.top())][CodeOfOpnd(s[i])]

== '=')//若当前运算符优先级等于栈顶运算符优先级

{

opnd.pop();//只退栈

}

pre_is_num = false;

}

}

stack<double>Number;

//通过逆波兰表达式运算

for (int i

= 0; i

< save.size(); i++)

{

if (save[i]

>= 0 && save[i]

!= '+' && save[i]

!= '-' && save[i]

!= '*' && save[i]

!= '/')

{

Number.push(save[i]);

}

else

{

int op1 = Number.top();

Number.pop();

int op2 = Number.top();

Number.pop();

Number.push(MathCalculate(op1,

op2, save[i]));

}

}

int result = Number.top();

return result;

}

};

char Solution::Prior[7][7]

= { {

'>', '>', '', '>' }, {

'>', '>', '', '>' },

{ '>', '>', '>', '>', '', '>' }, {

'>', '>', '>', '>', '', '>' },

{ '

'*' }, { '>', '>', '>', '>', '*',

'>', '>' },

{ '

'=' } };

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值