/************************************************************************************
*description:表达式得到期望结果的组成种数
* 给定一个字符串express,只由false(假)、true(真)、&(与)、|(或)、^(异或)
* 这5种字符组成。再给定一个bool值desired。
* 返回express能有多少种组合方式达到desired
* 例:express=“1^0|0|1",desired=false
* 1^((0|0)|1)和1^(0|(0|1))可以得到false,返回2
*description:表达式得到期望结果的组成种数
* 给定一个字符串express,只由false(假)、true(真)、&(与)、|(或)、^(异或)
* 这5种字符组成。再给定一个bool值desired。
* 返回express能有多少种组合方式达到desired
* 例:express=“1^0|0|1",desired=false
* 1^((0|0)|1)和1^(0|(0|1))可以得到false,返回2
***********************************************************************************/
#include<iostream>
#include<vector>
#include<string>
using namespace std;
//有效的表达式:1.长度为奇数
// 2.下标偶数位的字符是:0或1
// 3.下标奇数为的字符是:&、|、^
bool isValid(string express)
{
if (express.size() % 2 == 0)
return false;
for (int i = 0; i < express.size(); i+=2)
if (express[i] == '&' || express[i] == '|' || express[i] == '^')
return false;
for (int i = 1; i < express.size(); i+=2)
if (express[i] == '0' || express[i] == '1')
return false;
return true;
}
//方法1:暴力递归.时间复杂度O(N!),空间复杂度O(N):函数栈大小
int process_num1(string exp, bool desired, int left, int right)
{
if (left == right)
if (exp[left] == '1')
return desired ? 1 : 0;
else
return desired ? 0 : 1;
int res = 0;
for (int i = left+1; i < right; i+=2)
{
if (desired == true)
{
switch (exp[i])
{
case '&':
res += process_num1(exp, true, left, i-1) * process_num1(exp, true, i+1, right);
break;
case '|':
res += process_num1(exp, true, left, i-1) * process_num1(exp, true, i+1, right)
+process_num1(exp, true, left, i-1) * process_num1(exp, false, i+1, right)
+process_num1(exp, false, left, i-1) * process_num1(exp, true, i+1, right);
break;
case '^':
res += process_num1(exp, true, left, i-1) * process_num1(exp, false, i+1, right)
+process_num1(exp, false, left, i-1) * process_num1(exp, true, i+1, right);
default:
break;
}
}
else
{
switch (exp[i])
{
case '&':
res += process_num1(exp, true, left, i-1) * process_num1(exp, false, i+1, right)
+process_num1(exp, false, left, i-1) * process_num1(exp, true, i+1, right)
+process_num1(exp, false, left, i-1) * process_num1(exp, false, i+1, right);
break;
case '|':
res += process_num1(exp, false, left, i-1) * process_num1(exp, false, i+1, right);
break;
case '^':
res += process_num1(exp, true, left, i-1) * process_num1(exp, true, i+1, right)
+process_num1(exp, false, left, i-1) * process_num1(exp, false, i+1, right);
default:
break;
}
}
}
return res;
}
int numOfCombine_1(string express, bool desired)
{
if (express.size() == 0)
return 0;
if (isValid(express) == false)
return 0;
return process_num1(express, desired, 0, express.size()-1);
}
//方法2:动态规划.时间复杂度O(N^3),空间复杂度O(N^2)
//建立数组 t[N][N]和f[N][N],其中N为express的大小。
//t[j][i]表示express[j...i]组成true的种类;f[j][i]表示express[j...i]组成false的种类。
//t[0][N-1]或f[0][N-1]即为结果。
int numOfCombine_2(string express, bool desired)
{
if (express.size() == 0)
return 0;
if (isValid(express) == false)
return 0;
int N = express.size();
vector<vector<int>> t(N, N);
vector<vector<int>> f(N, N);
t[0][0] = express[0] == '1' ? 1 : 0;
f[0][0] = express[0] == '0' ? 1 : 0;
for (int i = 2; i < N; i += 2 )
{
t[i][i] = express[i] == '1' ? 1 : 0;
f[i][i] = express[i] == '0' ? 1 : 0;
for (int j = i - 2; j >= 0; j -= 2)
{
for (int k = j; k < i; k += 2)
{
if (express[k+1] == '&')
{
t[j][i] += t[j][k] * t[k+2][i];
f[i][j] += (f[j][k] + t[j][k])*f[k+2][i]+f[j][k]*t[k+2][i];
}
else if (express[k+1] == '|')
{
t[j][i] += (f[j][k] + t[j][k])*t[k+2][i]+t[j][k]*f[k+2][i];
f[j][i] += f[j][k] * f[k+2][i];
}
else
{
t[j][i] = f[j][k] * t[k+2][i] + t[j][k] * f[k+2][i];
f[j][i] = f[j][k] * f[k+2][i] + t[j][k] * t[k+2][i];
}
}
}
}
return desired == true ? t[0][N-1] : f[0][N-1];
}
int main()
{
string exp = "1^0|0|1";
bool desired = false;
cout << numOfCombine_2(exp, desired);
return 0;
}