标签:读取 遍历 empty style nal switch opened return size
逆波兰数:逆波兰数由两部分组成(操作数,操作符)——是波兰表达式的一种,即操作符在操作数的后面。
形式:A+B*C-D = ABC*D-;
(A+B)*C-D = AB+C*D-;
既然我们知道了,后缀表达式那我们表达式是唯一的吗?我们来看一组数据:
例如:(A+B)*C-D 和 C*(A+B)-D;
很显然第二个的表达式为:C*AB+D-;虽然对最后的结果无影响,但我们需要知道逆波兰的多样性。
注意事项:
1、如果出现1+23 = 123+,该如何判断它的数值呢?
可以利用分割符来进行很好的辅助性理解,例如1+23 = 1#23#+,这样可以完美的解决此问题。
2、存在括号的时候该如何处理?
其一:是‘(’直接压入,‘)’时,将两者之间的运算符弹出,压入后缀表达式。
其二:遇到‘(’开辟一个新的运算符栈,‘)’时,当前栈内运算符弹出,压入后缀表达式。
算法:
1、中缀表达式——逆波兰表达式的转变。
2、逆波兰求值。
核心代码:
1、中缀表达式——逆波兰表达式的转变。
bool is_char(char c)//判断是否为操作符
{
return c == ‘-‘ || c == ‘+‘ || c == ‘*‘ || c == ‘/‘;
}
void change()//表达式的转化
{
char c;
int i = 0, j = 0;//i遍历输入的字符,j不同层数的字符栈
while ((c = original[i++]) != ‘\0‘)
{
if (is_char(c))//是字符
one[j].push(c);
else if (is_number(c))//是数字
{
int x = i;//
while (is_number(c))
{
sconed.push_back(c);
if (is_number(c = original[x++]))//是数值,则数组往后移动一位(确保下一步能读取字符)
i++;
}
sconed.push_back(‘#‘);//分隔符
if (!one[j].empty())//判断是否为空
if (one[j].top() == ‘*‘ || one[j].top() == ‘/‘)//高阶运算,直接取出,压入数值链表
{
sconed.push_back(one[j].top());
one[j].pop();
}
}
else if (c == ‘)‘)
{
Dum(j);//多余的运算符赋值
j--;//回到上一层的字符栈
}
else
j++;//新的字符栈
}
Dum(j);
}
void Dum(int j)//多余的运算符逐个压入数值链表
{
while (!one[j].empty())
{
sconed.push_back(one[j].top());
one[j].pop();
}
}
2、逆波兰求值。
void Do_it(std::stack<int> &mc)
{
while (!sconed.empty())//不为空时。
{
char mid = sconed.front();//临时存储字符
sconed.pop_front();//压出
switch (mid)//判断
{
int a, b;
case‘-‘:
b = mc.top(), mc.pop(), a = mc.top(), mc.pop();//得到前两个数值进行减法运算。
mc.push(a - b);
break;
case‘+‘:
b = mc.top(), mc.pop(), a = mc.top(), mc.pop();//得到前两个数值进行加法运算。
mc.push(a + b);
break;
case‘*‘:
b = mc.top(), mc.pop(), a = mc.top(), mc.pop();//得到前两个数值进行乘法运算。
mc.push(a * b);
break;
case‘/‘:
b = mc.top(), mc.pop(), a = mc.top(), mc.pop();//得到前两个数值进行除法运算。
if (b == 0)//分母不能位0
{
is_right = false;
return;
}
else
mc.push(a / b);
break;
default://获得数值
{
int sum = 0;
if (is_number(mid))
{
while (is_number(mid))
{
sum = sum * 10 + mid - ‘0‘;//字符到数字的改变
mid = sconed.front();
if (is_number(mid))
sconed.pop_front();
}
mc.push(sum);
}
}
}
}
}
3、GitHub源码;
标签:读取 遍历 empty style nal switch opened return size
原文地址:http://www.cnblogs.com/7750-13/p/7604604.html