c语言打印真值表
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include
#include
#include
#include
#include
/*
(1) '!'表示否定
(2) '&'表示合取
(3) '|'表示析取
(4) '>'表示条件
(5) '='表示双条件
*/
struct Stack
{
char *base;
char *top;
int stacksize;
};
struct Room//建立一个比较大的结构体,用于储存字母,和字母所对应的真值
{
char ch;
char value;
}value[10];
void Move(char (*str)[50],int pace,int left)//横向移动字符串
{
int i;
str[0][left]='A';
for(i=left+1 ; i
str[0][i]=str[0][i+pace];
str[1][i]=str[1][i+pace];
}
str[0][i]=0;
str[1][i]=0;
return ;
}
bool IsConnect(char ch)
{
if((ch == '!') || (ch == '&') || (ch == '|') || (ch == '>') || (ch == '='))
return true;
else
return false;
}
void IsFormula(char (*str)[50])//关键函数判断 len>=3 的情况
{
int i,j,k;//辅助变量
int left = 0,right =0;
for(i=0;i
if(str[1][i] == 1)
{
left=i;
}
if(str[1][i] == 2)
{
right=i;
break;
}
}
str[1][left]=0;//用完 right 和 left 之后将其标记为0
str[1][right]=0;
k=right-left;
for(j=1;j<=k;j++)
{
if( ( str[0][left+j] =='!' && (IsConnect(str[0][left+j-1]) || str[0][left+j-1] =='(' ) && isalpha(str[0][left+j+1]) ) //'!'的左边为连接符或者'(',右边一定为A
|| ( isalpha(str[0][left+j]) && ( IsConnect(str[0][left+j-1]) || isalpha(str[0][left+j-1]) || str[0][left+j-1] =='(') && ( IsConnect(str[0][left+j+1]) || str[0][left+j+1] ==')')) //'A'的右边为连接符,或者'!',或者'(',右边为连接符或者右括号
|| ( IsConnect(str[0][left+j]) && isalpha(str[0][left+j-1]) && ( str[0][left+j+1] =='!' || isalpha(str[0][left+j+1])))) //连接符的左边为A,右边为非或者A
continue;
else
break;
}
if(j==k)
{
Move(str,k,left);
}
if(right == strlen(str[0])-1)
return ;
else
IsFormula(str);
}
bool CheckFormula(char *str1)
{
char str[2][50];//定义2行数组,str[0]存放字符串,str[1]做标记
int l=0,r=0;//l记录左括号的个数,r记录右括号的个数
int i;//辅助变量
int len=strlen(str[0]);
str[0][0]='(';//去空格,且在str[0]的外层加上括号,此时len>=2
i=1;
while( *str1 != '\0' )
{
if(*str1 != ' ')
{
str[0][i] = *str1;
i++;
}
str1++;
}
str[0][i]=')';
str[0][i+1]='\0';
if(len == 2)//当字符串为空的情况,即为()的情况
return false;
else
for(i=0;i< len ;i++)//判断所有的括号是否配对,且将'('标记为1,将')'标记为2
{
if(str[0][i] == '(')
{
str[1][i]=1;
l++;
}
if(str[0][i] == ')')
{
str[1][i]=2;
r++;
}
}
if( l==r )
{
IsFormula(str);
if(str[0][0] == 'A')
return true;
else
return false;
}
else
return false;
}
int RuleOperation(char ch)
{
switch(ch)
{
case '#':
return -1;
case '(':
return 0;
case '=':
return 1;
case '>':
return 2;
case '|':
return 3;
case '&':
return 4;
case '!':
return 5;
}
}
char Calculate(char x,char y,char ch)//计算合取,析取,条件,双条件
{
int p,q,c;
p=x-48;
q=y-48;
switch(ch)
{
case '&':
c=p&&q;
break;
case '|':
c=p||q;
break;
case '>':
c=!p||q;
break;
case '=':
c=(p && q)||(!p && !q);
break;
}
return c+48;
}
char LogicNo(char ch)
{
int p=ch-48;
return !p+48;
}
bool IsNum(char ch)
{
if( ch >= '0' && ch <= '9')
return true;
else
return false;
}
bool IsOperation(char ch)
{
if( ch == '&' || ch == '|' || ch == '>' || ch == '=' )
return true;
else
return false;
}
void push(Stack *s,char c)//栈的压入
{
if(s->top - s->base == s->stacksize)//如果 栈顶-栈低=栈长,则表明栈溢出,需要重新申请栈储存空间
{
printf("OverFlow\n");
exit(0);
}
*(s->top++) = c;//元素入栈,栈顶的指针+1
}
void pop(Stack *s,char *c)
{
if(s->base == s->top) //如果top==base,则表明栈空
return ;
*c = *(--s->top);//将顶元素储存如c,栈顶指针-1,并返回
}
int CalculateFormula(char *arr)
{
Stack s;//s操作符栈
int len,i,j;
char e;
char str[50];//后缀式的字符串
s.base=(char *)malloc(20*sizeof(char));//新建操作符栈
s.top=s.base;//空栈
s.stacksize=20;
len =strlen(arr);
arr[len]='#';
arr[len+1]='\0';
push(&s,'#');//先压入#,则栈顶的操作符优先级最小
for(i=0,j=0;i<=len;i++)
{
if(arr[i]=='!')
{
push(&s,arr[i]);
continue;
}
if(arr[i]=='(')
{
push(&s,arr[i]);
continue;
}
if(arr[i]==')')
{
while( *(s.top -1 ) != '(' )
{
pop(&s,&e);
str[j++]=e;
}
pop(&s,&e);
continue;
}
if( IsNum(arr[i]) )//如果是操作数,则直接进入后缀式
{
str[j++]=arr[i];
continue;
}
if(arr[i]=='#')
{
while( s.top-1 != s.base)
{
pop(&s,&e);
str[j++]=e;
}
continue;
}
//若当前字符为运算符且优先级大于栈顶运算符,则进栈,否则退出栈顶运算符并将其发送给后缀式。然后将当前运算符放入栈中。
if( IsOperation(arr[i]) && ( RuleOperation(arr[i]) > RuleOperation( *( s.top -1) ) ) )
{
push(&s,arr[i]);
continue;
}
else
{
pop(&s,&e);
str[j++]=e;
push(&s,arr[i]);
continue;
}
}
str[j]='\0';
//puts(str);
//后缀式的计算
char num1,num2,sum;
len=strlen(str);
for(i=0;i
if( IsNum(str[i]) )
{
push(&s,str[i]);
}
else
{
if(str[i]=='!')
{
pop(&s,&num1);
sum=LogicNo(num1);
push(&s,sum);
}
else
{
pop(&s,&num1);
pop(&s,&num2);
sum=Calculate(num1,num2,str[i]);
push(&s,sum);
}
}
}
pop(&s,&sum);
if(sum=='0')
{
printf("F\t");
}
else
{
prin
tf("T\t");
}
printf("\n");
return 0;
}//计算合式公式
void Binary(int n,int k)//将合式公式的原子命题,化为二进制的相应值,n为输入的值,k为二进至的位数
{
int top;
int x,m=0;
top=0;
while(n)
{
value[top++].value=n%2+48;
n=n/2;
m++;
}
for(int i=0;i
value[top++].value='0';
}
}
int main()
{
char arr[50];
printf("(1) '!'表示否定\n(2) '&'表示合取\n(3) '|'表示析取\n(4) '>'表示条件\n(5) '='表示双条件\n");
printf("请输入一个合式公式:\n");
gets(arr);
if(CheckFormula(arr))
{
char str[50];//用于保存arr字符串
int i,j,k=0;//辅助变量,k用于记录变量的个数
for(i=0;i
for(j=0;j{
if(arr[j]==arr[i])
break;
}
if(j==i && isalpha(arr[i]))//用结构体保存,英文字符
{
value[k++].ch=arr[i];
}
}
for(i=0;i
printf("%c\t",value[i].ch);
}
printf("%s\n",arr);
int n=pow(2.0,k);
for(int m=0;m
strcpy(str,arr);
Binary(m,k);
for(i=0;i
if(value[i].value=='0')
{
printf("F\t");
}
else
{
printf("T\t");
}
}
for(i=0;i
for(j=0;j
if(str[i]==value[j].ch)
{
str[i]=value[j].value;
}
}
}
//将新的字符串,传入函数中计算
CalculateFormula(str);
}
}
else
{
printf("合式公式不合法!\n");
}
return 0;
}