关于离散数学的真值表的求解

 //寒假,离散老师说,把几个程序实现一下。但是在家里都没怎么去看。花了点时间结束。

思路:

1、求解最后的真值,一般可以用栈,二叉树,当然还有其他方法。(可以参考:http://www.cnblogs.com/U2USoft/archive/2009/03/26/1422545.html

 

2、个人觉得麻烦的地方是,模拟离散数学中的真值表计算的过程。它并不是从左到右直接计算的。而是按照层次。优先级高的先计算,然后计算次优先级的,直到计算完整个表达式。模拟的程序要求输出每层运算的结果。

      离散数学书上,真值表计算具体步骤要求如下:

a,找出公式中的所含的全体命题变量,列出2^n个赋值

b,按从高到低的顺序写出公式的各个层次;

c,对应各个赋值计算出各个层次的真值,直到计算公式的真值

 

下面有个程序输出的例子。(打印的输出暂默认>为->)_______________________________________________
 请输入逻辑表达式,回车结束...
^(p->q)&q&r
真值表如下:
________________________________________________
 p q r      p>q   ^(p>q) (^(p>q)&q) ((^(p>q)&q)&r)
 0 0 0        1        0        0        0
 0 0 1        1        0        0        0
 0 1 0        1        0        0        0
 0 1 1        1        0        0        0
 1 0 0        0        1        0        0
 1 0 1        0        1        0        0
 1 1 0        1        0        0        0
 1 1 1        1        0        0        0
________________________________________________
 要继续计算? (y:是 n:否)
你的选择:

 解决关键:

      主要要找到每层的每个子命题(子公式),然后依次计算保存。

     建立表达式二叉树,从树节点的深度(这里的叶子节点的深度最小)就可以知道它的层次,按树节点的深度从小到大选择树节点,依次计算这个深度下的所有树节点及其一下的节点构成的命题。这样就保证“层次”计算的要求。保存的每个表头,就是子命题公式(如^(p>q))。从表达式树回到表达式时要注意括号和^。最后打印就可以啦。此外打印时候,注意对齐方式。

      本来是想每个子命题的运算完后,接着利用其计算结果继续计算大一点的子命题,以此扩展到整个明天的计算,但是好像有点烦,就放弃了。还是采用重复计算。

下面是一个真值表类的头文件: 

[code=C++]

 

/////////////////////////////////////////////////////////////////////

// filename:        truth_table.h

// Author         feng02

// purpose:         真值表类以及实现

//                  用于将输入的公式命题在所有的赋值情况列成表

//                  包括的联结词有()&|^-><->;

// Main functions:  SubStr,Evaluate,CreateExprBinTree           

// Edition:         *V3[2010/3/22]      V1[2010/3/3] V2[2010/3/13]

// modification :   1、修改添加函数,实现真值表的每层运算的输出

//                  2、修改了函数的参数,便于重用

// References     参考计算器程序,写了计算部分

// to be improved:  1、本函数计算第一层时,只要是第一层就直接读入计算,

//                      没有优先级,如^pp&q没有优先之分

//                  2、最后的真值表输入格式有待改善

//                  3、已经是二叉树就可以直接中序带入计算了;

//                      但是本程序之前使用栈,所以还是化成表达式后用栈计算

//                  4、程序效率和其他。

/////////////////////////////////////////////////////////////////////

 

#include

#include

#include          

#include "BinaryTree.h"

#define MAXLIST 32          //charnum的最大值

#define MAXLENTH 500        //(输入的表达式重新变成表达式后的最大长度)

using namespace std;

 

class TRUTH_TABLE

{

public :

    TRUTH_TABLE(BinTreeNode<char>*p);   //构造函数

    ~TRUTH_TABLE();                     //析构函数

    bool Run();                         //公共函数:提供一次完整的真值表计算

 

private:

    void CreateExprBinTree(BinTreeNode<char> *&root,char exprstr[]);//建立表达式二叉树

    int GetLeftPri(char c);                                 //得到左逻辑符号的优先级

    int GetRightPri(char c);                                //得到右逻辑符号的优先级

    bool IsOpr(char c);                                     //判断c是否为种联结词之一

    void GetEprStr(char exprstr[]);                         //完成输入和保存exprstr,并去除空白字符' '

    bool ChangeSign(char exprstr[]);                        //->转换为>,<->转换为*,判断是否存在字符

    bool ChangeSubStr(BinTreeNode<char>* t,char str[], int &ipos);//将表达式二叉树重新转换成带括号表达式

    void SetTruthList();                                    //按字母顺序设定truthlist的1,0值            

    int GetCharNum(char expstr[]);                          //计算并返回表达式中的命题变量(即不同字母)的个数

    int GetChar2Num(char num, int times);                   //char(p,q,r)转换成1,0

    int OperateNum(int rnum, char theta, int lnum );        //计算rnum theta lnum并返回结果

    void SubStr(BinTreeNode<char> *root);                   //寻找并计算每层的命题(子命题) 

    void Evaluate(char charnum, char exprstr[],int *&truthanswerlist);//对给定的命题或子命题计算逻辑运算结果

    void ShowLastList();                                    //显示最后的逻辑运算结果

 

private:

    BinTreeNode<char> *root;            //根节点

    CBinTree <char> *ptree;             //表达式二叉树

    int charnum;                        //不同字母的个数

    int substrnum;                      //子表达式(表头)的个数

    char charlist[MAXLIST];             //字母列表

    char exprstr[MAXLENTH];             //char保存输入的表达式

    int *truthlist;                     //字母不同赋值列表

    int *truthanswerlist[MAXLENTH];     //对应的真值表结果列表

    char *substrlist[MAXLENTH];         //相应的子命题

};

[/code]

你可能感兴趣的:(离散数学)