给定一个命题公式,求他的主析取范式和主和取范式,用C语言实现
时间: 2024-02-09 11:08:31 浏览: 16
下面是用C语言实现求解主析取范式和主和取范式的示例代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define MAX_LEN 100
// 定义结构体表示命题公式的节点
struct Node {
char symbol; // 符号
bool isNeg; // 是否取反
struct Node *next; // 指向下一个节点的指针
};
// 定义函数用于创建新节点
struct Node* newNode(char symbol, bool isNeg) {
struct Node* node = (struct Node*)malloc(sizeof(struct Node));
node->symbol = symbol;
node->isNeg = isNeg;
node->next = NULL;
return node;
}
// 定义函数用于向链表添加新节点
void addNode(struct Node** head_ref, char symbol, bool isNeg) {
struct Node* node = newNode(symbol, isNeg);
node->next = *head_ref;
*head_ref = node;
}
// 定义函数用于删除链表
void deleteList(struct Node** head_ref) {
struct Node* current = *head_ref;
struct Node* next = NULL;
while (current != NULL) {
next = current->next;
free(current);
current = next;
}
*head_ref = NULL;
}
// 定义函数用于打印链表
void printList(struct Node* head) {
struct Node* current = head;
while (current != NULL) {
if (current->isNeg) {
printf("~");
}
printf("%c", current->symbol);
current = current->next;
if (current != NULL) {
printf(" or ");
}
}
}
// 定义函数用于求解主析取范式
void getDNF(char* formula) {
int len = strlen(formula);
struct Node* head = NULL;
for (int i = 0; i < len; i++) {
if (formula[i] == '(') {
i++;
bool isNeg = false;
if (formula[i] == '~') {
isNeg = true;
i++;
}
addNode(&head, formula[i], isNeg);
} else if (formula[i] == ')') {
// 找到一个括号内的主项
printList(head);
printf(" and ");
deleteList(&head);
}
}
}
// 定义函数用于求解主和取范式
void getCNF(char* formula) {
int len = strlen(formula);
struct Node* head = NULL;
for (int i = 0; i < len; i++) {
if (formula[i] == '(') {
i++;
bool isNeg = false;
if (formula[i] == '~') {
isNeg = true;
i++;
}
addNode(&head, formula[i], isNeg);
} else if (formula[i] == ')') {
// 将链表中的每个节点取反,然后找到一个括号内的主项
struct Node* current = head;
while (current != NULL) {
current->isNeg = !current->isNeg;
current = current->next;
}
printList(head);
printf(" or ");
deleteList(&head);
}
}
}
// 测试
int main() {
char formula[MAX_LEN];
printf("请输入命题公式:\n");
fgets(formula, MAX_LEN, stdin);
formula[strcspn(formula, "\n")] = '\0'; // 去掉fgets()读入的换行符
printf("主析取范式为:\n");
getDNF(formula);
printf("\n主和取范式为:\n");
getCNF(formula);
return 0;
}
```
注意:此代码仅适用于括号匹配的命题公式,若涉及到更复杂的命题公式,需要进行适当修改。
阅读全文