精华内容
下载资源
问答
  • C++实现求命题公式真值表

    千次阅读 2020-03-25 16:52:44
    #include <bits/stdc++.h> using namespace std; #define LMGGTQL #ifdef LMGGTQL #define AND '&' #define OR 'V' #define NOT '!' #define IFF '@' ...inline string CharToString(char c) ...
    #include <bits/stdc++.h>
    using namespace std;
    #define LMGGTQL
    #ifdef LMGGTQL
    #define AND '&'
    #define OR 'V'
    #define NOT '!'
    #define IFF '@'
    #define IF '-'
    inline string CharToString(char c) {
    	string result;
    	result += c;
    	return result;
    }
    set<char> GetVar(const string &s) {
    	set<char> result;
    	for (auto &i : s)
    		if (i != NOT && i != AND && i != OR && i != IF && i != IFF)
    			result.emplace(i);
    	return result;
    }
    string GetEx(const string &input) {
    	string EX;
    	stack<char> st;
    	char top;
    	unordered_map<char, int> f { {NOT,5},{AND,4},{OR,3},{IF,2},{IFF,1} };//运算优先级
    	for (auto &i : input) {
    		switch (i) {
    		case '(': st.push('('); break;
    		case ')':
    			top = st.top();
    			while (top != '(') {
    				EX += top;
    				st.pop();
    				top = st.top();
    			}
    			st.pop();
    			break;
    		case NOT: case AND:
    		case OR:  case IF:
    		case IFF:
    		loop:
    			if (st.empty() || f[i] > f[st.top()]) st.push(i);
    			else {
    				EX += st.top();
    				st.pop(); goto loop;
    			}
    			break;
    		default: EX += i; break;
    		}
    	}
    	while (!st.empty()) {
    		EX += st.top();
    		st.pop();
    	}
    	return EX;
    }
    vector<string> GetName(const string &EX, const set<char> &Var) {
    	string temp;
    	stack<string> st;
    	vector<string> result;
    	for (auto &i : Var) result.emplace_back(temp = i);
    	for (auto c : EX) {
    		if (c == NOT) {
    			temp = "┐ " + st.top();
    			st.pop();
    			st.emplace(temp);
    			result.emplace_back(temp);
    		}
    		else if (c == AND || c == OR || c == IF || c == IFF) {
    			if (c == AND) temp = "∧";
    			else if (c == IF) temp = "→";
    			else if (c == IFF) temp = "↔";
    			else if (c == OR) temp = OR;
    			temp = temp + st.top() + ")"; st.pop();
    			temp = "(" + st.top() + temp; st.pop();
    			st.emplace(temp);
    			result.emplace_back(temp);
    		}
    		else st.emplace(temp = c);
    	}
    	return result;
    }
    bool ReplaceAll(string &str, const string &a1, const string &a2) {
    	auto pos = str.find(a1);
    	if (pos == string::npos) return false;
    	do {
    		str.replace(pos, a1.size(), a2);
    		pos = str.find(a1, a2.size() + pos);
    	} while (pos != string::npos);
    	return true;
    }
    int main() {
    	for (string input, temp; cin >> input;) {
    		ReplaceAll(input, "!", temp = NOT);
    		ReplaceAll(input, "->", temp = IF);
    		ReplaceAll(input, "<->", temp = IFF);
    		string EX = GetEx(input);
    		set<char> Var = GetVar(EX);
    		vector<string> Name = GetName(EX, Var);
    		int END = static_cast< int >(pow(2, Var.size())) - 1;
    		vector<vector<char>> store(END + 1);
    		for (int n = 0, cnt = 0; n <= END; n++, cnt = 0) {
    			stack<char> st;
    			string EXtemp = EX;
    			bitset<100> Btemp(n);
    			for (int j = Var.size() - 1; j >= 0; j--) store[n].emplace_back('0' + Btemp[j]);
    			for (auto &i : Var)	 ReplaceAll(EXtemp, CharToString(i), CharToString(store[n][cnt++]));
    			for (auto &i : EXtemp) {
    				if (isdigit(i))	st.push(i);
    				else if (i == '~') {
    					char top = st.top(); st.pop();
    					char result = top == '0' ? '1' : '0';
    					st.push(result);
    					store[n].push_back(result);
    				}
    				else {
    					char result;
    					char b = st.top(); st.pop();
    					char a = st.top(); st.pop();
    					switch (i) {
    					case AND: result = (a == '1' && b == '1' ? '1' : '0'); break;
    					case OR: result = (a == '1' || b == '1' ? '1' : '0'); break;
    					case IF: result = (a == '1' && b == '0' ? '0' : '1'); break;
    					case IFF: result = (((a == '1' && b == '1') || (a == '0' && b == '0')) ? '1' : '0'); break;
    					}
    					st.push(result);
    					store[n].push_back(result);
    				}
    			}
    		}
    		for (auto &i : Name) printf(" \t%s", i.c_str());
    		putchar('\n');
    		for (int n = 0; n <= END; n++) {
    			for (auto &i : store[n]) printf(" \t%c", i);
    			putchar('\n');
    		}
    	}
    }
    #endif
    
    展开全文
  • [离散] 编程求命题公式真值表

    万次阅读 多人点赞 2017-03-18 09:41:19
    [离散] 编程求命题公式真值表概述 真值表是离散数学中的一个重要概念,由真值表我们能求得任意命题公式的主析取范式和主合取范式。本文将用C语言编写一个任意命题公式真值表的程序

    [离散] 编程求命题公式真值表

    概述

    真值表是离散数学中的一个重要概念,由真值表我们能求得任意命题公式的主析取范式和主合取范式。下面我们先来回顾一下真值表的概念:

    将命题公式A在所有赋值下取值情况列成表,称作A的真值表

    由真值表的定义我们不难得出我们将要做些什么,

    1. 分析命题公式A
    2. 对命题公式进行赋值并求值
    3. 输出真值表

    本文将利用C语言编写一个程序,实现上述过程。

    分析问题

    要求真值表,就必须分析命题公式,将输入的命题公式,如 p&!q|(q>p) ,转化为计算机能理解的对象,方便后续求解。

    :这里用 & 表示合取, 用 | 表示析取,用 > 表示蕴含,用 = 表示等价,表示命题的否定


    人求解的思路

    一个解析命题公式最直接的也是最朴素的想法就是模拟,也就是模拟你是怎么想的,让计算机按照你分析公式的思路进行分析。

    这样,我们就需要仔细想想,我们在分析命题公式,求真值表的时候都在做些什么呢 ?


    :给定如下命题公式((p>q)&(q>r))>(p>r) ,求它的真值表

    读者不妨自己在纸上写下这个公式,然后自己想一想,理清思路


    一个常见的思路

    1. 给定一个赋值,从左到右按顺序求出每个子公式的值,最终得到公式的值
    2. 如,假设 p =1,q = 0, r = 1
    3. 计算p>q 得到 0,计算 q>r得到1,计算p>r得到1
    4. 最后计算 (0 & 1 ) > 1得到1

    我们分析这个思路,会发现,这里3步骤里计算哪个表达式选择往往因人而异,同时现实中很可能根本就是随意选取,这样是不利于计算机实现的。

    如果将第三步限定为从左到右选取,那么这个思路,我们要按顺序解析出每个形如 A[符号]B的命题,还要记下子命题之间的运算符,并且还需要用别的方法,搞清楚我们最后算总命题的顺序。

    不是不能做,也能做,有兴趣的也可以尝试编写对应代码试一试。不过在这里,我要介绍另一种利用递归的方法。


    给出参考思路:

    1. 我们在看到这个公式的时候,首先寻找了优先级最低的符号(即>),然后将这个表达式分成了两份。
    2. 观察分好的表达式,如果是形如A[符号]B的形式 ,则直接计算,如果不是进入下一步。
    3. 对新的子式重复做 步骤1,直到分成的每个子式都最简
    4. 然后按顺序反回去计算整个表达式的值

    熟悉递归的朋友,可能一下就会发现这就是个递归,将大问题拆分成子问题,用子问题的返回值,对父问题进行解答。


    抽象人的思路

    如果我们用一个树来表达我们的拆解过程,那么可以得到下面一颗非完全二叉树,我们的拆解过程,就是一个构建树的过程。

    还是之前的例子:((p>q)&(q>r))>(p>r) ,通过递归,我们得到了这样一颗树。

    这里写图片描述

    我们接下了的所有操作都将以这个树为基础,所以构建这个颗树极为关键,是整个算法的核心

    下面给出完整思路(忽略实现细节)

    1. 建树(建树思路前面给出)。
    2. 从树的叶子节点开始,自下而上,同层优先,进行计算。
    3. 得到根节点的值,然后重新赋值
    4. 回到步骤2,直到真值表构建完毕

    有了这个思路框架,我们就可以开始编写具体的代码,并补充一些其他需要注意的东西。


    实现细节

    建树

    节点的存储

    定义一个结构体 node 存储节点信息,除叶子节点外,每个节点都有至少有一个左儿子或右儿子(当然大部分是都有),这些节点要存储的信息如下:

    • 一个字符串存储命题公式
    • 一个字符存储,两个儿子之间的运算符
    • 一个int型整数存储该节点存储的命题公式的真值

    递归建树

    考虑递归结束的条件:

    1. 当当前命题公式不含符号时
    2. 当当前命题公式为命题的否定时

    按照运算的优先级,从低到高枚举第一个出现的符号,按符号将公式分成两个子式①

    优先级:= <> < |< &< ! < ()

    考虑一些特殊情况

    1. 第一个满足①的符号,包括在括号里②
    2. 命题公式以!开头③

    对于第一种,我们需要先检测公式第一个字符是不是右括号

    • 如果是,我们找到对应的左括号,并以左括号旁边的括号为分界点分出子式。
    • 如果不是,按原样处理。可以证明,如果第一个符号不是右括号或取反符号! ,则一定存在满足①的符号将子式正确分成两份。

    特殊中的特殊:出现多重括号。需要找到和最外层匹配的左括号。

    对于第二种,暂时忽略掉感叹号,从第二个字符开始处理,则可以按①或②进行处理,最后生成子串的时候记得感叹号任然保留。



    计算公式的真值

    根据我们之前的设计,我们要从最底层的叶子节点开始,并且同层优先,自下而上进行计算。

    而我们求真值的时候真的需要这么做吗?

    答案是:不需要

    同样的,我们利用递归,从根节点开始计算,递归表达式如下:

    f(father)=f(left_kid) [operator] f(right_kid)

    值得注意的一点:

    在C语言中,与运算和或运算,当能够确定真值时,将前者能够确定真值时将不再计算后者。即进行与运算的两个公式,如果前者为假,后者将不再计算。

    所有我们在书写程序时,不能直接return A&&B ,而要先计算 C=A&&B ,在返回 return C

    当然,我们还需要按顺序对命题变元赋值,循环计算公式的真值,并进行存储。

    本教程将他们放到了打印真值表里进行,当然你也可以不这么做。



    打印真值表

    在这部分,我们需要实现大约3个模块

    • 赋值需要知道每个叶子节点在树中的位置
    • 打印真值表,需要存储树的每一层含有的节点
    • 一个循环计算真值表

    叶子节点的位置,在建树的时候记忆
    每一层含有的节点,单独写一个函数计算

    给出伪代码:

    print(树) //从下向上,按层级打印
    for(i取遍所有赋值) //二进制转十进制
    {
      for() //给命题变元赋值
      for() //打印命题变元的值
      cal(1) //计算总公式的值和子式的值
      for() //打印子式和总公式的值
      print(换行)
    }

    注意:后面打印的真值要和第一行的命题公式一一对应



    参考代码

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define MAXN 100
    #define Maxn 100
    
    struct point
    {
        char str[MAXN];
        char oper;
        int value;
    } exp[Maxn];
    
    const char op[6] = {'=', '>', '|', '&'};
    
    int kid_bj[MAXN * 2], kid[MAXN];
    int kid_num = 0;
    
    int f_value[MAXN * 2];
    int layer[10][10], lay;
    
    void strcopy(char temp1[], char str[], int start, int end)
    {
        int i, j = 0;
        for (i = start; i < end; i++)
        {
            temp1[j++] = str[i];
        }
        temp1[j] = '\0';
    }
    
    void kill_bracket(char s[])
    {
        int i = 1;
        int left = 0;
        if (s[0] == '(')
        {
            left++;
            while (i < strlen(s) - 1)
            {
                if (s[i] == ')')
                {
                    if (left == 1)
                        return;
                    left--;
                }
                if (s[i] == '(')
                    left++;
                i++;
            }
            char temp[MAXN];
            strcopy(temp, s, 1, strlen(s) - 1);
            memset(s, 0, sizeof(s));
            strcpy(s, temp);
        }
    }
    
    void build_tree(char s[], int node)
    {
        int i, k, len, mid, find;
        char s1[MAXN], s2[MAXN];
        len = strlen(s);
        kill_bracket(s);
        if (s[0] == '!' && s[1] == '(' && s[len - 1] == ')')
        {
            exp[node].oper = s[0];
            strcpy(exp[node].str, s);
            strcopy(s1, s, 2, len - 1);
            build_tree(s1, node * 2);
            return;
        }
    
        if (len <= 2)
        {
            if (len == 1)
            {
                strcpy(exp[node].str, s);
                if (kid_bj[s[0]] == 0)
                {
                    kid_bj[s[0]] = 1;
                    kid[kid_num++] = s[0];
                }
                return;
            }
            else
            {
                char temp[MAXN];
                temp[0] = s[1];
                temp[1] = '\0';
                strcpy(exp[node].str, s);
                exp[node].oper = s[0];
                strcpy(exp[node * 2].str, temp);
                if (kid_bj[temp[0]] == 0)
                {
                    kid_bj[temp[0]] = 1;
                    kid[kid_num++] = temp[0];
                }
                return;
            }
        }
        find = 0;
        for (k = 0; k < 4; k++)
        {
            i = 0;
            if (find)
                break;
            while (i < len)
            {
                if (s[i] == '(')
                {
                    i++;
                    int num = 1;
                    while (i < len)
                    {
                        if (num == 0)
                            break;
                        if (s[i] == '(')
                            num++;
                        if (s[i] == ')')
                            num--;
                        i++;
                    }
                }
                if (s[i] == op[k])
                {
                    mid = i;
                    find = 1;
                    break;
                }
                i++;
            }
        }
        // printf("%c\n",s[mid]);
        printf("%d  %s\n", strlen(s), s);
        strcpy(exp[node].str, s);
        exp[node].oper = s[mid];
        // if (s[mid - 1] == ')' && s[0] == '(')
        //     strcopy(s1, s, 1, mid - 1);
        // else
            strcopy(s1, s, 0, mid);
        // if (s[mid + 1] == '(')
        //     strcopy(s2, s, mid + 2, len - 1);
        // else
            strcopy(s2, s, mid + 1, len);
        printf("%d  %s\n", strlen(s1), s1);
        printf("%d  %s\n", strlen(s2), s2);
        build_tree(s1, node * 2);
        build_tree(s2, node * 2 + 1);
    }
    
    int cal_val(int node)
    {
        if (strlen(exp[node].str) == 1)
        {
            // printf("****%c %d***",exp[node].str[0],f_value[exp[node].str[0]]);
            return f_value[exp[node].str[0]];
        }
    
        int lkid, rkid;
        int a, b;
    
        lkid = node * 2;
        rkid = node * 2 + 1;
    
        switch (exp[node].oper)
        {
        case '=':
            if (cal_val(lkid) == cal_val(rkid))
            {
                exp[node].value = 1;
                return exp[node].value;
            }
            else
            {
                exp[node].value = 0;
                return exp[node].value;
            }
            break;
    
        case '>':
            if (cal_val(lkid) == 1 && cal_val(rkid) == 0)
            {
                exp[node].value = 0;
                return exp[node].value;
            }
            else
            {
                exp[node].value = 1;
                return exp[node].value;
            }
            break;
    
        case '|':
            a = cal_val(lkid);
            b = cal_val(rkid);
            exp[node].value = a || b;
            return exp[node].value;
            break;
    
        case '&':
            a = cal_val(lkid);
            b = cal_val(rkid);
            exp[node].value = a && b;
            return exp[node].value;
            break;
    
        case '!':
            if (cal_val(lkid) == 1)
            {
                exp[node].value = 0;
                return exp[node].value;
            }
            else
            {
                exp[node].value = 1;
                return exp[node].value;
            }
            break;
        }
    }
    
    void getLayer(int node, int l)
    {
    
        int lens = strlen(exp[node].str);
        if (lens > 1)
        {
            if (l > lay)
                lay = l;
            layer[l][++layer[l][0]] = node;
            if (lens == 2 || (exp[node].str[0] == '!' && exp[node].str[lens - 1] == ')'))
                getLayer(node * 2, l + 1);
            else
            {
                getLayer(node * 2, l + 1);
                getLayer(node * 2 + 1, l + 1);
            }
        }
        return;
    }
    
    void print_table()
    {
        int i, count = 1, j, temp, k;
        printf("layer=%d\n", lay);
        for (i = kid_num - 1; i >= 0; i--)
        {
            count *= 2;
            printf("%10c  ", kid[i]);
        }
    
        printf("kidnum=%d\n", kid_num);
        // 打印各层节点
        // for (i = lay; i > 0; i--)
        //     for (j = 1; j <= layer[i][0]; j++)
        //         printf("%10s  ", exp[layer[i][j]].str);
        printf("\n");
    
        for (i = 0; i < count; i++)
        {
            temp = i;
            for (j = 0; j < kid_num; j++)
            {
                f_value[kid[j]] = temp % 2;
                temp /= 2;
            }
            for (j = kid_num - 1; j >= 0; j--)
                printf("%10d  ", f_value[kid[j]]);
    
            cal_val(1);
            // 打印各层节点
            // for (k = lay; k > 0; k--)
            //     for (j = 1; j <= layer[k][0]; j++)
            //         printf("%10d  ", exp[layer[k][j]].value);
            //打印根节点
            printf("%10d  ", exp[layer[1][1]].value);
            printf("\n");
        }
    }
    
    int main()
    {
        char s[MAXN];
        scanf("%s", s);
        build_tree(s, 1);
        getLayer(1, 1);
        print_table();
        system("pause");
        return 0;
    }
    展开全文
  • “离散数学”实验报告(给定命题公式真值表一.实验目的3二.实验内容……………………………………………………………………….3任意一个命题公式真值表3三.实验环境3四. 实验原理和实现过程(算法描述)31.实验...

    “离散数学”实验报告

    (求给定命题公式的真值表一.实验目的3

    二.实验内容……………………………………………………………………….3

    求任意一个命题公式的真值表3

    三.实验环境3

    四. 实验原理和实现过程(算法描述)3

    1.实验原理3

    2.实验流程图5

    五.实验代码6

    六. 实验结果14

    七. 实验总结19

    一.实验目的

    本实验课程是网络工程专业学生的一门专业基础课程,通过实验,帮助学生更好地掌握计算机科学技术常用的离散数学中的概念、性质和运算;通过实验提高学生编写实验报告、总结实验结果的能力;使学生具备程序设计的思想,能够独立完成简单的算法设计和分析。

    熟悉掌握命题逻辑中的真值表、主范式等,进一步能用它们来解决实际问题。

    二.实验内容

    求任意一个命题公式的真值表,并根据真值表求主范式

    详细说明:

    求任意一个命题公式的真值表

    本实验要求大家利用C/C++语言,实现任意输入公式的真值表计算。一般我们将公式中的命题变元放在真值表的左边,将公式的结果放在真值表的右边。命题变元可用数值变量表示,合适公式的表示及求真值表转化为逻辑运算结果;可用一维数表示合式公式中所出现的n个命题变元,同时它也是一个二进制加法器的模拟器,每当在这个模拟器中产生一个二进制数时,就相当于给各个命题变元产生了一组真值指派。算法逻辑如下:

    (1)将二进制加法模拟器赋初值0

    (2)计算模拟器中所对应的一组真值指派下合式公式的真值。

    (3)输出真值表中对应于模拟器所给出的一组真值指派及这组真值指派所对应的一行真值。

    (4)产生下一个二进制数值,若该数值等于2n-1,则结束,否则转(2)。

    三.实验环境;

    使用visual C++6.0为编程软件,采用C语言为编程语言实现。

    四. 实验原理和实现过程(算法描述);

    1.实验原理

    (1)真值表表征逻辑事件输入和输出之间全部可能状态的表格。列出命题公式真假值的表。通常以1表示真,0 表示假。命题公式的取值由组成命题公式的命题变元的取值和命题联结词决定,命题联结词的真值表给出了真假值的算法。 真值表是在逻辑中使用的一类数学表,用来确定一个表达式是否为真或有效。主析取范式在含有n个命题变元的简单合取式中,若每个命题变元与其否定不同时存在,而两者之一出现一次且仅出现一次,称该简单合取式为小项由若干个不同的小项组成的析取式称为主析取范式;与A等价的主析取范式称为A的主析取范式任意含n个命题变元的非永假命题公式A都存在与其等价的主析取范式,并且是惟一的主合取范式在含有n个命题变元的简单析取式中,若每个命题变元与其否定不同时存在,而两者之一出现一次且仅出现一次,称该简单析取式为大项由若干个不同的大项组成的合取式称为主合取范式;与A等价的主合取范式称为A的主合取范式任意含n个命题变元的非永真命题公式A都存在与其等价的主合取范式,并且是惟一的

    五.实验代码

    #include "stdio.h"

    #include "stdlib.h"

    #include "string.h"

    #include "conio.h"

    #include "math.h"

    #define N 50

    void panduan(int b[N],int f);//赋值函数

    int tkh (char sz[N], char ccu[N], int icu[N], int h0);//分级运算函数

    int fkh (char sz[N], char ccu[N], int icu[N], int h0);//主运算函数

    main()

    {

    int i1,i2,d=1,icu[N],kh=0,jg,j=0,h0;//icu[N]用于存放变量值,kh括号计数,jg存放结果

    int bj=0,hq[N],h=0,x=0,xq[N];//hq[N]存放合取结果xq[N]存放析取结果

    char sz[N],ccu[N],sz0[N],s;//sz[N]存放式子,ccu[N]存放变量,sz0[N]也是用于存放式子

    hq[0]=-1;

    xq[0]=-1;

    printf("***************************************\n");//标语

    printf("** **\n");

    printf("** 欢迎进入逻辑运算软件 **\n");

    printf("** (可运算真值表,主范式,支持括号) **\n");

    printf("** **\n");

    printf("** 用!表示非

    展开全文
  • 真值表命题逻辑理论 中的一个重要 概念 , 利用它可 以命 题公式 的主 范式 、 定命 题公式 的类型以及 进行 判命题 逻辑的推理等 。本文给 出了 意命题 公式真值 表的生成 算法 , 用计算机 解决命题 逻辑 中的...
  • C语言 命题公式真值表

    千次阅读 2020-11-21 00:49:36
    掌握命题公式真值表的求解,并实现自动求解程序。 2.实验内容 输入:任意命题公式 输出:该命题公式的真值表 要求: 输入任意命题公式,要求用数据存储命题公式的所有赋值及对应真值,并输出该公式真值表 此题...

    1.实验目的

    掌握命题公式真值表的求解,并实现自动求解程序。

    2.实验内容

    输入:任意命题公式

    输出:该命题公式的真值表

    要求:

    1. 输入任意命题公式,要求用数据存储命题公式的所有赋值及对应真值,并输出该公式真值表
    2. 此题,难度稍大,对命题公式的表示的方式不一样,实现过程略有不同,可查找相关资料

     

    3.实验过程(主要思想、核心算法、核心代码)

    代码比较长,还需要细心观看,有什么意见还请大佬提出,谢谢!

    主函数

    #include <stdio.h>
    #include <string.h>
    int main()
    {
    	void quFan(char a[]);
    	void kuohao(char a[]);
    	void heQu(char a[]);
    	void stJian(char a[]);
    	void xiQu(char a[]);
    	int allData(char a[],char b[]);
    	void fillIn(char a[],char varchar[],int nvar,char values[],char resultchar[]);
    
    	char pstate[120],pstate0[120],charList[120],charVal[120];
    	int i=0,nold=0,nnew=0,nvar=1,nRow=1,j=0,flagsum=1;
    	printf("请输入公式(析|,合&,条-,双=,否!,01):\n");
    	gets(pstate0);
    
    	nold=strlen(pstate0)+1;
    	nnew=strlen(pstate0);
    	for(i=0;i<nnew;i++)
    	{
    		pstate[i]=pstate0[i];
    	}
    	pstate[i]='\0';
    
    	nvar=allData(pstate,charList);//取变元个数
    	nRow=1;//有2^n个情况
    	for(i=0;i<nvar;i++){
    		charVal[i]='0';nRow=nRow*2;
    	}
    	charVal[i]='\0';
    
    	for(i=0;i<nRow;i++){//输出每种情况的结果
    		for(j=0;j<nvar;j++)
    		{
    			printf("%4c",charVal[j]);//每种赋值情况输出
    		}
    
    		/**
    			将值填入公式
    			pstate原始数组
    			返回pstate填充后数组
    		*/
    		fillIn(pstate0,charList,nvar,charVal,pstate);
    		//计算公式的值
    		nold=strlen(pstate0)+1;
    		nnew=strlen(pstate);
    		while(nnew<nold)
    		{
    			nold=strlen(pstate);
    			quFan(pstate);
    			kuohao(pstate);
    			stJian(pstate);
    			heQu(pstate);
    			xiQu(pstate);
    			nnew=strlen(pstate);
    		}
    
    		printf("%15c%s",' ',pstate);
    		printf("\n");
    		//值加1
    		flagsum=1;
    		for(j=nvar-1;j>=0;j--)
    		{
    			if(charVal[j]=='1'){
    				if(flagsum==1){//1+1=10//进位
    					charVal[j]='0';flagsum=1;
    				}else{break;}//1+0=1  不变
    			}else if(charVal[j]=='0'){
    				if(flagsum==1){ //0+1=1 //没有进位
    					charVal[j]='1'; flagsum=0;
    				}else{break;}// 0+0 
    			}
    		}
    	}
    	return 0;
    }
    

     

    取反,也就是非!

    void quFan(char a[]){
    	int _result=0,i=0,j=0;
    	while(i<strlen(a)){
    		j=i;_result=0;
    		//非的真值情况
    		if((j+1<strlen(a))&&(a[j]=='!')&&(a[j+1]=='1')){
    			a[j]='0';_result=1;
    		}else if((j+1<strlen(a))&&(a[j]=='!')&&(a[j+1]=='0')){
    			a[j]='1';_result=1;
    		}
    
    		if(_result==1){//修改成功后则后面的往前覆盖
    			j++;
    			while(a[j+1]!='\0'){
    				a[j]=a[j+1]; j++;
    			}
    			a[j]='\0';
    		}else{i++;}
    	}
    }
    

     

    括号解析

    void kuohao(char a[])
    {
    	int _result=0,i=0,j=0;
    	while(i<strlen(a)){
    		j=i; _result=0;
    		//括号的处理
    		if((j+2<strlen(a))&&(a[j]=='(')&&(a[j+1]=='1')&&(a[j+2]==')')){
    			a[j]='1'; _result=1;
    		}else if((j+2<strlen(a))&&(a[j]=='(')&&(a[j+1]=='0')&&(a[j+2]==')')){
    			a[j]='0'; _result=1;
    		}
    
    		if(_result==1){//修改成功后则后面的往前覆盖
    			j++;
    			while(a[j+2]!='\0'){
    				a[j]=a[j+2]; j++;
    			}
    			a[j]='\0';
    		}else {i++;}
    	}
    }
    

     

    合取

    void heQu(char a[]){
    	int _result=0,i=0,j=0;
    	while(i<strlen(a)){
    		j=i;_result=0;
    		//合取的真值情况
    		if((j+2<strlen(a))&&(a[j]=='0')&&(a[j+1]=='&')&&(a[j+2]=='0'))
    		{a[j]='0';_result=1;}
    		else if((j+2<strlen(a))&&(a[j]=='0')&&(a[j+1]=='&')&&(a[j+2]=='1'))
    		{a[j]='0';_result=1;}
    		else if((j+2<strlen(a))&&(a[j]=='1')&&(a[j+1]=='&')&&(a[j+2]=='0'))
    		{a[j]='0';_result=1;}
    		else if((j+2<strlen(a))&&(a[j]=='1')&&(a[j+1]=='&')&&(a[j+2]=='1'))
    		{a[j]='1';_result=1;}
    
    		if(_result==1){//修改成功后则后面的往前覆盖
    			j++;
    			while(a[j+2]!='\0'){
    				a[j]=a[j+2];j++;
    			}
    			a[j]='\0';
    		}else {i++;}
    	}
    }
    

     

    析取

    void xiQu(char a[]){
    	int _result=0,i=0,j=0;
    	while(i<strlen(a)){
    		j=i;_result=0;
    		//析取的真值情况
    		if((j+2<strlen(a))&&(a[j]=='0')&&(a[j+1]=='|')&&(a[j+2]=='0'))
    		{a[j]='0';_result=1;}
    		else if((j+2<strlen(a))&&(a[j]=='0')&&(a[j+1]=='|')&&(a[j+2]=='1'))
    		{a[j]='1';_result=1;}
    		else if((j+2<strlen(a))&&(a[j]=='1')&&(a[j+1]=='|')&&(a[j+2]=='0'))
    		{a[j]='1';_result=1;}
    		else if((j+2<strlen(a))&&(a[j]=='1')&&(a[j+1]=='|')&&(a[j+2]=='1'))
    		{a[j]='1';_result=1;}
    
    		if(_result==1){//修改成功后则后面的往前覆盖
    			j++;
    			while(a[j+2]!='\0'){
    				a[j]=a[j+2];j++;
    			}
    			a[j]='\0';//结尾添加字符串结束符
    		}else {i++;}
    	}
    }
    

     

    双条件

    void stJian(char a[])
    {
    	int _result=0,i=0,j=0;
    	while(i<strlen(a)){
    		j=i;_result=0;
    		//双条件的真值情况
    		if((j+2<strlen(a))&&(a[j]=='0')&&(a[j+1]=='=')&&(a[j+2]=='0'))
    		{a[j]='0';_result=1;}
    		else if((j+2<strlen(a))&&(a[j]=='0')&&(a[j+1]=='=')&&(a[j+2]=='1'))
    		{a[j]='0';_result=1;}
    		else if((j+2<strlen(a))&&(a[j]=='1')&&(a[j+1]=='=')&&(a[j+2]=='0'))
    		{a[j]='0';_result=1;}
    		else if((j+2<strlen(a))&&(a[j]=='1')&&(a[j+1]=='=')&&(a[j+2]=='1'))
    		{a[j]='1';_result=1;}
    
    		if(_result==1){//修改成功后则后面的往前覆盖
    			j++;
    			while(a[j+2]!='\0'){
    				a[j]=a[j+2];j++;
    			}
    			a[j]='\0';
    		}else {i++;}
    	}
    }
    

     

    获取命题公式所有不同的元素

    int allData(char a[],char b[]){
    	char tmpc=' '; 
    	int n=strlen(a),i=0,j=0,k=0;
    	for(i=0;i<n;i++){//获取所有变元,以便于输出和赋值
    		if(((a[i]>='a')&&(a[i]<='z'))||((a[i]>='A')&&(a[i]<='Z'))){
    			for(k=0;k<j;k++){
    				if(b[k]==a[i]){
    					break;
    				}
    			}
    			if(k>=j){
    				b[j]=a[i];
    				j++;
    			}
    		}
    	}
    	b[j]='\0';//加上结束标志
    	//printf("====%s",b);
    	//从高到低排序
    	for(i=0;i<j-1;i++){
    		for(k=0;k<j-i-1;k++){
    			if(b[k]>b[k+1]){
    				tmpc=b[k];
    				b[k]=b[k+1];
    				b[k+1]=tmpc;
    			}
    		}
    	}
    	return j;//不同的变元个数
    }
    

     

    将赋值情况代入命题公式中

    void fillIn(char a[],char varchar[],int nvar,char values[],char resultchar[])
    {
    	/**
    		a是原始公式
    		varchar是变元列表如abc
    		values 是变元的某次取值
    		二进制的思维把相应位置的变元替换成'0'或'1'
    	*/
    	int nLen=strlen(a),i=0,j=0,k=0;
    	for(i=0;i<nLen;i++){//不改变原数组
    		resultchar[i]=a[i];
    	}
    	resultchar[i]='\0';
    	for(i=0;i<nLen;i++){
    		for(j=0;j<nvar;j++){
    			if(resultchar[i]==varchar[j]){
    				resultchar[i]=values[j];
    				break;
    			}
    		}
    	}
    }
    

     

    温馨提示:以上是完整代码,小代码块可能多出一个花括号,不碍事那是main的或括号。大佬有意见或者建议还请提出,学习进步。

    展开全文
  • 内容介绍原文档由会员 xiaowei 发布命题公式真值表生成算法研究与程序设计1.1万字 20页论文+开题+任务书+翻译+程序代码摘要推理的自动化(包括自动定理证明)特别诱人,因为所有数学以及许多技术领域均可用一定的形式...
  • 离散数学实验报告专业...3.【实验内容】任意一个命题公式真值表4、【实验要求】C 或 C++语言编程实现5. 【算法描述】1.实验原理真值表:表征逻辑事件输入和输出之间全部可能状态的表格。列出命题公式 真假值...
  • 已知命题公式A=﹁( p∨ q ) ∧ ( (p∨ r) ∨ s),用JAVA语言编写程序构造该命题公式真值表真值表输出样式自己设计(变量值可以不手工输入)</p>
  • 用c语言做命题公式真值表(仅支持交,并,非三种运算符)
  • 本关任务:编写一个程序,打印给定命题公式真值表。 相关知识 为了完成本关任务,你需要掌握: 1.五个命题联接词的真值定义 1.列真值表时命题变元的排序顺序,真值指派的排列顺序 2.中缀式命题公式转换为后缀式...
  • 输出命题公式真值表

    千次阅读 2019-03-04 15:17:08
    描述 先输入一个正整数 n(n 小于等于 10),...用类似于逆波兰表达式形式的字符串表示的命题公式真值表波兰表达式(即二 元运算,两个操作数在前,运算符在后;一元运算,一个操作数在前,运算符在 后)。 输入 ...
  • 给出任意变元的合式公式,构造该合式公式真值表
  • 用来生成真值表,然后用函数运算,输出结果,并根据结果归类给范式,最后输出范式。 函数部分,主要是 3 个函数,一个为真值表递加函数,通过二进制的加法原理递进产生&...
  • * 显示合适公式真值表 * 提供将一个中缀合适公式真值表输出到某一PrintStream流中的功能 * 以单个大写字母表示变量(支持26个变量) * 以字符0或者1表示值 * 以 ~ ^ & > - 分别表示 非 析取 合取 条件 双...
  • 离散数学命题公式真值表C或C语言实验报告 离散数学实验报告专业班级:12 级计算机本部一班 姓名:鲍佳珍 学号: 201212201401016 实验成绩:1. 【实验题目】命题逻辑实验二2. 【实验目的】熟悉掌握命题逻辑中真...
  • 给定任意一个命题公式的真值表,并根据真值表求主范式。 算法思想 将逻辑表达式转换为后缀表达式,然后套用逆波兰表达式的求值方法 利用位运算,找出一个十进制整数对应二进制的每一位,给命题变项赋值 记录下成真...
  • 首先用一个串来储存使用者所输入的命题表达式,依据人类的思维,会对输入的命题公式进行分析和计算,但计算机可不会,这时我们就要写入相关代码把使用者输入的命题表达式转换为计算机所能进行计算的后缀表达式,我们...
  • Java实现离散真值表

    2018-10-17 22:20:14
    此文件实现了离散中的输出真值表,应用了栈的技术,可以帮助java学习者更好的巩固基础
  • 对给出的任意一个命题公式(不超过四个命题变元),使学生会用c语言的程序编程表示出来,并且能够计算它在各组真值指派下所应有的真值,画出其真值表。#includeusing namespace std;struct{int p[4] = {1,1,0,0};int q...
  • 用两个栈解决顺序计算命题问题 一个栈存储操作符号,一个栈存储操作符。 (“良心“的献上手绘图) 当遇到)号时依次弹出操作符并弹出真值计算完后压入栈中遇到(停止。 依次类推就可以解决先后顺序问题。 此类问题...
  • 根据命题公式真值表求主析取范式。 输入格式: 第一行为命题中符号的个数(最大不超过8); 第二行开始到最后为命题公式的真值表最后一列。 输出格式: 输出主析取范式。 注意: 1.逻辑连接词非为!,与为^,或为+; 2....
  • 命题公式真值表计算

    千次阅读 2020-04-16 09:17:48
    1.包括了如何得到后缀式 还有后缀式的计算 2.关于去重问题 用set存储命题中的字母 起...5.关于命题变元的真假赋值 可以参考子集得到方法 i&(1<<j) /* //草稿图 */ #include<iostream> #include&l...
  • } } printf("输入的正整数有%d个,其平均为:%f",nNum,(float)nSum/nNum); return 0; } 3. #include <stdio.h> #include <string.h> int main(void) { int a[3],nMin,nMax; int i; for(i=0;i;i++){ printf("请...
  • 离散数学命题公式求真值表

    千次阅读 2019-03-08 22:07:00
    上离散学这一部分的时候就感觉手工太麻烦了,所以就考虑写个程序直接枚举每一种情况,然后把真值表输出出来开始的时候,考虑把命题转成后缀表达式,然后进一步计算表达式的值。但是中间遇到了一些问题,不是很好...
  • 1在命题公式中,对于分量指派真值的各种可能组合,就确定了这个命题公式的各种真值情况,把它汇列成表,就是命题公式真值表。现举例说明如下:例题1 构造┓p∨q的真值表。解表1-4.1p q ┓p ┓p∨qt t f tt f f ff ...
  • 已知命题公式A=﹁( p q ) ( (p r) s),用JAVA或C/C++语言编写程序构造该命题公式真值表真值表输出样式自己设计(变量值可以不手工输入),编制程序、画流程图、解释核心程序段、展示结果、心得等,撰写并提交实践...
  • } } printf("输入的正整数有%d个,其平均为:%f",nnum,(float)nsum/nnum); return 0; } 3. #include <stdio.h> #include <string.h> int main(void) { int a[3],nmin,nmax; int i; for(i=0;i;i++){ printf("请...
  • 1422.输出命题公式真值表 时限:1000ms 内存限制:10000K 总时限:3000ms 描述 先输入一个正整数n(n小于等于10),表示共有n个命题变元,再输入一个类似于逆波兰表达式的字符串表示一个命题公式,约定在该...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,639
精华内容 1,055
关键字:

求命题公式的真值表