离散数学命题公式求真值表

为了输入和处理的时候方便,做了以下规定:

否定:!

合取:&

析取:|

蕴含:>

等价: -

#include<map>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define ElemPyte char
#define maxn 100
#pragma warning(disable : 4996)
using namespace std;

class Stack 
{
public:
	Stack();
	int M;
	ElemPyte* top;
	ElemPyte* best;
	void push(ElemPyte e)
	{
		if (top - best >= M)
		{
			best = (ElemPyte*)realloc(best, sizeof(ElemPyte) * (M + maxn));
			if(!best)
			{
				exit(0);
			}
			M += maxn;
		}
		*top = e;
		top++;
	}
	ElemPyte pop()
	{
		if (top == best) return 0;
		return *(--top);
	}
	bool empty()
	{
		return best == top;
	}
};
Stack::Stack()
{
	M = maxn;
	best = (ElemPyte*)malloc(sizeof(ElemPyte) * maxn);
	if (!best)
	{
		exit(0);
	}
	top = best;
}
Stack s1;
char a[10000];
char rpn[10000];
int rpn_t;
map<char, int>book;
map<char, int>book2;
int t =0;
int e[26];
char slove(char s[], int n)
{
	int i = 0;
	while ( i < n)
	{
		if (s[i]=='!')
		{
			if (s[i + 1] == '!')
			{
				for (int j = i; j < n - 2; j++)
				{
					s[j] = s[j + 2];
				}
				n -= 2;
				continue;
			}
			else
			{
				s[i + 1] ^= 1;
				for (int j = i; j < n-1; j++)
				{
					s[j] = s[j + 1];
				}
				n--;
				i++;
			}
		}
		else
		{
			i++;
		}
	}
	int sum;
	do
	{
		sum = 0;
		for (i = 0; i < n-1; i++)
		{
			if (s[i] == '&')
			{
				sum++;
				s[i - 1] = ((s[i - 1] - '0') && (s[i + 1] - '0')) + '0';
				for (int j = i; j < n - 2; j++)
				{
					s[j] = s[j + 2];
				}
				n -= 2;
			}
		}
	} while (sum);
	do
	{
		sum = 0;
		for (i = 0; i < n - 1; i++)
		{
			if (s[i] == '|')
			{
				sum++;
				s[i - 1] = ((s[i - 1] - '0') || (s[i + 1] - '0')) + '0';
				for (int j = i; j < n - 2; j++)
				{
					s[j] = s[j + 2];
				}
				n -= 2;
			}
		}
	} while (sum);
	do
	{
		sum = 0;
		for (i = 0; i < n - 1; i++)
		{
			if (s[i] == '>')
			{
				sum++;
				if (s[i - 1] == '0')
				{
					s[i - 1] = '1';
				}
				else
				{
					if (s[i + 1] == '1')
					{
						s[i - 1] = '1';
					}
					else
					{
						s[i - 1] = '0';
					}
				}
				for (int j = i; j < n - 2; j++)
				{
					s[j] = s[j + 2];
				}
				n -= 2;
			}
		}
	} while (sum);
	do
	{
		sum = 0;
		for (i = 0; i < n - 1; i++)
		{
			if (s[i] == '-')
			{
				sum++;
				if (s[i - 1] == s[i + 1])
				{
					s[i - 1] = '1';
				}
				else
				{
					s[i - 1] = '0';
				}
				for (int j = i; j < n - 2; j++)
				{
					s[j] = s[j + 2];
				}
				n -= 2;
			}
		}
	} while (sum);
	s[n] = '\0';
	return s[0];
}
int main()
{
	printf("请输入命题公式\n");
	printf("否定:!\n合取:&\n析取:|\n蕴含:>\n等价:-\n");
	scanf("%s", a);
	int n = strlen(a);
	for (int i = 0; i < n; i++) if (a[i] != '!' && a[i] != '&' && a[i] != '|' && a[i] != '>' && a[i] != '-' && a[i] != '(' && a[i] != ')' && !book2[a[i]]) book2[a[i]]=1,e[t++]=a[i]-'a';
	sort(e, e + t);
	for (int i = 0; i < t; i++) book[e[i] + 'a'] = t - i;
	for (int pos = 0; pos < 1 << t; pos++)
	{
		char copy[1000];
		for (int i = 0; i < n; i++)
		{
			copy[i] = a[i];
			if (a[i] != '!' && a[i] != '&' && a[i] != '|' && a[i] != '>' && a[i] != '-' && a[i] != '(' && a[i] != ')')
			{
				copy[i] = '0' + (1 & pos >> book[a[i]]-1);
			}
		}
		char str[1000];
		int sum = 0,str_n=0;
		do
		{
			sum = 0;
			int i = n - 1;
			int r = n;
			while ( i >= 0 )
			{
				str_n = 0;
				if (copy[i] == '(')
				{
					sum++;
					int j;
					for (j = i + 1; j < n; j++)
					{
						if (copy[j] != ')')
						{
							str[str_n++] = copy[j];
						}
						else
						{
							break;
						}
					}
					str[str_n] = '\0';
					copy[i] = slove(str, str_n);
					int e = r;
					r = i+1;
					for (int k = j + 1; k < e; k++) copy[r++] = copy[k];
					copy[r++] = '\0';
					break;
				}
				i = min(r-1, i - 1);
			}
		} while (sum);
		char ans = slove(copy, n);
		printf("%c\n",ans);
	}
	return 0;
}

 

以下是一份实现已知命题公式真值表的 C 代码: ```c #include <stdio.h> #include <stdbool.h> #include <math.h> #define MAX_N 4 int n; char formula[100]; bool values[MAX_N]; int get_value(char c) { return c - 'A'; } bool calculate(bool a, bool b, char op) { switch (op) { case '+': return a || b; case '^': return a && b; case '>': return !a || b; case '-': return a == b; case '!': return !a; } return false; } bool evaluate(int pos, int end) { if (pos == end) { return values[get_value(formula[pos])]; } if (formula[pos] == '!') { return !evaluate(pos + 1, end); } int depth = 0; bool a, b; for (int i = pos; i <= end; i++) { if (formula[i] == '(') depth++; else if (formula[i] == ')') depth--; else if (depth == 0 && (formula[i] == '+' || formula[i] == '^' || formula[i] == '>' || formula[i] == '-')) { a = evaluate(pos, i - 1); b = evaluate(i + 1, end); return calculate(a, b, formula[i]); } } return evaluate(pos + 1, end - 1); } void print_table() { int rows = (int)pow(2, n); printf("|"); for (int i = 0; i < n; i++) { printf(" %c |", 'A' + i); } printf(" %s |\n", formula); for (int i = 0; i < rows; i++) { for (int j = 0; j < n; j++) { values[j] = (i >> (n - j - 1)) & 1; printf("| %c |", values[j] ? 'T' : 'F'); } printf(" %c |\n", evaluate(0, strlen(formula) - 1) ? 'T' : 'F'); } } int main() { scanf("%d", &n); scanf("%s", formula); print_table(); return 0; } ``` 该代码使用递归方法计算命题公式的真值。首先,根据公式中的每个命题符号,生成一个二进制数列,以列的形式输出真值表。然后,对于每一行,根据二进制数列设置命题符号的真值,并计算整个公式的真值,最后以行的形式输出。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值