题目:
给定一个表达式,该表达式由以下规则生成:
1.“0”和“1”是合法表达式;
2.如果x是一个合法表达式,那么“(!x)”是一个合法表达式;
3.如果x和y是合法表达式,那么“(x|y)”和“(x&y)”都是一个合法表达式;
其中,!是逻辑非操作符,|和&分别是与运算符和或运算符,给定一个合法表达式,求该表达式最终的值。
输入描述:
第一行是一个整数T(T<=20)。接下来T行,每一行是一个合法表达式。表达式不含空格,且输入保证该表达式是一个合法表达式。
对于30%的数据,表达式的长度不超过500;对于100%的数据,表达式的长度不超过150000。
输出描述:
T行,每一行表示相应表达式的值。
示例:
输入:
3
(!0)
(0|(1&0))
(0|(1&(!0)))
输出:
1
0
1
思路:创建两个栈,每当遇到非数字字符时,除了符号')',全部压入第一个栈中,当遇到数字时,压入第二个栈;当遇到符号')'时,则从第二个栈中弹出栈顶数字,第一个栈弹出符号,直到第一个栈弹出的是符号'('为止,则退出这轮计算,最后把计算结果压入第二个数字栈中,以备下次继续计算。
代码:
#include <iostream>
#include <stack>
#include <assert.h>
using namespace std;
//注意:这个代码的运行前提条件是这个表达式合法,这里根据测试用例测试,就不多加考虑
int Count_Number(char * str)
{
//断言,str为合法字符串
assert(str != NULL);
//创建两个辅助栈
stack<char> stack1;
stack<char> stack2;
char tmp1;//用于保存stack1弹出的符号
int a,b;//用于保存stack2弹出的数字,并保存最后结果
while(*str != '\0')
{
if(*str == '(' || *str == '!' || *str == '&' || *str == '|')
{
stack1.push(*str);//遇到以上符号,压入stack1中
}
else if(*str == '0' || *str == '1')
{
stack2.push((*str-'0'));//遇到1到9的数字压入stack2中
}
else if(*str == ')')//遇到')'进行栈内数据和符号计算
{
tmp1 = stack1.top();
stack1.pop();
a = stack2.top();
stack2.pop();
while(tmp1 != '(')
{
if(tmp1 == '|')
{
b = stack2.top();
stack2.pop();
a = a|b;
}
else if(tmp1 == '&')
{
b = stack2.top();
stack2.pop();
a = a&b;
}
else if(tmp1 == '!')
{
a = !a;
}
tmp1 = stack1.top();
stack1.pop();
}
stack2.push(a);//将这一次的计算结果压入数字栈stack2中,以备下次继续计算
}
str++;
}
return (stack2.top());
}
int main()
{
//测试用例:
cout<<"请输入表达式的个数::"<<endl;
int num;
cin>>num;
char ** p = (char**)malloc(sizeof(char*)*num);
cout<<"请输入表达式:"<<endl;
for(int i = 0; i<num; i++)
{
p[i] = (char*)malloc(sizeof(char)*150000);
cin>>p[i];
// cout<<endl;
}
cout<<"结果:"<<endl;
for(int i = 0; i<num; i++)
{
cout<<Count_Number(p[i])<<endl;
}
return 0;
}