用c++写 同学们都学习过《离散数学》这门课程,知道真值表是用于逻辑中的一类数学用表,用来计算逻辑表示式在每一个逻辑变量取值组合下的值。在这里我们给定一个逻辑表达式,要求生成对应的真值表。提示一下,数据结构教材中介绍了数学表达式的处理算法,可以将其改造以适用于我们的项目。 项目分为三个子项目,第一部分为词法分析,即将逻辑表达式分隔为多个词(token)。下面给出两个例子。 例一: 逻辑表达式p^q中有p、^和q共三个词; 例二: 逻辑表达式p^(q^r)中有p、^、(、q、^、r和)共七个词。 逻辑联结词有五个,见下表,这些符号和教材上的有所不同,主要是为了方便。 否定 合取 析取 蕴涵 等值 ! ^ || -> <-> 引入括号,规定基本逻辑联接词优先顺序从高到低依次是:( )、!、∧、||、->、<->。 同一优先级,从左到右顺序进行。 输入 输入由多行组成,每行都是一个正确的逻辑表达式。 逻辑表达式小于100个字符。 一个正确的逻辑表达式可以包含小写字母,空格和逻辑联结词(含括号)。单个小写字母表示一个逻辑变量,一个表达式中逻辑变量的个数不超过10。空格作为分隔符, 不是词,同一个词的字符之间不能有空格。 输出 每一个逻辑表达式产生如下的输出: 第一行按顺序输出表达式中的所有词。每个词之间用空格分开。 第二行按字母序输出表达式中的所有逻辑变量,用空格分开。 第三行开始输出逻辑变量值的所有组合情况。 具体见样例。 样例输入 Copy p p->q p||q 样例输出 Copy p p 1 0 p -> q p q 1 1 1 0 0 1 0 0 p || q p q 1 1 1 0 0 1 0 0
时间: 2024-03-10 14:46:45 浏览: 85
以下是C++代码实现:
```cpp
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;
const int MAXN = 15;
map<char, int> id; // 存储每个变量对应的编号
int n; // 变量个数
struct Token {
string str; // 词
int type; // 词类型,1表示变量,2表示运算符
} tokens[MAXN * 10]; // 最多有10个变量,每个变量最多由长度为1的字符组成,加上运算符最多也就10*10个token
int tok_idx; // token计数器
void lex(string s) {
tok_idx = 0;
for (int i = 0; i < s.size(); i++) {
if (s[i] == ' ') continue; // 空格不是词
if (s[i] == '(' || s[i] == ')') { // 括号是词
tokens[tok_idx++] = { string(1, s[i]), 2 };
continue;
}
if (s[i] == '^' || s[i] == '!' || s[i] == '-' || s[i] == '<' || s[i] == '>' || s[i] == '|' || s[i] == '&') { // 运算符是词
if (i + 1 < s.size() && s[i] == '-' && s[i + 1] == '>') { // 特判->
tokens[tok_idx++] = { "->", 2 };
i++;
} else if (i + 2 < s.size() && s[i] == '<' && s[i + 1] == '-' && s[i + 2] == '>') { // 特判<->
tokens[tok_idx++] = { "<->", 2 };
i += 2;
} else {
tokens[tok_idx++] = { string(1, s[i]), 2 };
}
continue;
}
if (id.find(s[i]) == id.end()) { // 变量是词
id[s[i]] = n++;
}
tokens[tok_idx++] = { string(1, s[i]), 1 };
}
}
bool calc(bool a, bool b, string op) { // 计算两个值的运算结果
if (op == "!") return !a;
if (op == "^") return a && b;
if (op == "||") return a || b;
if (op == "->") return !a || b;
if (op == "<->") return a == b;
return false;
}
void dfs(int idx, vector<bool>& values) { // 枚举变量取值的所有可能情况
if (idx == n) { // 到底了,输出值
for (int i = 0; i < n; i++) {
cout << values[i] << " ";
}
cout << calc(values[0], values[1], tokens[2].str); // 计算表达式的值
for (int i = 3; i < tok_idx; i += 2) { // 计算剩下的表达式的值
cout << " " << calc(values[tokens[i - 1].str[0] - 'a'], values[tokens[i + 1].str[0] - 'a'], tokens[i].str);
}
cout << endl;
return;
}
values[idx] = false;
dfs(idx + 1, values);
values[idx] = true;
dfs(idx + 1, values);
}
int main() {
string s;
while (getline(cin, s)) {
n = 0;
id.clear();
lex(s);
sort(tokens, tokens + tok_idx, [](const Token& a, const Token& b){ return a.type < b.type; }); // 按照优先级排序
vector<bool> values(n);
for (int i = 0; i < tok_idx; i++) {
if (tokens[i].type == 1) { // 变量,记录下来
values[id[tokens[i].str[0]]] = true;
}
}
sort(id.begin(), id.end()); // 按照字母序排序
for (int i = 0; i < tok_idx; i++) {
cout << tokens[i].str << " ";
}
cout << endl;
for (auto& p : id) {
cout << p.first << " ";
}
cout << endl;
dfs(0, values);
}
return 0;
}
```
阅读全文