利用C语言编写代码满足下列要求:用户输入公式,写出公式的真值表以及主析取范式、主合取范式并判断公式类型
时间: 2024-03-22 21:40:28 浏览: 77
好的,我理解了你的问题。以下是一个简单的C语言程序,可以根据用户输入的公式生成真值表,并计算主析取范式和主合取范式。程序假设输入的公式只包含变量、非运算符、与运算符和或运算符。
```
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define MAX_VARIABLES 10 // 最大变量数
#define MAX_FORMULA_LENGTH 100 // 最大公式长度
// 定义结构体表示公式
struct Formula {
int variables[MAX_VARIABLES]; // 变量表
char operation[MAX_FORMULA_LENGTH]; // 运算符表
int length; // 公式长度
};
// 将一个十进制数转换为二进制字符串
char* decimal_to_binary(int decimal, int num_bits) {
char* binary = (char*) malloc(num_bits + 1);
for (int i = num_bits - 1; i >= 0; i--) {
binary[i] = (decimal % 2) + '0';
decimal /= 2;
}
binary[num_bits] = '\0';
return binary;
}
// 计算公式的值
int calculate_formula_value(struct Formula* formula, int input_values[]) {
int stack[MAX_FORMULA_LENGTH]; // 操作数栈
int top = 0; // 栈顶指针
for (int i = 0; i < formula->length; i++) {
if (formula->operation[i] == '!') {
int operand = stack[--top];
stack[top++] = !operand;
} else if (formula->operation[i] == '&') {
int operand2 = stack[--top];
int operand1 = stack[--top];
stack[top++] = operand1 && operand2;
} else if (formula->operation[i] == '|') {
int operand2 = stack[--top];
int operand1 = stack[--top];
stack[top++] = operand1 || operand2;
} else {
stack[top++] = input_values[formula->variables[i]];
}
}
return stack[0];
}
// 打印真值表
void print_truth_table(struct Formula* formula) {
int num_variables = 0;
for (int i = 0; i < MAX_VARIABLES; i++) {
if (formula->variables[i] != -1) {
num_variables++;
}
}
printf("Truth table:\n");
for (int i = 0; i < pow(2, num_variables); i++) {
int* input_values = (int*) malloc(num_variables * sizeof(int));
char* input_binary = decimal_to_binary(i, num_variables);
for (int j = 0; j < num_variables; j++) {
input_values[j] = input_binary[j] - '0';
printf("%d ", input_values[j]);
}
int output_value = calculate_formula_value(formula, input_values);
printf("%d\n", output_value);
free(input_values);
free(input_binary);
}
}
// 计算主析取范式和主合取范式
void print_disjunctive_and_conjunctive_normal_forms(struct Formula* formula) {
int num_variables = 0;
for (int i = 0; i < MAX_VARIABLES; i++) {
if (formula->variables[i] != -1) {
num_variables++;
}
}
printf("Disjunctive normal form:\n");
for (int i = 0; i < pow(2, num_variables); i++) {
int* input_values = (int*) malloc(num_variables * sizeof(int));
char* input_binary = decimal_to_binary(i, num_variables);
for (int j = 0; j < num_variables; j++) {
input_values[j] = input_binary[j] - '0';
}
int output_value = calculate_formula_value(formula, input_values);
if (output_value) {
for (int j = 0; j < num_variables; j++) {
if (input_values[j]) {
printf("%c", 'A' + j);
} else {
printf("!%c", 'A' + j);
}
if (j < num_variables - 1) {
printf(" | ");
}
}
printf("\n");
}
free(input_values);
free(input_binary);
}
printf("Conjunctive normal form:\n");
for (int i = 0; i < pow(2, num_variables); i++) {
int* input_values = (int*) malloc(num_variables * sizeof(int));
char* input_binary = decimal_to_binary(i, num_variables);
for (int j = 0; j < num_variables; j++) {
input_values[j] = input_binary[j] - '0';
}
int output_value = calculate_formula_value(formula, input_values);
if (!output_value) {
for (int j = 0; j < num_variables; j++) {
if (!input_values[j]) {
printf("%c", 'A' + j);
} else {
printf("!%c", 'A' + j);
}
if (j < num_variables - 1) {
printf(" & ");
}
}
printf("\n");
}
free(input_values);
free(input_binary);
}
}
// 判断公式类型
void print_formula_type(struct Formula* formula) {
int num_variables = 0;
for (int i = 0; i < MAX_VARIABLES; i++) {
if (formula->variables[i] != -1) {
num_variables++;
}
}
int num_clauses = 0;
int num_literals = 0;
for (int i = 0; i < formula->length; i++) {
if (formula->operation[i] == '|') {
num_clauses++;
} else if (formula->operation[i] == '&' || formula->operation[i] == '!') {
// do nothing
} else {
num_literals++;
}
}
if (num_literals == num_variables && num_clauses == 1) {
printf("Formula type: single clause\n");
} else if (num_literals == num_variables && num_clauses == 0) {
printf("Formula type: tautology\n");
} else if (num_literals == 0 && num_clauses == 1) {
printf("Formula type: contradiction\n");
} else {
printf("Formula type: normal\n");
}
}
int main() {
struct Formula formula;
printf("Please enter a formula: ");
char input[MAX_FORMULA_LENGTH];
scanf("%s", input);
formula.length = 0;
memset(formula.variables, -1, sizeof(formula.variables)); // 初始化变量表为-1
for (int i = 0; i < strlen(input); i++) {
if (input[i] >= 'A' && input[i] <= 'A' + MAX_VARIABLES - 1) {
// 变量
formula.variables[formula.length] = input[i] - 'A';
formula.operation[formula.length] = ' ';
formula.length++;
} else {
// 运算符
formula.operation[formula.length] = input[i];
formula.length++;
}
}
print_truth_table(&formula);
print_disjunctive_and_conjunctive_normal_forms(&formula);
print_formula_type(&formula);
return 0;
}
```
程序流程如下:
1. 从用户输入中解析出公式。
2. 针对每个可能的变量值,计算公式的真值并打印出真值表。
3. 针对每个可能的变量值,计算公式的真值并判断其是否为主析取范式或主合取范式,然后打印出来。
4. 根据公式中变量和运算符的数量,判断公式的类型并打印出来。
请注意,此程序仅支持包含变量、非运算符、与运算符和或运算符的公式。如果要支持其他运算符(例如蕴含、等价、异或等),需要进行相应的修改。
阅读全文