使用C语言实现,利用了堆栈的数据结构。为了避免拿来即用,主函数不全。希望能帮到真正需要的同学。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define msize 50
typedef struct stack{
int top;
int maxSize;
char *element;
}Stack;
/*函数功能:初始化堆栈
函数参数:堆栈的地址
函数返回值:ERROR表示初始化失败,OK表示初始化成功
*/
void CreateStack(Stack *s)
{
s->maxSize=msize;
s->element=(char *)malloc(sizeof(char)*msize);
s->top=-1;
}
/*函数功能:判断堆栈是否为空
函数参数:堆栈的地址
函数返回值:返回1表示堆栈空,返回0表示堆栈非空
*/
int IsEmpty(Stack *s)
{
return s->top==-1;
}
/*函数功能:判断堆栈是否已满
函数参数:堆栈的地址
函数返回值:返回1表示堆栈已满,返回0表示堆栈未满
*/
int IsFull(Stack *s)
{
return s->top==s->maxSize-1;
}
/*函数功能:获取栈顶元素的值
函数参数:堆栈的地址
函数返回值:栈顶元素
*/
char TopElem(Stack *s)
{
if(IsEmpty(s))
return '\0';
return s->element[s->top];
}
/*函数功能:向栈中输入元素
函数参数:堆栈的地址,新栈顶元素的值
函数返回值:返回1表示输入成功,返回0表示输入失败
*/
int Push(Stack *s,char x)
{
if(IsFull(s))
return 0;
s->top++;
s->element[s->top]=x;
return 1;
}
/*函数功能:删除栈顶元素
函数参数:堆栈的地址
函数返回值:返回1表示删除成功,返回0表示删除失败
*/
int Pop(Stack *s)
{
if(IsEmpty(s))
return 0;
s->top--;
return 1;
}
/*函数功能:清空栈中元素
函数参数:堆栈的地址
函数返回值:无
*/
void Clear(Stack *s)
{
s->top=-1;
}
/*函数功能:检查输入的式子是否有非法字符
函数参数:字符指针
函数返回值:返回1表示式子合法,返回0表示式子非法
*/
int IsLegal(char *s)
{
int i=0;
char c;
if(strlen(s)>50)
return 0;
for(;i<strlen(s);i++){
c=s[i];
if(!((c>='A'&&c<='Z')||c=='!'||c=='&'||c=='|'
||c=='>'||c=='='||c=='('||c==')' ))
return 0;
}
return 1;
}
/*函数功能:获取某个运算符的栈外优先级
函数参数:字符变量
函数返回值:该字符变量的栈外优先级
*/
int ICP(char c)
{
if(c=='(')
return 4;
else if(c=='!')
return 3;
else if(c==')')
return 1;
else if(c=='#')
return 0;
else
return 2;
}
/*函数功能:获取某个运算符的栈内优先级
函数参数:字符变量
函数返回值:该字符变量的栈内优先级
*/
int ISP(char c)
{
if(c=='(')
return 1;
else if(c=='!')
return 3;
else if(c==')')
return 4;
else if(c=='#')
return 0;
else
return 2;
}
/*函数功能:将输入的式子元素通过栈转化为后缀表达式
函数参数:两个字符指针
函数返回值:无
*/
void ToPostfix(char *infix,char *postfix)
{
int i,j;
Stack s;
CreateStack(&s);
Push(&s,'#');
j=0;
for(i=0;i<strlen(infix);i++){
if(infix[i]>='A'&&infix[i]<='Z')
postfix[j++]=infix[i];/*如果是操作数则直接输出*/
else if(infix[i]==')'){ /*如果是左括号则连续出栈直到栈顶为右括号*/
while(TopElem(&s)!='('){
postfix[j++]=TopElem(&s);
Pop(&s);
}
Pop(&s);
}
else if(ICP(infix[i])<=ISP(TopElem(&s))){ /*如果操作符优先级小于栈顶元素优先级,则连续出栈直到大于,并将操作符入栈*/
while(ICP(infix[i])<=ISP(TopElem(&s))&&ISP(TopElem(&s))!=0){
postfix[j++]=TopElem(&s);
Pop(&s);
}
Push(&s,infix[i]);
}
else
Push(&s,infix[i]);/*如果操作符优先级大于栈顶元素,则直接入栈*/
}
Clear(&s);
}
/*函数功能:检查某个变量是否重复出现
函数参数:字符指针
函数返回值:返回1说明重复,返回0说明不重复
*/
int IsRepeat(char *str,char c)
{
int i=0;
for(;i<strlen(str);i++)
if(str[i]==c)
return 1;
return 0;
}
/*函数功能:计算表达式中的变元个数,同时打印这些变元
函数参数:字符指针,整形指针
函数返回值:字符指针的地址
*/
char* GetVariable(char *fix,int *n)
{
char *temp=(char *)malloc(sizeof(char)*20);
int i=0;
int j=0;
for(;i<strlen(fix);i++)
if(fix[i]>='A'&&fix[i]<='Z'&&IsRepeat(temp,fix[i])!=1)
temp[j++]=fix[i];
printf(" 对应真值表\n");
for(i=0;i<j;i++)
printf(" %c ",temp[i]);
*n=j;
return temp;
}
/*函数功能:根据变元个数生成真值表
函数参数:二维数组首地址,变元个数
函数返回值:无
*/
void CreateTrueList(char **t,int n)
{
int i=0;
int j=0;
int k=0;
int row=pow(2,n);
int col=n;
for(;i<n;i++)
for(j=0;j<row-1;j+=pow(2,n-i-1)){
for(k=j;k<j+pow(2,n-i-1);k++)
t[k][i]='T';
j=k;
}
}
/*函数功能:初始化真值表全为F
函数参数:二维数组首地址,变元个数
函数返回值:二维数组首地址
*/
char ** IniTrueList(char **t,int n)
{
int i=0;
int row=pow(2,n);
int col=n;
int j=0;
t=(char **)malloc(sizeof(char *)*row);/*创建长为2^n次方的指针数组*/
for(;i<row;i++){
t[i]=(char *)malloc(sizeof(char)*(n+1));
}
for(i=0;i<row;i++)
for(j=0;j<col;j++)
t[i][j]='F';
return t;
}
/*函数功能:打印真值表
函数参数:二维数组首地址,变元个数
函数返回值:无
*/
void PrintTrueList(char **t,int n)
{
int i=0;
int j=0;
for(;i<pow(2,n);i++){
for(j=0;j<n+1;j++)
printf(" %c ",t[i][j]);
printf("\n");
}
}
/*函数功能:将变元的真值代入后缀表达式中
函数参数:指向二维真值表行的一级指针,待赋值的后缀表达式、变元数
函数返回值:无
*/
void TrueListAssign(char *t,char *postfix,int n)
{
int i=0;
int count=0;
char a[101]={0};
for(i=0;postfix[i]!='\0';i++)
if(!IsRepeat(a,postfix[i])&&postfix[i]>='A'&&postfix[i]<='Z'){
a[count]=postfix[i];
count+=2;
}
count=0;
for(i=1;count<n;i+=2){
a[i]=t[count++];
}
for(i=0;i<2*n;i+=2)
for(count=0;postfix[count]!=0;count++)
if(postfix[count]==a[i])
postfix[count]=a[i+1];
}
/*函数功能:根据后缀表达式的操作符,来对已入栈的操作数进行计算
函数参数:栈,后缀表达式
函数返回值:无
*/
void Operation(Stack *s,char op)
{
char a=0,b=0;
if(op=='!')
if(TopElem(s)=='T'){
Pop(s);
Push(s,'F');
return ;
}
else{
Pop(s);
Push(s,'T');
return ;
}
if(op=='&'){
a=TopElem(s);
Pop(s);
b=TopElem(s);
Pop(s);
if(a=='T'&&b=='T')
Push(s,'T');
else
Push(s,'F');
return ;
}
if(op=='|'){
a=TopElem(s);
Pop(s);
b=TopElem(s);
Pop(s);
if(a=='F'&&b=='F')
Push(s,'F');
else
Push(s,'T');
return ;
}
if(op=='>'){
a=TopElem(s);
Pop(s);
b=TopElem(s);
Pop(s);
if(a=='F'&&b=='T')
Push(s,'F');
else
Push(s,'T');
return ;
}
if(op=='='){
a=TopElem(s);
Pop(s);
b=TopElem(s);
Pop(s);
if((a=='T'&&b=='T')||(a=='F'&&a=='F'))
Push(s,'T');
else
Push(s,'F');
return ;
}
}
/*函数功能:根据后缀表达式计算真值情况,并将结果存储在真值表中
函数参数:二维数组,后缀表达式
函数返回值:无
*/
void CalcuPostfix(char *postfix,char **t,int n)
{
Stack s;
int i=0;
int j=0;
char temp[50]={0};
for(i=0;i<strlen(postfix);i++)
temp[i]=postfix[i];
CreateStack(&s);
for(i=0;i<pow(2,n);i++){
TrueListAssign(t[i],postfix,n);/*把第i行真值表中变元的值代入后缀表达式中*/
for(j=0;postfix[j]!='\0';j++)
if(postfix[j]=='T'||postfix[j]=='F')/*如果是变元,则直接入栈*/
Push(&s,postfix[j]);
else
Operation(&s,postfix[j]);/*如果是联结词,则对栈内元素进行运算*/
t[i][n]=TopElem(&s);/*将运算结果储存在真值表中*/
strcpy(postfix,temp);
Pop(&s);
}
}
/*函数功能:打印主析取范式
函数参数:真值表,变元表,变元数目
函数返回值:无
*/
void PrintPDNF(char **t,char *v,int n)
{
int i=0;
int j=0;
int count=0;
printf("主析取范式为:");
for(;i<pow(2,n);i++)
if(t[i][n]=='T'){
printf("(");
for(j=0;j<n;j++){
if(t[i][j]=='T')
printf("%c",v[j]);
else
printf("!%c",v[j]);
if(j!=n-1)printf("∧");
}
printf(")");
count++;
if(count!=pow(2,n-1))
printf("∨");
}
printf("\n");
}
/*函数功能:打印主合取范式
函数参数:真值表,变元表,变元数目
函数返回值:无
*/
void PrintPCNF(char **t,char *v,int n)
{
int i=0;
int j=0;
int count=0;
printf("主合取范式为:");
for(;i<pow(2,n);i++)
if(t[i][n]=='F'){
printf("(");
for(j=0;j<n;j++){
if(t[i][j]=='F')
printf("%c",v[j]);
else
printf("!%c",v[j]);
if(j!=n-1)printf("∨");
}
printf(")");
count++;
if(count!=pow(2,n-1))
printf("∧");
}
printf("\n");
}
/*函数功能:用于重新输入前清空字符串
函数参数:字符指针
函数返回值:无
*/
void ClearString(char *s)
{
int i=0;
while(s[i]!='\0')
s[i++]='\0';
}
int main()
{
char a[51]={0};
char b[51]={0};
int n=0;
char *variable=NULL;
char **TrueList=NULL;
gets(a);
a[strlen(a)]='#';
variable=GetVariable(a,&n);
TrueList=IniTrueList(TrueList,n);
CreateTrueList(TrueList,n);
ToPostfix(a,b);
a[strlen(a)-1]='\0';
printf("%s \n",a);
CalcuPostfix(b,TrueList,n);
PrintTrueList(TrueList,n);
PrintPDNF(TrueList,variable,n);
PrintPCNF(TrueList,variable,n);
printf("按任意键结束程序....");
getchar();
return 0;
}
有问题可以私信我哦。