要求能够输出任意逻辑表达式的真值表
时间: 2024-03-13 20:44:29 浏览: 49
为了能够输出任意逻辑表达式的真值表,我们需要先将逻辑表达式转化为逆波兰表达式,然后再使用栈来计算表达式的值,并输出真值表。下面是一个简单的C语言程序,可以实现这个功能:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_EXPR_LEN 100 // 定义逻辑表达式的最大长度
typedef enum {
OPERAND, // 操作数
OPERATOR // 操作符
} TokenType;
typedef struct {
TokenType type; // Token类型
union {
char operator; // 操作符
int operand; // 操作数
} value;
} Token;
typedef struct StackNode {
Token data;
struct StackNode *next;
} StackNode, *Stack;
Stack createStack() {
Stack stack = (Stack) malloc(sizeof(StackNode));
stack->next = NULL;
return stack;
}
int isEmpty(Stack stack) {
return stack->next == NULL;
}
Token top(Stack stack) {
Token token;
if (!isEmpty(stack)) {
token = stack->next->data;
}
return token;
}
void push(Stack stack, Token token) {
StackNode *newNode = (StackNode *) malloc(sizeof(StackNode));
newNode->data = token;
newNode->next = stack->next;
stack->next = newNode;
}
Token pop(Stack stack) {
Token token;
if (!isEmpty(stack)) {
StackNode *p = stack->next;
token = p->data;
stack->next = p->next;
free(p);
}
return token;
}
int isOperator(char c) {
return c == '~' || c == '&' || c == '|' || c == '^';
}
int priority(char c) {
switch (c) {
case '~':
return 3;
case '&':
return 2;
case '|':
return 1;
case '^':
return 0;
default:
return -1;
}
}
void infixToPostfix(char *infix, Token *postfix, int *postfixSize) {
Stack stack = createStack();
int i = 0;
int j = 0;
while (infix[i] != '\0') {
if (infix[i] >= '0' && infix[i] <= '9') {
Token token = {OPERAND, .value.operand = infix[i] - '0'};
postfix[j++] = token;
} else if (isOperator(infix[i])) {
while (!isEmpty(stack) && priority(top(stack).value.operator) >= priority(infix[i])) {
postfix[j++] = pop(stack);
}
Token token = {OPERATOR, .value.operator = infix[i]};
push(stack, token);
} else if (infix[i] == '(') {
Token token = {OPERATOR, .value.operator = infix[i]};
push(stack, token);
} else if (infix[i] == ')') {
while (top(stack).value.operator != '(') {
postfix[j++] = pop(stack);
}
pop(stack);
}
i++;
}
while (!isEmpty(stack)) {
postfix[j++] = pop(stack);
}
*postfixSize = j;
}
int evaluatePostfix(Token *postfix, int postfixSize, int *values) {
Stack stack = createStack();
for (int i = 0; i < postfixSize; i++) {
if (postfix[i].type == OPERAND) {
push(stack, postfix[i]);
} else if (postfix[i].type == OPERATOR) {
if (postfix[i].value.operator == '~') {
Token operand = pop(stack);
Token result = {OPERAND, .value.operand = !operand.value.operand};
push(stack, result);
} else {
Token operand2 = pop(stack);
Token operand1 = pop(stack);
int value1 = values[operand1.value.operand];
int value2 = values[operand2.value.operand];
int result;
switch (postfix[i].value.operator) {
case '&':
result = value1 && value2;
break;
case '|':
result = value1 || value2;
break;
case '^':
result = value1 ^ value2;
break;
}
Token token = {OPERAND, .value.operand = result};
push(stack, token);
}
}
}
int result = pop(stack).value.operand;
return result;
}
void printTruthTable(char *expr) {
Token postfix[MAX_EXPR_LEN];
int postfixSize = 0;
infixToPostfix(expr, postfix, &postfixSize);
int numVars = 0;
int values[MAX_EXPR_LEN];
for (int i = 0; i < postfixSize; i++) {
if (postfix[i].type == OPERAND) {
values[postfix[i].value.operand] = 0;
numVars = postfix[i].value.operand + 1 > numVars ? postfix[i].value.operand + 1 : numVars;
}
}
printf("%s\n", expr);
for (int i = 0; i < numVars; i++) {
printf("x%d\t", i);
}
printf("result\n");
for (int i = 0; i < (1 << numVars); i++) {
for (int j = 0; j < numVars; j++) {
values[j] = (i >> j) & 1;
printf("%d\t", values[j]);
}
int result = evaluatePostfix(postfix, postfixSize, values);
printf("%d\n", result);
}
}
int main() {
char expr[MAX_EXPR_LEN];
printf("请输入逻辑表达式:\n");
scanf("%s", expr);
printTruthTable(expr);
return 0;
}
```
在这个程序中,我们定义了一个 `Token` 结构体,用于表示逆波兰表达式中的每个元素,包括操作符和操作数。然后我们使用两个函数 `infixToPostfix` 和 `evaluatePostfix` 分别将中缀表达式转化为逆波兰表达式,并计算逆波兰表达式的值。最后,我们使用 `printTruthTable` 函数输出逻辑表达式的真值表。
在 `printTruthTable` 函数中,我们首先将逻辑表达式转化为逆波兰表达式,并统计变量的数量。然后我们遍历所有可能的变量取值,计算逻辑表达式的值,并输出真值表。注意,我们使用了位运算来生成所有可能的变量取值。
你可以在命令行中输入逻辑表达式,程序会输出该表达式的真值表。
阅读全文