虽然很简单吧,但是毕竟算是除了刷题外第一个自己写出来的有一点用的代码,所以还是打算水一篇博客
主要思路就是把式子转化成后缀表达式,然后再用后缀表达式求值的方法来计算,其中每个命题变元的情况是用没有剪枝的深搜枚举出来的
下面是代码
ps:第一版代码的条件语句计算出了点问题,已经改了,顺便加了个多组输入
#include<cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <string>
#include <stack>
#include <map>
using namespace std;
map<char,int> q;
map<char,int> a;
string str;
bool true_false[50];
bool tf[2] = {true, false};
int cnt = 0;
string course[105];
bool count_out(){
stack<bool> b;
for(int i = 0;i<str.size();i++){
if(str[i]==\'#\'){
break;
}
if(isalpha(str[i])){
b.push(true_false[a[str[i]]]);
}else if(str[i]==\'!\'){
bool A = b.top();
b.pop();
b.push(!A);
}else if(str[i] == \'&\'){
bool A = b.top();
b.pop();
bool B = b.top();
b.pop();
b.push(A&&B);
}else if(str[i] == \'|\'){
bool A = b.top();
b.pop();
bool B = b.top();
b.pop();
b.push(A||B);
}else if(str[i] == \'-\'||str[i]==\'%\'){
bool A = b.top();
b.pop();
bool B = b.top();
b.pop();
b.push(!(!A&&B));
}else if(str[i] == \'=\'){
bool A = b.top();
b.pop();
bool B = b.top();
b.pop();
b.push((A&&B)||(!A&&!B));
}
}
return b.top();
}
void deep(int i){
if(i==cnt+1){
for(int j = 1;j<=cnt;j++){
cout<<(true_false[j]?"T ":"F ");
}
cout<<\'\t\';
cout<<(count_out()?"T":"F")<<endl;//计算后缀式的值
return;
}else{
for(int j = 0;j<2;j++){
true_false[i] = tf[j];
deep(i+1);
}
}
}
void init(){
q.clear();
memset(true_false,0, sizeof(true_false));
str.clear();
a.clear();
q[\'#\'] = -1;
q[\'(\'] = 0;
q[\'!\'] = 6;
q[\'&\'] = 5;
q[\'|\'] = 4;
q[\'-\'] = 3;
q[\'=\'] = 2;
q[\'%\'] = 1;
cnt = 0;
}
void output(string s,string s_out){
for(int i = 0;i<s_out.size();i++){
cout<<s_out[i]<<\' \';
}
cout<<s<<endl;
}
string getRPN(string s){
string s_out;
stack<char> operation;
for(int i = 0;i<s.size();i++){
if(s[i]==\'#\') break;
if(isalpha(s[i])){
str+=s[i];
if(!a[s[i]]){
s_out+=s[i];
a[s[i]] = ++cnt;
}
}else{
if(operation.empty()) operation.push(s[i]);
else if(s[i]==\'(\')
operation.push(s[i]);
else if(s[i]==\')\'){
while(operation.top()!=\'(\'){
str+=operation.top();
operation.pop();
}
operation.pop();
}
else if(q[s[i]]>q[operation.top()]){
operation.push(s[i]);
}else{
str+=operation.top();
operation.pop();
operation.push(s[i]);
}
}
}
while(!operation.empty()){
str+=operation.top();
operation.pop();
}
str+=\'#\';
return s_out;
}
int main() {
ios::sync_with_stdio(false);
string s;
while(cin>>s){
init(); //初始化
string s_out = getRPN(s); //将命题表达式转为后缀式并输出表头
output(s,s_out);
deep(1); //搜索找所有命题变元的TF情况
}
return 0;
}