// 离散数学-命题公式.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include
#include
#include
#include
#include
#include
using namespace std;
int number;
char *tmp;
int j = 0;
const int length = 6;//命题变元的最大长度
char varist[length];
string expression;
bool* v;
bool first(string a);//命题公式必须由字母、运算符和括号组成
bool second(string a);//不允许右括号后接字母
bool third(string a);//不允许运算符后面接运算符或右括号
bool fourth(string a);//不允许左括号后接运算符(!除外)
bool fifth(string a);//不允许左括号前有字母或右括号
bool sixth(string a);//命题公式开头必须是:字母、!、左括号这三者其一
bool seventh(string a);//命题公式结尾必须是字母或者右括号
bool eighth(string a);//左右括号匹配
int compare(char op1, char op2);//运算符优先级的比较
void createvarlist(string s);//将表达式中的所有命题变元插入到全局数组
bool calculate(string s, bool* varValue);//求命题公式在一组赋值(存放在bool数组中)下的真值取值情况,并将其真值返回
void increase(bool* v);//将数组v中的当前赋值取值+1
int seek(char p);//查找指定变元在变元数组中的存放位置,并返回其下标
bool count(bool op1, bool op2, char op);//计算op1与op2做op运算符的运算,并把结果返回.
int main()
{
cout << "请输入命题公式,并以'#'号结束" << endl;
getline(cin, expression);//而不是getline(cin,expression,'#')
cout << "表达式为:" << expression << endl;
createvarlist(expression);
if (first(expression) && second(expression) && third(expression) && fourth(expression) && fifth(expression) && sixth(expression) && seventh(expression) && eighth(expression))
{
v = new bool[number];//赋值数组初始化
for (int i = 0; i < number; i++)
v[i] = false;
for (int i = 0; i < number; i++)//真值表的表头输出
cout << setw(3) << varist[i];
cout << " " << expression << endl;
for (int i = 0; i < pow(2, number); i++)//每一种赋值情况
{
for (int j = 0; j < number; j++)
cout << setw(3) << v[j];
cout << " " << calculate(expression, v);//未带有#(则引起报错)
increase(v);
cout << endl;
}
}
else
cout << "命题公式不合法" << endl;
system("pause");
return 0;
}
bool first(string a)
{
for (int i = 0; i < a.length() - 1; i++)
{
if (strchr("+-|&!()", a[i]) || (a[i] >= 'A'&&a[i] <= 'z'))
continue;
else
return false;
}
return true;
}
bool second(string a)
{
for (int i = 0; i <= a.length() - 1; i++)
{
if (a[i] == ')')
{
if (a[i + 1] >= 'A'&&a[i + 1] <= 'z')//A的ASCII码:65,z的ASCII码:122
{
return false;
}
else
continue;
}
else
continue;
}
return true;
}
bool third(string a)
{
for (int i = 0; i < a.length() - 1; i++)
{
if (strchr("+-|&!", a[i]))
{
if (strchr("+-|&!", a[i + 1]) || a[i + 1] == ')')
return false;
else
continue;
}
else
continue;
}
return true;
}
bool fourth(string a)
{
for (int i = 0; i < a.length() - 1; i++)
{
if (a[i] == '(')
{
if (strchr("+-|&", a[i + 1]))
return false;
else
continue;
}
else
continue;
}
return true;
}
bool fifth(string a)
{
for (int i = 0; i < a.length() - 1; i++)
{
if (a[i] == '('&&i >= 1)
{
if (a[i - 1] == ')' || (a[i - 1] >= 'A'&&a[i - 1] <= 'z'))
return false;
else
continue;
}
else
continue;
}
return true;
}
bool sixth(string a)
{
if (a[0] == '!' || (a[0] >= 'A'&&a[0] <= 'z') || a[0] == '(')
return true;
else
return false;
}
bool seventh(string a)
{
if ((a[a.length() - 2] >= 'A'&&a[a.length() - 2] <= 'z') || a[a.length() - 2] == ')')
return true;
else
return false;
}
bool eighth(string a)
{
int b = 0;
char *tmp = new char[a.length() - number - 1];//存放括号
for (int i = 0, j = 0; i < a.length() - 1; i++)
{
if (strchr("()", a[i]))
{
tmp[j] = a[i];
j++;
}
else
continue;
}
for (int x = 0; x < (a.length() - 1 - number); ++x)
{
switch (tmp[x])
{
case '(':
++b;
break;
case ')':
++b;
break;
}
}
if (b % 2 == 0)
return true;
else
return false;
}
int compare(char op1, char op2)//比较两运算符的优先级
{
if (op2 == '#' || (op1 == '-'&&op2 == ')') || (op1 == '+'&&op2 == ')'))//特别声明出来的,判断条件的缺失
return 1;
if (op1 == '('&&op2 == ')' || op1 == '#'&&op2 == '#')
return 0;// 优先级相同
else if (op1 == '#' || op1 == '(' || op2 == '(' || op2 == '!' || op1 == '-' || (op1 == '|' && op2 == '&')/* || (op1 == '|' &&op2 == '!') || (op1 == '&'&&op2 == '!')*/)
return -1;//op1的优先级低于op2(入栈)
else
return 1;//op1的优先级高于op2(计算)
}
void createvarlist(string s)//命题变元的提取
{
char ch;
for (unsigned int i = 0; i < s.size() && (ch = s[i]) != '#'; i++)//扫描命题公式中所有字符
if (!strchr("+-|&!()#", ch)) //若ch不是运算符,则为命题变元
{
int j;
for (j = number - 1; j >= 0 && varist[j] > ch; j--)//在变元表varList数组中查找ch的插入位置,使之保持有序
varist[j + 1] = varist[j];
if (varist[j] < ch) //若varList[j]==ch,则表示该变元已经存放在varList数组中,无需再次插入
{
varist[j + 1] = ch;
number++;
}
}
}
int seek(char p)
{
int loc;
for (loc = 0; varist[loc] != p&&loc < number; loc++);
return loc;
}
void increase(bool* v)
{
for (int i = number - 1; i >= 0; i--)
{
if (v[i] + 1 == 1)//最后位为0
{
v[i] = 1;
break;
}
if (v[i] + 1 == 2)//最后位为1
{
v[i] = 0;
continue;
}
}
}
bool count(bool op1, bool op2, char op)
{
switch (op)
{
case '&':
if (op1 == 1 && op2 == 1)
return true;
else
return false;
case '|':
if (op1 == 0 && op2 == 0)
return false;
else
return true;
case '-':
if (op1 == 0 && op2 == 1)//考虑到命题变元的出栈顺序是相反的
return false;
else
return true;
case '+'://双条件
if (op1 != op2)
return false;
else
return true;
}
}
bool calculate(string s, bool* value)
{
stack
stack
char op, ch = '#';
int i = 0;
bool a, b;
optr.push(ch);
while ((ch = s[i]) != '#' || optr.top() != '#')
{
if (!strchr("+-|&!()#", ch))//是变元(即为操作数),则取变元的当前赋值压入堆栈中
{
opnd.push(value[seek(ch)]);
++i;
}
else
{
op = optr.top();
switch (compare(op, ch))
{
case 0:
optr.pop();
i++;
break;
case -1:
optr.push(ch);
i++;
break;
case 1:
if (optr.top() == '!')
{
opnd.top() = !opnd.top();
optr.pop();
break;
}
else
{
a = opnd.top();
opnd.pop();
b = opnd.top();
opnd.pop();
opnd.push(count(a, b, optr.top()));
optr.pop();
break;
}
}
}
}
if (!optr.empty() && optr.top() != '#')//清空optr栈,以进行下一循环
{
optr.pop();
}
return opnd.top();
}