题目要求
对给出的任意一个合式公式(不超过四个命题变元),用程序编程表示出来,能够计算它在各组真值指派下所应有的真值,画出其真值表,并输出构成主析取范式的所有小项。涉及的运算符包括∧(&),∨(|),¬(!),→(−>),↔(<−>)五种运算符,对于无法由键盘输入的运算符,可以使用括号内的符号代替。例如输入:
(?⟶?)∨?
难度:较难
说明:
a) 能支持1-4个变元
b) 能支持1-4次逻辑运算
c) 人机交互友好,排版美观
IDE:Microsoft Visual C++ 6.0
代码:

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
#define MAXSIZE 40
typedef char elemtype;
char str[40],st[40],st1[40],st2[40];
int table1[16][5];
int flag=1;
/*str接收输入的字符,st是转化后的字符,
st1储存变量,st2变量转化为相应公式;
table1储存真值表*/
/*
数据结构自己学的,然后写后缀表达式时一直提示一些符号没有
然后我猜想是头文件没有,但是网上找了好多,都不对
于是我就对着买的书,把这些定义全部打上了。*/
typedef struct              //  定义栈结构
{   elemtype date[MAXSIZE];int top;
}SqStack;
void InitStack(SqStack *&s)         //初始化栈
{s=(SqStack * ) malloc(sizeof(SqStack));s->top=-1;
}
void DestoryStack(SqStack *&s)          //销毁栈
{free(s);
}
bool StackEmpty(SqStack *s)         //判断栈是否为空
{return(s->top==-1);
}
bool Push(SqStack *&s, elemtype e)          //入栈
{if(s->top==MAXSIZE-1)return false;s->top++;s->date[s->top]=e;return true;
}
bool Pop(SqStack *&s,elemtype &e)       //出栈
{if(s->top==-1)return false;e=s->date[s->top];s->top--;return true;
}
bool GetTop(SqStack *s,elemtype &e)         //取栈顶元素
{if(s->top==-1)return false;e=s->date[s->top];return true;
}
int calFun(char st2[])      //  计算后缀表达式
{SqStack *S;            //定义栈int i=0;char x,x1,x2;InitStack(S);            //初始化栈while (st2[i]!='\0'){switch(st2[i]){case'&':             //计算析取Pop(S, x2);Pop(S, x1);x=(x1-'0')&&(x2-'0');Push(S,(x+'0'));i++; break;case'|':            //计算合取Pop(S, x2);Pop(S, x1);x=(x1-'0')||(x2-'0');Push(S,(x+'0'));i++; break;case'-':            //计算条件Pop(S, x2);Pop(S, x1);x=!(x1-'0')||(x2-'0');Push(S,(x+'0'));i++; break;case'=':      //计算双条件Pop(S, x2);Pop(S, x1);x=(x1-'0')==(x2-'0');Push(S,(x+'0'));i++; break;case'~':         //计算否定Pop(S,x1);x=!(x1-'0');Push(S,(x+'0'));i++; break;default:         while(st2[i]=='1'||st2[i]=='0'){Push(S,st2[i]);i++;}}}GetTop(S,x);            //取栈顶元素,即合式公式真值DestoryStack(S);      //销毁栈return (int)(x-'0');     //返回真值
}void suffix(char *z,char st2[])        //  将中缀表达式转化为后缀表达式
{                                   char e;SqStack *Optr;           //定义栈InitStack(Optr);       //初始化栈int i=0;while(*z!='\0')           {switch(*z){case'(':                  //左括号Push(Optr,'(');z++;break;case')':                    //右括号Pop(Optr,e);while(e!='('){st2[i++]=e;Pop(Optr,e);}z++;break;case'-':                     //条件和双条件case'=':while(!StackEmpty(Optr)){GetTop(Optr,e);if(e!='('){st2[i++]=e;Pop(Optr,e);}elsebreak;}Push(Optr,*z);z++;break;case'&':case'|':                   //合取和析取while(!StackEmpty(Optr)){GetTop(Optr,e);if(e!='('&&e!='-'&&e!='='){st2[i++]=e;Pop(Optr,e);}elsebreak;}Push(Optr,*z);z++;break;case'!':              //否定while(!StackEmpty(Optr)){GetTop(Optr,e);if(e!='!'){st2[i++]=e;Pop(Optr,e);}elsebreak;}Push(Optr,*z);z++;break;default:              //对应真值while(*z=='0'||*z=='1'){st2[i++]=*z;z++;}//st2[i++]='#';            //我不知道这行有什么用,书上有,我加上后运行不了}}while(!StackEmpty(Optr))       {Pop(Optr,e);st2[i++]=e;             //出栈}st2[i]='\0';            //给st2加上结束符DestoryStack(Optr);          //销毁栈
}void disjunctiveFun(int table1[][5],int h,int num)
{int i,j;printf("主析取范式小项为:\n");           //如果合式公式真值为1就打印for(i=0;i<h;i++){  if(table1[i][num]==1){for(j=0;j<num;j++){   //printf("%d",table1[i][j]);if(table1[i][j]==0)             //对应字母为0,加!printf("%c",'!');printf("%c",st1[j]);if(j!=num-1)                  //加个&printf("%c",'&');}printf("\n");} }
}
void trueTable(char st[],int num)       //打印真值表
{int h,i,j,k;int a;int table[40];char z[40];h=(int)pow(2,num);     //计算真值表的行数for(i=0;i<num;i++){printf("%c\t", st1[i]);}printf("%s\n",str);strcpy(z,st);for(i=0;i<h;i++){  strcpy(z,st);for(j=0;j<num;j++){table[j]=(i/(int)pow(2,j)%2);        //真值表赋值printf("%d\t", table[j]);table1[i][j]=table[j];           //储存真值}for(k=0;z[k]!='\0';k++)        //将字母转化为对应真值{for(j=0;st1[j]!='\0';j++){if(z[k]==st1[j]){z[k]=table[j]+'0';          //弄了好长时间,char不能储存int}}}suffix(z,st2);            //转化为后缀表达式//    printf("%s",st2);a=calFun(st2);          //计算后缀表达式printf("%d\n",a);//  printf("%s\n",z);table1[i][num]=a;       //合适公式真值储存}disjunctiveFun(table1,h,num);        //调用打印主析取范式函数
}
int judgeNum(char st[])     //判断变量个数是否正确并且提取字母
{int i,j,k=0,num=0 ;for(i=0;st[i]!='\0';i++){if(st[i]>='A'&&st[i]<='Z'){    for(j=0;j<i;j++){if(st[j]==st[i])break ;}if(i==j){st1[k++]=st[i];      //将字母存放到数组st1中num++ ; }   }}if(num>=1&&num<=4);else{  flag=0;}return num;
}
void judgeSymbol(char st[])     //判断符号是否输入正确
{int i,j,num;char s0[40];strcpy(s0,st);for(i=0;s0[i]!='\0';i++)           //先把括号移除{if(s0[i]=='(') for(j=i;s0[j]!='\0';j++)s0[j]=s0[j+1];if(s0[i]==')')for(j=i;s0[j]!='\0';j++)s0[j]=s0[j+1];}for(i=0;s0[i+1]!='\0';i++)        //判断字母是否连着字母{if(s0[i]>='A'&&s0[i]<='Z'){if(s0[i+1]=='&'||s0[i+1]=='|'||s0[i+1]=='-'||s0[i+1]=='=');else{flag=0;break;}}if(s0[i]=='!')     //判断!后跟的是不是字母{if(s0[i+1]>='A'&&s0[i+1]<='Z');else{flag=0;break;}}if(s0[i]=='&'||s0[i]=='|'||s0[i]=='-'||s0[i]=='=')      //判断符号后跟的是不是字母{if(s0[i+1]>='A'&&s0[i+1]>='Z'||s0[i+1]!='!');else{flag=0;break;}}}if(flag==1)num=judgeNum(st);     //判断变量个数并且返回值if(flag==1)trueTable(st,num);else printf("合式公式错误!\n");}
void judgeParentheses(char st[])        //判断括号匹配是否正确
{int i,left,right;      left=0;right=0;for(i=0;st[i]!='\0';i++){    if(st[i]=='(')left++;if(st[i]==')')right++;if(left>right+1||left+1<right)break;}if(left!=right){flag=0;}else judgeSymbol(st);     //调用判断符号是否正确}
void transform(char st[])       //把条件和双条件转化为-和=表示
{int i,j;for(i=0;st[i]!='\0';i++)     //把双条件转化为={if(st[i]=='<'){st[i]='=';if(st[i+2]!='\0')for(j=i;st[j]!='\0';j++)st[++i]=st[i+2];else if(st[i+2]=='\0')st[++i]='\0';}}for(i=0;st[i]!='\0';i++)        //把条件转化为-{if(st[i]=='-'){if(st[i+1]!='\0')for(j=i;st[j]!='\0';j++)st[++i]=st[i+1];else if(st[i+2]=='\0')st[++i]='\0';}}
}
void main()
{while(1){      //循环运行printf("请输入1-4变元的一个合式公式:\n");printf("仅支持大写英文字母的变元!\n");printf("合取(&),析取(|),否定(!),条件(->),双条件 (<->):\n");gets(str);strcpy(st,str);transform(st);     //调用转化函数judgeParentheses(st);       //调用判断函数system("pause");  //  按一下继续system("cls");       //清屏}
}

感想:转专业来到物联网学院,因为转专业需要补修大一课程的原因,打乱了自己的课表,和物联网不同的班级上课,发现每个班的优秀的同学都好多的,感觉自己大一像是玩了一样,而他们却学课外的知识,什么Python、java、单片机、MySQL等等。
这次离散数学大作业,感觉内容还好吧,虽然对我来说有点吃力,没系统的学过数据结构,C语言主要内容学完的情况下,能够完成感觉自己还是不错的。上课课程其他地方没有落下,就是某些算法,耦合度等关键词,因为数据结构没上,了解的也不是很多。只能大二下再补课。
写完这次大作业之后,感觉写其他的程序代码也不是很长。首先,克服了感觉自己代码输长了就闲麻烦,或者感觉输入的不正确。其次,为以后打程序打下了一个比较良好的基础。

离散数学大作业代码及感想相关推荐

  1. 数据库大作业代码展示2

    因为上个界面实在是太卡了,尤其在c#代码里,打字都是延缓的,所以分开来展示. 这一个主要是管理员界面的介绍,窗口调用如下: ManageMain窗口:(管理员主界面)省略代码和前文一样, (学生管理) ...

  2. 魔兽世界(三):开战 北京大学慕课C++大作业 代码与思路

    类的组织 总体思路: 自底向上为:Weapon -> Warrior -> HeadQuarter | City -> main函数 每个司令部含有一个Warrior的vector, ...

  3. python大作业代码_大二期末python大作业有效代码不低于5000行是什么水平?

    6月30日更新 鉴于题主说老师已经收回对行数的要求,就请大家看过则罢,不要再点赞了(还有收藏的是什么鬼?).本文说的不过是一些投机取巧的伎俩,不值取,不可取. ~~~以下是原文~~~: 一个熟练工程序 ...

  4. python大作业代码_爬虫大作业(示例代码)

    1.选一个自己感兴趣的主题(所有人不能雷同). 每天都有接触各大平台推送的新闻,了解到了校园外的大小事.故此,对新浪新闻标题的关键字的爬取,看看最近发生的实时,也想比较下标题党还是和实际内容的差异. ...

  5. 数据库大作业代码展示1

    SQL server中的一些操作,贴图可能更加直观一些: Course表: DetailedCourse表: SC表: Studetn表: SysLog表: SysManage表: SysUser表: ...

  6. 离散数学大作业——C++实现集合的基本运算

    项目描述:可以实现从键盘输入集合,可以实现两个集合求解交集.差集.并集.补集.对称差等基本运算.运行后的界面如下所示: 程序源代码如下: #include<iostream> #inclu ...

  7. 模式识别大作业-代码

    数据增强 数据处理 #将文件下的图片处理成的数据,保存在Dataframe中 import glob import numpy as np import pandas as pd import cv2 ...

  8. HTML网页大作业代码【免费代码已上传】

  9. 网页大作业代码自取【HTML+CSS制作美味糖果网站】

  10. 课程项目:大学程序设计相关大作业汇总参考及源码地址

    C++程序设计 利用C++实现的小游戏:2048,俄罗斯方块和贪吃蛇[Some small games implemented in C++: 2048, Tetris and Snake (Univ ...

最新文章

  1. 摄像头定位:ICCV2019论文解析
  2. 银行背景下分库分表技术选型
  3. uc3842开关电源电路图_UC3842构成的开关电源电路
  4. 关于CSS中的字体尺寸设置 em rem等
  5. 不具有继承关系的Delegate如何进行类型转换?
  6. 论文浅尝 - ICLR2021 | 从信息论的角度提高语言模型的鲁棒性
  7. 5.1.4 SELECT+RIGHT JOIN读取数据
  8. 解决 An invalid domain was specified for this cookie
  9. 怎样改动、扩展并重写Magento代码
  10. C++ 引用的几个用法
  11. python3.5 3.6_centos7安装较高版本python3.5/3.6
  12. 网站的pv、uv、ip分别是什么意思
  13. windows2003序列号
  14. TikTok如何玩转语言教学类目?
  15. css绘制一个Pinia小菠萝
  16. Altium Designer--如何添加泪滴
  17. uva-1600 巡逻机器人
  18. Materials - 角色分层材质规范
  19. python网络编程 赵宏_2018年Python爱好者社区历史文章合集(作者篇)
  20. 利用unicode字符rlo

热门文章

  1. 计算机辅助翻译 教学大纲,计算机辅助翻译本科课程教学大纲翻译本科.doc
  2. 局域网不同网段远程桌面_自动化已非原来的自动化:看虚拟局域网技术应用到罗克韦尔的DCS...
  3. C#程序员整理的Unity 3D笔记(十三):Unity 3D基于组件的思想
  4. 华为网关服务器型号,02311CWM CN21ITGC SP212 I350-T4 华为服务器四口千兆网卡
  5. 分区表修复工具--DISKFIX
  6. visio 取消跨线
  7. 202102 sqlplus command not found 注意切换用户
  8. Cool Edit Pro软件介绍
  9. visual studio 2012 密钥
  10. java中滚动字幕做法_四种滚动字幕的方法