重言式判别-课程设计报告
重言式判别_课程设计报告
学院计算机科学与技术系课程设计报告2016~2017学年第1学期课程数据结构与算法课程设计题目名称重言式的判别学生王芳学号1404011018专业班级计算机科学与技术14级1班指导教师红何立新2016年9月一、题目【问题描述】一个逻辑表达式如果对于其变元的任一种取值都为真,则称为重言式;反之,如果对于其变元的任一种取值都为假,则称为矛盾式;然而,更多的情况下,既非重言式,也非矛盾式。
试写一个程序,通过真值表判别一个逻辑表达式属于上述哪一类。
【基本要求】(1) 逻辑表达式从终端输入,长度不超过一行。
逻辑运算符包括 "|","&" 和"~",分别表示或、与和非,运算优先程度递增,但可由括号改变,即括号的运算优先。
逻辑变元为大写字母。
表达式中任何地方都可以含有多个空格符。
(2) 若是重言式或矛盾式,可以只显示"True forever",或"False forever",否则显示 "Satisfactible" 以及变量名序列,与用户交互。
若用户对表达式中变元取定一组值,程序就求出并显示逻辑表达式的值。
【测试数据】(1) (A|~A)&(B|~B)(2) (A&~A)&C(3) A|B|C|D|E|~A(4) A&B&C&~B(5) (A|B)&(A|~B)(6) A&~B|~A&B;O ,0;0,1;1,0;1,1 。
二、问题分析1、一个逻辑表达式如果对于其变元的任一种取值均为真,则称为重言式;反之,如果对于其变元的任一种取值都为假,则称为矛盾式,若对于其变元的任一种取值既有真,又有假,则称其为可满足式。
写一个程序通过真值表判别一个逻辑表达式属于上述哪一类。
基本要求如下:1)逻辑表达式从终端输入,长度不超过一行。
算法课设实验报告(3篇)
第1篇一、实验背景与目的随着计算机技术的飞速发展,算法在计算机科学中扮演着至关重要的角色。
为了加深对算法设计与分析的理解,提高实际应用能力,本实验课程设计旨在通过实际操作,让学生掌握算法设计与分析的基本方法,学会运用所学知识解决实际问题。
二、实验内容与步骤本次实验共分为三个部分,分别为排序算法、贪心算法和动态规划算法的设计与实现。
1. 排序算法(1)实验目的:熟悉常见的排序算法,理解其原理,比较其优缺点,并实现至少三种排序算法。
(2)实验内容:- 实现冒泡排序、快速排序和归并排序三种算法。
- 对每种算法进行时间复杂度和空间复杂度的分析。
- 编写测试程序,对算法进行性能测试,比较不同算法的优劣。
(3)实验步骤:- 分析冒泡排序、快速排序和归并排序的原理。
- 编写三种排序算法的代码。
- 分析代码的时间复杂度和空间复杂度。
- 编写测试程序,生成随机测试数据,测试三种算法的性能。
- 比较三种算法的运行时间和内存占用。
2. 贪心算法(1)实验目的:理解贪心算法的基本思想,掌握贪心算法的解题步骤,并实现一个贪心算法问题。
(2)实验内容:- 实现一个贪心算法问题,如活动选择问题。
- 分析贪心算法的正确性,并证明其最优性。
(3)实验步骤:- 分析活动选择问题的贪心策略。
- 编写贪心算法的代码。
- 分析贪心算法的正确性,并证明其最优性。
- 编写测试程序,验证贪心算法的正确性。
3. 动态规划算法(1)实验目的:理解动态规划算法的基本思想,掌握动态规划算法的解题步骤,并实现一个动态规划算法问题。
(2)实验内容:- 实现一个动态规划算法问题,如背包问题。
- 分析动态规划算法的正确性,并证明其最优性。
(3)实验步骤:- 分析背包问题的动态规划策略。
- 编写动态规划算法的代码。
- 分析动态规划算法的正确性,并证明其最优性。
- 编写测试程序,验证动态规划算法的正确性。
三、实验结果与分析1. 排序算法实验结果:- 冒泡排序:时间复杂度O(n^2),空间复杂度O(1)。
重言式判别-课程设计报告
学院计算机科学与技术系课程设计报告2016~2017学年第1学期课程数据结构与算法课程设计题目名称重言式的判别学生王芳学号1404011018专业班级计算机科学与技术14级1班指导教师红何立新2016年9月一、题目【问题描述】一个逻辑表达式如果对于其变元的任一种取值都为真,则称为重言式;反之,如果对于其变元的任一种取值都为假,则称为矛盾式;然而,更多的情况下,既非重言式,也非矛盾式。
试写一个程序,通过真值表判别一个逻辑表达式属于上述哪一类。
【基本要求】(1) 逻辑表达式从终端输入,长度不超过一行。
逻辑运算符包括"|","&" 和"~",分别表示或、与和非,运算优先程度递增,但可由括号改变,即括号的运算优先。
逻辑变元为大写字母。
表达式中任何地方都可以含有多个空格符。
(2) 若是重言式或矛盾式,可以只显示"True forever",或"False forever",否则显示"Satisfactible" 以及变量名序列,与用户交互。
若用户对表达式中变元取定一组值,程序就求出并显示逻辑表达式的值。
【测试数据】(1) (A|~A)&(B|~B)(2) (A&~A)&C(3) A|B|C|D|E|~A(4) A&B&C&~B(5) (A|B)&(A|~B)(6) A&~B|~A&B;O ,0;0,1;1,0;1,1 。
二、问题分析1、一个逻辑表达式如果对于其变元的任一种取值均为真,则称为重言式;反之,如果对于其变元的任一种取值都为假,则称为矛盾式,若对于其变元的任一种取值既有真,又有假,则称其为可满足式。
写一个程序通过真值表判别一个逻辑表达式属于上述哪一类。
基本要求如下:1)逻辑表达式从终端输入,长度不超过一行。
左孝凌离散数学1.5重言式与蕴含式PPT课件
从而┐Q(P→Q)为假.
②若Q为假,则┐Q为真,P→Q为假,
从而┐Q(P→Q)为假.
根据① ②,所以 ┐Q(P→Q)┐P
4)法4: (┐Q(P→Q)) → ┐P
┐ (┐Q( ┐ P ∨ Q)) ∨ ┐P
(Q ∨(P ┐ Q)) ∨ ┐P
((Q ∨P) (Q ∨ ┐ Q )) ∨ ┐P
(Q ∨P) ∨ ┐P
4
第一章 命题逻辑(Propositional Logic) 1.5重
言式与蕴含式(Tautology and Implication)
判别命题公式的类型有两种方法: 真值表法和等值
演算法.
等值演算法是将所给命题公式通过等值演算化为最
简单的形式, 然后再进行判别.
例1.判别下列命题公式的类型.
(1). Q∨┓((┓P∨Q)∧P) (重言式)
重言式与蕴含式(Tautology and Implication)
• 小结:本节介绍了命题公式的分类,重言式、矛盾式与蕴 含式的概念及其性质,等价式与蕴涵式的关系。
• 重点掌握: (1)用等值演算法判别命题公式的类型。 (2)重言式、矛盾式与蕴涵式的性质。 (3)等价式与蕴涵式的关系。
• 作业: P23 (1)c,d ,(2) a ,(8). • 预习:1.6 • 思考题:1) 为什么要引入联结词?
2) 什么是最小联结词组? ,,, c
21
1. 真值表指派 2. 真值表及其构成方法 3. 等价公式及等价置换 4. 命题公式的分类 5. 蕴含式判定及其性质
小结
(1)若A在其各种赋值下的取值均为真,则称A是重言式或永真式, 记 为T或1。 (2)若A在其各种赋值下的取值均为假,则称A是矛盾式或永假式, 记 为F或0。
判别分析 实验报告
判别分析实验报告判别分析实验报告一、引言判别分析是一种常用的统计分析方法,广泛应用于数据挖掘、模式识别、生物信息学等领域。
本实验旨在通过对一个真实数据集的分析,探讨判别分析在实际问题中的应用效果。
二、数据集介绍本实验使用的数据集是一份关于肿瘤患者的临床数据,包括患者的年龄、性别、肿瘤大小、转移情况等多个变量。
我们的目标是根据这些变量,建立一个判别模型,能够准确地预测患者是否患有恶性肿瘤。
三、数据预处理在进行判别分析之前,我们首先对数据进行预处理。
这包括数据清洗、缺失值处理、异常值检测等步骤。
通过对数据的观察和分析,我们发现有部分数据存在缺失值,需要进行处理。
我们选择使用均值替代缺失值的方法进行处理,并对替代后的数据进行了异常值检测。
四、判别模型建立在本实验中,我们选择了线性判别分析(LDA)作为判别模型的建立方法。
LDA 是一种经典的判别分析方法,通过将数据投影到低维空间中,使得不同类别的样本在投影后的空间中能够更好地区分开来。
我们使用Python中的scikit-learn 库来实现LDA算法。
五、模型评估为了评估建立的判别模型的性能,我们将数据集划分为训练集和测试集。
使用训练集对模型进行训练,并使用测试集进行模型的评估。
我们选择了准确率、精确率、召回率和F1值等指标来评估模型的性能。
经过多次实验和交叉验证,我们得到了一个较为稳定的模型,并对其性能进行了详细的分析和解释。
六、结果与讨论经过模型评估,我们得到了一个在测试集上准确率为85%的判别模型。
该模型在预测恶性肿瘤时具有较高的精确率和召回率,说明了其在实际应用中的可行性和有效性。
但同时我们也发现,该模型在预测良性肿瘤时存在一定的误判率,可能需要进一步优化和改进。
七、结论本实验通过对一个真实数据集的判别分析,验证了判别分析方法在预测恶性肿瘤的应用效果。
通过建立判别模型,并对其性能进行评估,我们得到了一个在测试集上具有较高准确率的模型。
然而,我们也发现了该模型在预测良性肿瘤时存在一定的误判率,需要进一步的改进和优化。
判别分析实验报告 SPSS
判别分析实验报告 SPSS一、实验目的判别分析是一种用于分类和预测的统计方法。
本次实验旨在通过使用 SPSS 软件,掌握判别分析的基本原理和操作流程,能够运用判别分析方法对实际数据进行分类,并对分类结果进行评估和解释。
二、实验数据本次实验使用的数据集包含了两个类别(类别 A 和类别 B)的样本,每个样本具有若干个特征变量,如年龄、收入、教育程度等。
数据集共有 200 个样本,其中类别 A 有 100 个样本,类别 B 有 100 个样本。
三、实验步骤1、数据导入首先,打开 SPSS 软件,选择“文件”菜单中的“打开”选项,将实验数据文件导入到 SPSS 中。
2、变量定义在 SPSS 数据视图中,对各个变量进行定义,包括变量名称、变量类型、变量标签等。
3、判别分析操作选择“分析”菜单中的“分类”子菜单,然后点击“判别分析”选项。
在弹出的判别分析对话框中,将类别变量选入“分组变量”框中,将其他特征变量选入“自变量”框中。
4、选择判别方法SPSS 提供了多种判别方法,如费希尔判别法、贝叶斯判别法等。
本次实验选择费希尔判别法。
5、模型评估在判别分析结果中,查看判别函数的系数、判别函数的显著性检验、分类结果的准确性等指标,以评估模型的性能。
四、实验结果与分析1、判别函数系数判别函数的系数反映了各个自变量对判别函数的贡献程度。
通过查看系数的大小和符号,可以了解各个变量在区分不同类别中的重要性。
例如,年龄变量的系数为正,说明年龄越大,越有可能属于某个类别;而收入变量的系数为负,说明收入越低,越有可能属于另一个类别。
2、判别函数的显著性检验通过对判别函数的显著性检验,可以判断判别函数是否能够有效地区分不同的类别。
如果检验结果显著,说明判别函数具有统计学意义,可以用于分类。
3、分类结果SPSS 会给出每个样本的分类结果,以及分类的准确性。
通过比较实际类别和预测类别,可以评估模型的分类效果。
如果分类准确性较高,说明模型能够较好地对样本进行分类;如果分类准确性较低,则需要进一步分析原因,可能是数据质量问题、变量选择不当或者判别方法不合适等。
SAS判别分析实验报告
判别分析一:实验目的通过实验掌握使用SAS进行判别分析的几种常用方法:距离判别,贝叶斯判别,费希尔判别。
二:实验内容1.用DISCRIM过程作贝叶斯判别。
2.用DISCRIM过程作费希尔判别。
三:程序代码及结果分析练习1(1)程序代码(2)结果及分析表1.1-对14名未定级运动员作贝叶斯判别表1.1 表明了在先验概率相同的前提下,对14名未定级运动员作贝叶斯判别的结果。
其中8,9,11,12,14均判给第二组,其余9个均判给第一组。
表1.2交叉验证法对误判概率作估计表1.2表明交叉验证法对误判概率做出的估计。
其中40,48号运用交叉验证法得出是误判的。
均是误判给了第一组。
而在全样品中是没有被误判的。
表1.3各组误判概率及平均误判概率表1.3表明把第一组误判的概率为0,将第二组误判给第一组的概率为0.08.平均误判概率为0.04..表1.4先验概率不同情况下的贝叶斯判别表1.4为在先验概率p1=0.8,p2=0.2的情况下运动员归属的判别。
其中9,11,12,14判给第二组,其余均判给第一组。
由表可以看出先验概率不同得到的判别是不同的。
例如第60号(第8个未定级)运动员判给了第一组,而在概率相同时时判给了第二组。
练习2(1)程序代码(2)结果及分析表2.1费希尔判别系数费希尔判别式为xxxxxxxxy87654321103687468.0195246015.0202200109.0420281838.1 00763493.0837675738.0369109646.0022344104.0-+++ --+=xxxxxxxxy876543212026966644.0235306430.0203863959.0039957871.1006017311.0386499597.0332405063.0045417606.0+++-++++-=表2.2判别式得分散点图表2.2中1代表通用牛奶厂商,2代表克罗格厂商,3代表夸克厂商。
(003)(课程设计报告)(10065012)(舒焕)
表达式类型的实现一目的熟练掌握《数据结构》课程的相关知识,完成一个具有一定难度的综合设计题目,熟练使用c/c++语言进行程序设计,并且规范完成课程设计报告。
巩固《数据结构》里的字符串,树等理论知识的理解,掌握现实复杂问题的分析建模和解决方法,提高利用计算机分析解决综合性实际问题的基本能力。
二需求分析1、功能1、将前缀表达式输入到字符串数组中,并且存储到二叉树中。
2、将二叉树中的表达式以中缀的表达式形式输出,有必要的地方加()。
3、对存储前缀表达式的字符串数组进行查询,有未知变量的进行赋值,并且赋值完后存储到该字符串数组中。
并且更新二叉树里的数据。
4、对已经赋值完了的二叉树进行求值。
2、输入输入的形式以字符串的形式输入到字符串数组中,并且输入的数字字符都是个位数的运算,不能执行十位以上的运算。
可以输入未知变量,如a,b,c,当对未知变量赋值时,未知变量可以是十位以上的数字,但在运算过程中,结果不得超过256,也就是asc码的范围。
例如输入0;a;-91;+a*b5;+-9/62-ab4。
3、输出该程序的输出分为两步,第一步:将前缀表达式转化为中缀表达式,存储到字符串数组中,并输出;第二步:输出表达式测试的结果,并判断是否正确。
对上面的输入,正确的输出应该为0;a;9-1;a+b*5;9-6/2*(a-b)+4;三概要设计1、变量定义宏定义的有,MAXSTR,表示表达式的长度最大限度。
全局变量定义,char 类型的str[MAXSTR],用来存储前缀表达式;char 类型的str1[MAXSTR],用来存储中缀表达式,并且有必要加括号的时候也包含括号;结构体类型的树和全局变量树指针T,具体定义如下:typedef struct BitNode{unsigned char data;int status;struct BitNode *lchild,*rchild;}BitNode,*BitTree;Int 类型的overflow,表示当数据大于256时,溢出,不能用符号的asc码表示,需要做一定的处理,int 类型的m,用来存储溢出时是256的多少倍。
数据结构课程设计可选题目
1.背包问题的求解2.全国交通咨询模拟3.一元稀疏多项式计算器4.马踏棋盘5.电梯模拟6.重言式判别7.教学计划编制8.全国交通咨询模拟9.运动会分数统计10.订票系统11.文章编辑12.约瑟夫环(Joseph)13.校园导游程序14.任意长的整数加法15.通讯录管理系统的设计与实现.16.产品进销存管理系统17..学生信息管理系统的设计与实现18.简易电子表格的设计19.教师信息管理系统的设计与实现20.电话号码查询系统21.二叉排序树与平衡二叉树的实现22.仓库管理系统23.农夫过河问题的求解24.图书管理信息系统的设计与实现25.客户消费积分管理系统26.商店售货管理系统的设计与实现27.家谱管理系统28.排序算法比较29.算术表达式求值30.职工工资管理系统的设计与实现31.房屋销售管理信息系统的设计与实现32.电视大赛观众投票及排名系统33.超市管理信息系统的设计与实现34.药店的药品销售统计系统35.教师职称管理系统的设计与实现36.宾馆客房管理系统的设计与实现37.航空售票处的服务系统38.营业窗口队列模拟39.迷宫问题40.八皇后问题41.运算器42.稀疏矩阵运算器43.电话号码查询系统44.停车场模拟管理程序的设计与实现45.哈夫曼编/译码的设计与实现46.班级学生成绩管理系统47.个人书籍管理系统的设计与实现48.稀疏矩阵的应用49.银行业务模拟50.最小生成树的Prime算法实现51.最小生成树的Kruskal算法实现52.链式串的实现53.多项式运算的实现54.数制转换问题55.关键路径求解56.纸牌游戏57.宿舍管理查询软件58.活期储蓄帐目管理59.手机通讯录的制作60.H TML文档标记匹配算法。
重言式判别课程设计报告
合肥学院计算机科学与技术系课程设计报告2016~2017学年第1学期课程数据结构与算法课程设计题目名称重言式的判别学生姓名王芳学号1404011018专业班级计算机科学与技术14级1班指导教师李红何立新2016年9月一、题目【问题描述】一个逻辑表达式如果对于其变元的任一种取值都为真,则称为重言式;反之,如果对于其变元的任一种取值都为假,则称为矛盾式;然而,更多的情况下,既非重言式,也非矛盾式。
试写一个程序,通过真值表判别一个逻辑表达式属于上述哪一类。
【基本要求】(1) 逻辑表达式从终端输入,长度不超过一行。
逻辑运算符包括"|","&" 和"~",分别表示或、与和非,运算优先程度递增,但可由括号改变,即括号内的运算优先。
逻辑变元为大写字母。
表达式中任何地方都可以含有多个空格符。
(2) 若是重言式或矛盾式,可以只显示"True forever",或"False forever",否则显示"Satisfactible" 以及变量名序列,与用户交互。
若用户对表达式中变元取定一组值,程序就求出并显示逻辑表达式的值。
【测试数据】(1) (A|~A)&(B|~B)(2) (A&~A)&C(3) A|B|C|D|E|~A(4) A&B&C&~B(5) (A|B)&(A|~B)(6) A&~B|~A&B;O ,0;0,1;1,0;1,1 。
二、问题分析1、一个逻辑表达式如果对于其变元的任一种取值均为真,则称为重言式;反之,如果对于其变元的任一种取值都为假,则称为矛盾式,若对于其变元的任一种取值既有真,又有假,则称其为可满足式。
写一个程序通过真值表判别一个逻辑表达式属于上述哪一类。
基本要求如下:1)逻辑表达式从终端输入,长度不超过一行。
Fisher判别法课程设计
Fisher判别法课程设计一、课程目标知识目标:1. 理解Fisher判别法的原理和数学推导过程;2. 学会运用Fisher判别法解决实际问题,如对给定的数据集进行判别分析;3. 掌握Fisher判别法在统计学习中的应用范围和限制。
技能目标:1. 能够运用所学软件(如R、Python等)实现Fisher判别法的计算过程;2. 能够通过实际案例,运用Fisher判别法对数据进行预处理和特征提取;3. 能够分析判别结果,对模型的性能进行评估和优化。
情感态度价值观目标:1. 培养学生独立思考、团队协作的能力,激发学生学习统计学习的兴趣;2. 培养学生面对实际问题,敢于尝试、勇于探索的精神;3. 增强学生对我国在统计学习领域取得的成果的认识,提高国家自豪感。
课程性质:本课程为高年级统计学或相关专业的专业课程,旨在让学生掌握Fisher判别法这一经典统计学习方法。
学生特点:学生已具备一定的数学基础和统计学知识,具有一定的编程能力。
教学要求:通过本课程的学习,使学生能够将Fisher判别法应用于实际问题,并具备独立解决实际问题的能力。
教学过程中注重理论与实践相结合,培养学生的实际操作能力和创新精神。
教学评估将以学生在实际案例中的应用表现为主,注重学生的过程学习和能力提升。
二、教学内容1. 引入Fisher判别法的背景和基本概念,介绍Fisher线性判别和Fisher二次判别的原理;- 教材章节:第三章“判别分析”,第一节“Fisher判别法”;- 内容安排:讲解Fisher判别法的数学推导,分析线性与二次判别的区别及适用场景。
2. 讲解Fisher判别法的计算步骤和实际应用案例;- 教材章节:第三章“判别分析”,第二节“Fisher判别法的计算与应用”;- 内容安排:通过实际案例,演示Fisher判别法的计算过程,分析判别效果。
3. 学习使用统计软件(如R、Python)实现Fisher判别法;- 教材章节:第三章“判别分析”,第三节“Fisher判别法的软件实现”;- 内容安排:教授学生如何利用统计软件进行Fisher判别法的计算,掌握相关函数和操作。
重言式判别
重言式判别#include<stdio.h>#include<math.h>#include<stdlib.h>#define ok 1#define error 0#define overflow 0 typedef struct array{int quan;char data;}array;typedef struct bitnode {char data;struct bitnode *rchild;struct bitnode *lchild; } bitnode,*bitree;array ary[100];char a[100];void initary( int n){int i,j;for(i=0;i<=n;i++){ary[i].data=a[i];if(ary[i].data=='~')ary[i].quan=3;else if(ary[i].data=='&')ary[i].quan=2;else if(ary[i].data=='|')ary[i].quan=1;else if(ary[i].data=='('||ary[i].data==')')ary[i].quan=-1;elseary[i].quan=0;}for(i=0;i<=n;i++){if(ary[i].data=='(')for(j=i;j<n;j++){if(ary[j].quan>0)ary[j].quan+=4;}if(ary[i].quan<min&&ary[i].quan>0){min=ary[i].quan;k=i;}return k;}//寻找运算符中权值最小的int deletek(int n){int i,j,k;k=n;for(i=0;i<=n;i++)if(ary[i].data=='('||ary[i].data==')'){k--;for(j=i;j<=n;j++)ary[j]=ary[j+1];}for(i=0;i<=k;i++)printf("%c",ary[i].data);printf("\n");return k;}//删除带权数组中的括号,保证建的树中没有括号,叶子节点全是变元void createbitree(bitree &T,int m1,int m2){//开始出错是m1<=m2,没分开int i;if(m1<m2){i=searchmin(m1,m2);if(!(T=(bitnode * )malloc(sizeof(bitnode))))exit(overflow);elseT->data=ary[i].data;createbitree(T->lchild,m1,i-1);createbitree(T->rchild,i+1,m2);}else if(m1==m2){if(!(T=(bitnode* )malloc(sizeof(bitnode))))exit(overflow);T->data=ary[m1].data;T->lchild=NULL;T->rchild=NULL;}elseT=NULL;//出错当是~时,后面无法输出,只有右子树,没有左子树}char as[20];void inorder(bitree T){if(T){inorder(T->lchild);printf("%c",T->data);inorder(T->rchild);}}char s[20]={0};int b[20][20]={0};int countleaf(bitree T,int &i,int j){{if(T->lchild==NULL&&T->rchild==NULL) {int k=0;for(j=0;j<i;j++){if(T->data==s[j]){k=1; break;}}if(k==0){s[i]=T->data;printf("%c",T->data);i++;}}countleaf(T->lchild,i,j);countleaf(T->rchild,i,j);}return i;}char rcountleaf(bitree T,int &i,int j,int m){{if(T->lchild==NULL&&T->rchild==NULL) {int k=0;for(j=0;j<i;j++){if(T->data==s[j]){k=1; break;}}if(k==0){s[i]=T->data;i++;}}rcountleaf(T->lchild,i,j,m);rcountleaf(T->rchild,i,j,m);}return s[m];}int sum(bitree T,int m,int j){int i;if(T){if(T->data=='&'){T->data=sum(T->lchild,m,j)&&sum(T->rchild ,m,j);}else if(T->data=='|')T->data=sum(T->lchild,m,j)||sum(T->rchild,m ,j);else if(T->data=='~')T->data=!sum(T->rchild,m,j);else{for(i=0;i<j;i++){if(T->data==as[i]){T->data=b[m][i];break;}}}}return T->data;}void main(){ printf("请输入要判断的表达式:"); char c;int i=0,n,k,s,j,m,count=0,d,f; bitree T;c=getchar();while(c!='\n'){if(c!=' '){a[i]=c;i++;}c=getchar();}n=i-1;printf("要判断的表达式是:"); for(i=0;i<=100;i++)printf("%c",a[i]);printf("\n");//输入表达式并输出initary(n);k=0;//printf("%d %d\n",k,n);d=deletek(n);createbitree(T,k,d);inorder(T);printf("\n");i=0;j=0;printf("输出所有变元:");j=countleaf(T,i,j);printf("\n");printf("变元的个数是:%d",j); printf("\n");for(m=0;m<j;m++){k=n=0;as[m]=rcountleaf(T,k,n,m); printf("%c\n",as[m]);}//建立数组存变元printf("\n");s=1;for(k=j;k>0;k--)s=2*s;printf("变元的可能取值有%d种\n",s);//输出选择的个数n=s;for(m=0;m<s;m++){n=n-1;k=n;for(i=0;i<j;i++){b[m][i]=k%2;k=k/2;}}//for(m=0;m<s;m++)//{//for(i=0;i<j;i++)//printf("%d ",b[m][i]);//printf("\n");//}//printf("所有可能取值输入完毕\n");for(m=0;m<s;m++){k=0;createbitree(T,k,d);n=sum(T,m,j);//调用函数里的m不变?//printf("%d\n",n);if(n==1)count++;}if(count==0)printf("False forever\n");else if(count==s)printf("True forever\n");else{printf("Satisfactible\n");for(f=0;f<s;f++){k=0;m=0;createbitree(T,k,d);printf("请输入变量的值:");for(i=0;i<j;i++)scanf("%d",&b[m][i]);n=sum(T,m,j);printf("%d\n",n);}}}。
数据结构报告—重言式判别
实习报告题目:重言式判别班级:计算机学院12052313 姓名:卢魏旭学号:12051521 完成日期:2012年11月一、需求分析试写一个程序,通过真值表判断一个逻辑表达式属于哪一类的表达式基本要求:1)逻辑表达式从终端输入,长度不超过一行,逻辑运算符包括“|”,“&”和“~”,分别表示或,与和非,运算优先程度递增,但可以由括号改变,即括号内的运算符优先。
逻辑变元为大写字母,表达式中任意地方都可以含有空格符。
2)若是重言式或者矛盾式,可以只显示“True forever”或者“False forever”,否者显示“Statisfactible”,与用户交互,若用户对表达式中变元取定一组值,程序就求出并显示逻辑表达式的值。
3)附加要求,可以根据用户要求,列出该逻辑表达式的真值表。
测试数据:1) (A|~A)&(B|~B)2) (A&~A)&C3) A|B|C|D|E|~A……二、概要设计为实现上述程序功能,以二叉树的结构来存储逻辑表达式,通过一个辅助栈来完成建树过程二叉树的抽象数据类型定义为:ADT Bitree{数据对象 D:D是具有相同特性的数据元素的集合数据关系 R:基本操作:creatbitree(&B,&S1,&S2,*a)初始条件:树B,栈S1,S2存在操作结果:通过两个辅助的栈S1,S2将元素a值建在二叉树内showtree(B)初始条件:二叉树B存在操作结果:先序遍历二叉树,输出每一个节点中的信息(用于检测)voluation($B,c,value)初始条件:二叉树B存在操作结果:通过先序遍历二叉树,对树中变量为c的结点赋值value excel(B,i,c,v[],*x)初始条件:二叉树存在操作结果:通过递归的算法在一维数组v[]中记录各个变量各种赋值情况(所有赋值情况的真值结果记录)}此外以栈的存储结构做辅助栈的抽象数据类型定义为:ADT Bstack{数据对象:D={a|ai<-ElemSet,i=1,2,3…n}数据关系:R1={<ai-1,ai>|ai-1,ai<-D,i=1,2,3…n}基本操作:creatstack(&S)操作结果:建立一个空栈SPushstack(&S,&B)初始条件:栈S存在操作结果:将一个二叉树的结点入栈Popstack(&S,&B)初始条件:栈S存在操作结果:从栈中取出一个二叉树的结点showstack(S)初始条件:栈S存在操作结果:访问栈内结点,查看元素信息Gettop(S)初始条件:栈S存在操作结果:返回栈顶元素}三、详细设计#include<stdio.h>#include<malloc.h>#include<windows.h>#include<math.h>typedef struct BiTnode{char data;int value;struct BiTnode *lchild,*rchild;}*Bitree;typedef struct Bstack{Bitree *top;Bitree *base;};void creatstack(Bstack &S){S.base=(Bitree*)malloc(sizeof(BiTnode));S.top=S.base;}void Pushstack(Bstack &S,Bitree &B){*S.top=B;S.top++;}void Popstack(Bstack &S,Bitree &B){S.top--;B=*S.top;}Bitree Gettop(Bstack S){return *(S.top-1);}int Judge(char c) //判断字符是运算符还是操作符{if(c>='A'&&c<='Z'||c>='a'&&c<='z'||c=='0'||c=='1') return 1;elsereturn 0;}char compare(char c1,char c2) //比较两个运算符的优先级{char c='-1';switch(c1){case '|':switch(c2){case '|':c='>';break;case '&':c='<';break;case '~':c='<';break;case '(':c='<';break;case ')':c='>';break;case '#':c='>';break;}break;case '&':switch(c2){case '|':c='>';break;case '&':c='>';break;case '~':c='<';break;case '(':c='<';break;case ')':c='>';break;case '#':c='>';break;}break;case '~':switch(c2){case '|':c='>';break;case '&':c='>';break;case '~':c='>';break;case '(':c='<';break;case ')':c='>';break;case '#':c='>';break;}break;case '(':switch(c2){case '|':c='<';break;case '&':c='<';break;case '~':c='<';break;case '(':c='<';break;case ')':c='=';break;}break;case ')':switch(c2){case '|':c='>';break;case '&':c='>';break;case '~':c='>';break;case '(':c='>';break;case ')':c='>';break;case '#':c='>';break;}break;case '#':switch(c2){case '|':c='<';break;case '&':c='<';break;case '~':c='<';break;case '(':c='<';break;case '#':c='=';break;}break;}return c;}void showstack(Bstack S){while(S.base!=S.top){S.top--;printf("%c\n",(*S.top)->data);}}int creatBiTree(Bitree &B,Bstack &S1,Bstack &S2,char *a) //S1为a操作符栈,为运算数栈建立二叉树过程类似于算术表达式求值{int i=0,len=0,flag=1;char c;Bitree b1;b1=(Bitree)malloc(sizeof(BiTnode));b1->data='#';b1->value=0;b1->lchild=NULL;b1->rchild=NULL;Pushstack(S1,b1); //先在运算符栈里存放一个data值为“#”的结点做标记while(a[i]){len++;i++;}i=0;c=a[0];while(c!='#'||Gettop(S1)->data!='#'){c=a[i];if(c==' ') //若有空格,直接忽略掉{i++;continue;}if(i>=len){c='#';}Bitree b;b=(Bitree)malloc(sizeof(BiTnode)); 建立一个树的结点b->data=c;b->value=0;b->lchild=NULL;b->rchild=NULL;if(Judge(c)){Pushstack(S2,b); //若是操作数的结点则进栈i++;continue;}else{char c1=compare(Gettop(S1)->data,c);if(c1=='-1'){flag=0;break;}switch(c1){case '<':printf("执行D“<”:\n ");Pushstack(S1,b);i++;break;case '=':printf("执行D“=”: \n");if(c!='#'){Popstack(S1,b);i++;break;}elsebreak;case '>':printf("执行D“>”: \n"); //如果栈顶运算符优先级高,则先建立二叉树char c2=Gettop(S1)->data;Bitree a0,a1; //先取一个运算符和一个操作数,将操作数连接在运算符的右孩子上Popstack(S1,a0);Popstack(S2,a1);a0->rchild=a1;if(c2!='~') //如果不是“~”运算符,再取一个结点连接在运算符结点的左孩子上{Bitree a2;Popstack(S2,a2);a0->lchild=a2;Pushstack(S2,a0);}elsePushstack(S2,a0);}}}if(flag) //表达式输入无误则继续进行{B=Gettop(S2);return 1;}elsereturn 0;}void caculate(Bitree B) //采用后序遍历判断逻辑表达式的真值{if(B){caculate(B->lchild);caculate(B->rchild);switch(B->data){case '|':B->value=B->lchild->value||B->rchild->value;break;case '&':B->value=B->lchild->value&&B->rchild->value;break;case '~':B->value=!B->rchild->value;break;case '0':B->value=0;break;case '1':B->value=1;break;}}}void showtree(Bitree B) //先序遍历二叉树{if(B){printf("%c ",B->data);showtree(B->lchild);showtree(B->rchild);}}void voluation(Bitree B,char c,int value)//采用先序遍历为二叉树的变量赋值{if(B){if(B->data==c)B->value=value;voluation(B->lchild,c,value);voluation(B->rchild,c,value);}}void show(char *a){int i=0;while(a[i]){if(a[i]==' '){i++;continue;}printf("%c",a[i]);i++;}}void excel(Bitree B,int i,char *c,int v[],int *x) //采用递归算法为所有的变量赋值,用数组v[]记录下每一种变量复制后逻辑表达式的真值{if(c[i]!='0'){voluation(B,c[i],0);i++;excel(B,i,c,v,x);i--;voluation(B,c[i],1);i++;excel(B,i,c,v,x);}else{caculate(B);v[*x]=B->value;(*x)--;}}int search(char *a,char *ch) //查找表达式中的变量,放入ch[]数组中{int i=0,k=0,flag=1;while(a[i]){if(a[i]>='A'&&a[i]<='Z'){int j=0;while(ch[j]!='0'){if(ch[j]==a[i]){flag=0;break;}j++;}if(flag){ch[k]=a[i];k++;}}i++;flag=1;}// printf("%d \n",k);return k;}char Judge2(int *v) //根据所有赋值情况,判断逻辑表达式是哪种类型的{int i=0,flag1=0,flag2=0,flag3=0;while(v[i]!=-1){if(v[i]==0)flag1=1;if(v[i]==1)flag2=1;if(flag1&&flag2)return 'O';i++;}if(flag1)return 'F';if(flag2)return 'T';}void selfvoluation(Bitree b,char ch[],char a[]) //用户自行赋值{printf("是否自行为表达式赋值以计算真值?(Y/N)\n");char c;c=getchar();if(c=='Y'||c=='y'){int k=0,x;while(ch[k]!='0'){printf("为%c赋值:êo%c=",ch[k],ch[k]);scanf("%d",&x);while(x!=0&&x!=1){printf("赋值有误!!请重新输入:");scanf("%d",&x);}voluation(b,ch[k],x);k++;}caculate(b);printf("表达式? ");show(a);printf(" 的真值为%d\n",b->value);}}void change(int *b,int x,int sum) //将十进制转换为二进制{while(x!=0){b[sum]=(x%2);x=x/2;sum--;}}void TrueExcel(char *a,char *ch,int j,int *v2,int *v1) //输出真值表{int i=0;while(ch[i]!='0'){printf("%c ",ch[i]);i++;}printf("|");show(a);printf("\n");for(int l=0,m=pow(2,(double)j)-1;l<pow(2,(double)j);l++,m--){change(v2,l,j-1);for(int k=0;k<j;k++){if(v2[k]==-1)printf("0 ");elseprintf("%d ",v2[k]);}printf("| %d\n",v1[m]);}}void main(){int j=0,i=0,n,v1[200],v2[200],flag=0;Bitree b;Bstack S1,S2;creatstack(S1);creatstack(S2);char a[100],ch[10]; //a[]记录表达式,ch[]记录变量值for(int k=0;k<10;k++) //初始化变量数组ch[k]='0';for(int m=0;m<200;m++) //初始化真值表数组{v2[m]=-1;v1[m]=-1;}gets(a); //输入表达式j=search(a,ch); //获取所有变量的个数yn=pow(2,(double)j)-1; //要赋值的次数flag=creatBiTree(b,S1,S2,a); //根据表达式建立二叉树if(flag){excel(b,0,ch,v1,&n); //计算所有变量赋值的真值switch(Judge2(v1)){case 'T':printf("表达式为永真式\n");break;case 'F':printf("表达式为永假式\n");break;case 'O':printf("表达式为不确定式\n");selfvoluation(b,ch,a);break;}}elseprintf("表达式输入有误\n");TrueExcel(a,ch,j,v2,v1);system("PAUSE");}四、调试分析1、本程序实现了逻辑表达式的求值,判断,以及真值表的输出,程序的难点在于逻辑表达式的二叉树建立,以及其判断,二叉树的建立creatbitree()依靠两个工作栈实现的,形式类似于算术表达式的求值,不过这里是建树,存放变量的结点作为叶子结点,存放运算符的结点作为根结点,这是自底向上的算符优先法,第二个难点在于对所有的变量的所有情况赋值,这里采用了简单的递归算法,这个算法我自己做的时候花了很长时间来想,excel()递归时候,对每个变量有0和1两种赋值情况,每当递归到最顶层时,调用caculate()算法计算一次真值,然后将值存放到函数携带的一维数组中去。
重言式判别——精选推荐
重⾔式判别题⽬参见:清华⼤学出版社的《数据结构题集(C语⾔版)》 P148 5.1刚开始时不知道从哪⾥下⼿,尤其是将输⼊的字符串序列建⽴成⼆叉树,⾃⼰想了半天越想越复杂,于是决定不浪费时间去⽹上直接找解题思路,发现通过构建加权字符数组的⽅法很不错,整体思路有了就动⼿实现吧,整个过程中对递归的应⽤很多,更加体会到了递归的美妙之处啊。
= v =。
中间⽐较纠结的是判别是否永真或永假,尤其是每进⾏⼀次运算会改变⼆叉树中原先的变元,最初没有考虑到这个结果很多都是直接跳到了结果,没有判断过程。
本来以为构造出⼆叉树之后后⾯的⼯作会简单⼀些,结果还是耗了很长时间。
= =||,⾼兴太早了麽,,,代码就堆在下⾯了。
代码1 #include <stdio.h>2 #include <stdlib.h>3 #include <string.h>45 typedef struct DutyElement6 {7char data;8int duty;9 }DutyElement;1011 DutyElement DutyArray[100]; //定义加权数组1213 typedef struct BiTNode14 {15char data;16struct BiTNode *lchild, *rchild;17 }BiTNode, *BiTree;1819void InitDutyArray(char *s, int n) //根据输⼊的序列初始化加权数组20{21int i, j;22for (i = 0; i < n; i++)23 {24 DutyArray[i].data = s[i];25switch (DutyArray[i].data) //分别赋权值26 {27case'~':28 DutyArray[i].duty = 3; break;29case'&':30 DutyArray[i].duty = 2; break;31case'|':32 DutyArray[i].duty = 1; break;33default:34 DutyArray[i].duty = 0; break;35 }36 }37for (i = 0; i < n; i++)38 {39if (DutyArray[i].data == '(') //是左括号的话则对运算符进⾏加权操作40 {41for (j = i; j < n; j++)42 {43if (DutyArray[j].duty != 0)44 DutyArray[j].duty += 5;45 }46 }47else48 {49if (DutyArray[i].data == ')') //右括号的话对运算符进⾏减权操作50 {51for (j = i; j < n; j++)52 {53if (DutyArray[j].duty != 0)54 DutyArray[j].duty -= 5;55 }56 }57 }58 }59 }6061int SearchMinDutyOperator(int a, int b) //寻找权值最⼩的运算符,即为⼆叉树的根节点62{63int i, n = a, duty = 1000;64for (i = a; i < b + 1; i++)65 {66if (DutyArray[i].duty > 0 && DutyArray[i].duty < duty)67 {68 n = i;69 duty = DutyArray[i].duty;70 }71 }72return n;73 }7475int ParenthesesCloesed(int a, int b) //判断序列是否在最外层有⼀对括号76{77int i, n = 0;78for (i = a; i <= b; i++)79 {80if (DutyArray[i].data == '(')81 n++;82if (DutyArray[i].data == ')')83 n--;84if (n == 0)85break;86 }87if (i == b)88return1;89else90return0;91 }9293 BiTree Create(int a, int b) //根据加权数组创建⼆叉树94{95 BiTree p;96if (DutyArray[a].data == '(' && DutyArray[b].data == ')' && ParenthesesCloesed(a, b) == 1) //去括号97 {98 a += 1;99 b -= 1;100 }101if (a > b)102 p = NULL;103else104 {105if (a == b)106 {107 p = (BiTNode *)malloc(sizeof(BiTNode));108 p->data = DutyArray[a].data;109 p->lchild = NULL;110 p->rchild = NULL;111 }112else113 {114int n;115 n = SearchMinDutyOperator(a, b);116 p = (BiTNode *)malloc(sizeof(BiTNode));117 p->data = DutyArray[n].data;118 p->lchild = Create(a, n - 1);119 p->rchild = Create(n + 1, b);120 }121 }122return p;123 }124125void AssignValue(BiTree T, char letter, char binary) //递归为对应的字母赋⼆进制字符126 {127if (T)128 {129if (T->data == letter)130 T->data = binary;131 AssignValue(T->lchild, letter, binary);132 AssignValue(T->rchild, letter, binary);133 }134 }135136int Calculate(BiTree T) //递归计算⼆进制字符⼆叉树137 {138switch (T->data)139 {140case'0':141return0;142case'1':143return1;144case'~':145return !Calculate(T->rchild);146case'&':147return (Calculate(T->lchild) & Calculate(T->rchild));148case'|':149return (Calculate(T->lchild) | Calculate(T->rchild));150 }151 }152153void main()154 {155 BiTree T;156int m = 0, n, i, j, k, length = 0, strlength, num = 1, flag;157char value[20] = {0};158char s[100] = {0};159char c, *str;160 str = (char *)malloc(sizeof(char) * 20);161for (i = 0; i < 20; i++)162 {163 *(str + i) = 0;164 }165 c = getchar();166 i = 0;167while (c != '\n')168 {169if (c != ' ')170 {171 s[i] = c;172 i++;173 }174 c = getchar();175 }176for (i = 0; i < 100; i++)177 {178if (s[i] == 0)179 {180 n = i; //n为输⼊序列的长度181break;182 }183 }184for (i = 0; i < n; i++)185 {186if (strchr(s, 'A' + i) != NULL)187 length++;188else189break;190 }191 length = i;192 InitDutyArray(s, n); //初始化加权数组193 T = Create(0, n - 1);194for (i = 0; i < length; i++)195 {196 AssignValue(T, 'A' + i, '0');197 }198 flag = Calculate(T);199for (i = 0; i < length; i++)200 {201 num *= 2;202 }203for (i = 0; i < num; i++)204 {205 T = Create(0, n - 1); //由于每运算⼀次会将原来的⼆叉树中的变元改变,所以得重新构造206 itoa(i, str, 2);207 strlength = strlen(str);208for (j = 0; j < length; j++)209 {210if (strlength - j - 1 >= 0)211 value[length - j - 1] = *(str + strlength - 1 - j);212else213 value[length - j - 1] = '0';214215 }216for (k = 0; k < length; k++)217 {218 AssignValue(T, 'A' + k, value[k]);219 }220if (Calculate(T) != flag)221 {222 printf("Satisfactible\n");223break;224 }225else226 {227if (i == num - 1 && flag == 1)228 {229 printf("True forever\n");230return;231 }232if (i == num - 1 && flag == 0)233 {234 printf("False forever\n");235return;236 }237 }238 }239for (i = 0; i < length; i++)240 {241 printf("%c ", 'A' + i);242 }243 printf("\n");244 c = getchar(); //输⼊对各字符的赋值,保存在value数组中245 i = 0;246while (c != ';')247 {248if (c != ',')249 {250 value[i] = c;251 i++;252 }253 c = getchar();254 }255 T = Create(0, n - 1); //重新构造⼆叉树256for (i = 0; i < length; i++)257 {258 AssignValue(T, 'A' + i, value[i]);259 }260 printf("The result is %d\n", Calculate(T));261 }。
2a重言式、蕴含式
[¬p ∧(p ∨q )]→q
T T T F F T F F
Tautology by truth table
p q ¬p p ∨q F F T T T T T F ¬p ∧(p ∨q ) F F T F [¬p ∧(p ∨q )]→q T T T T
17
T T T F F T F F
Tautology by proof
18
练习:
课本P23习题 (1)
19
定义蕴含式
当仅当P→Q是一个重言式时,我们称 “ P 蕴含 Q ”,并记作 P⇒Q ⇒
P→Q的 逆换式: → 逆换式: Q→P 反换式: 反换式: ┑P → ┑Q 逆反式: 逆反式: ┑Q → ┑P ( P→Q) ⇔ (┑Q → ┑P) (┑P→ ┑Q) ⇔ (Q→P)
new!
定义重言式、矛盾式
给定一命题公式,若无论对分量作怎 样的指派,其对应的真值永远为T,则称该 命题公式为重言式或永真式。 DEF: A compound proposition is called a tautology if no matter what truth values its atomic propositions have, its own truth value is T. EG: p ∨ ¬p (Law of excluded middle)
12
Tautology by truth table
p q ¬p p ∨q ¬p ∧(p ∨q ) [¬p ∧(p ∨q )]→q
T T T F F T F F
13
Tautology by truth table
p q ¬p p ∨q F F T T
14
¬p ∧(p ∨q )
判别分析实验报告模板1
石家庄铁道大学实验报告课程名称:任课教师:实验日期:班级:姓名:学号:实验项目名称:判别分析一、实验目的及要求1. 通过上机操作使学生掌握判别分析方法在SPSS软件中的实现,了解判别方法的分类、适用条件和结果验证方法;2. 要求学生熟悉判别分析的用途和操作,重点掌握对软件处理结果的解释(区域图、未标准化典型判别函数、标准化典型判别函数等)和如何使用分析结果对新样品进行分类;3. 要求学生阅读一定数量的文献资料,掌握判别分析方法在写作中的应用。
二、实验环境1.系统软件:WindowsXP2.工具:SPSS16.0三、实验内容银行的贷款部门需要判别每个客户的信用好坏(是否未履行还贷责任),以决定是否给予贷款。
可以根据贷款申请人的年龄(X1)、受教育程度(X2)、现在所从事工作的年数(X3)、未变更住址的年数(X4)、收入(X5)、负债收入比例(X6)、信用卡债务(X7)、其它债务(X8)等来判断其信用情况。
文件“银行信用”包括从某银行的客户资料中抽取的部分数据。
⑴根据样本资料用Fisher判别法建立判别函数和判别规则。
⑵某客户的如上情况资料为(53,1,9,18,50,11.20,2.02,3.58),对其进行信用好坏的判别。
四、实验过程与步骤1、使用菜单中File→Open命令,然后选中要分析的数据文件“银行信用”2、选择Analyze→Classify→Discriminant,打开主对话框,将group移到“Grouping Variable”框中,激活Define Range,点击此按钮,进入定义范窗口,分别在“Minimum”和“Maximum”后面的矩形框中键入1与2,然后按“Continue”按钮返回主对话框。
3、在主对话框左边的矩形框中选择判别变量“贷款申请人的年龄(X1)、受教育程度(X2)、现在所从事工作的年数(X3)、未变更住址的年数(X4)、收入(X5)、负债收入比例(X6)、信用卡债务(X7)、其它债务(X8)”,并用下面一个箭头按钮将它们移到“Independents”矩形框中。
信息论课程设计报告
成绩:2016-2017学年第1学期《信息论》课程设计学院名称:班级学号:学生:教师:2016年12 月一、判定唯一可译码1. 任务说明输入:任意的一个码(即已知码字个数及每个具体的码字) 输出:判决结果(是/不是)输入文件:in1.txt ,含至少2组码,每组的结尾为”$”符 输出文件:out1.txt ,对每组码的判断结果说明:为了简化设计,可以假定码字为0,1串2. 实现原理判断方法:将码C 中所有码字可能的尾随后缀组成一个集合F ,当且仅当集合F 中没有 包含任一码字,则可判断此码C 为唯一可译变长码。
构成集合F :首先观察码C 中最短的码字是否是其他码字的前缀。
若是,将其所有可能 的尾随后缀排列出。
就是将其他码字序列中截去与其最短码字相同的前缀 部分,将余下的序列为尾随后缀。
而这些尾随后缀又可能是某些码字的前 缀,或者最短码字又仍是这些尾随后缀的前缀,再将由这些尾随后缀产生 的新的尾随后缀列出。
然后再观察这些新的尾随后缀是否是某些码字的前 缀,或观察有否其他码字是这些新的尾随后缀的前缀,再将产生的尾随后 缀列出,依次下去,直至没有一个尾随后缀是码字的前缀或没有新的尾随 后缀产生为止。
这样,首先获得的是由最短码字能引起的所有尾随后缀。
接着,按照上述步骤将次短的码字、......所有码字可能产生的尾随后缀前部列出。
由此得到由码C 的所有可能的尾随后缀组成的集合F 。
参考算法伪代码:For all ,i j W W C ∈ doif i W 是j W 的前缀 then将相应的后缀作为一个尾随后缀放入集合0F 中 End if End forLoopFor all i W C ∈ doFor all j n W F ∈ doif i W 是j W 的前缀 then将相应的后缀作为一个尾随后缀放入集合1n F +中 Else if j W 是i W 的前缀 then将相应的后缀作为一个尾随后缀放入集合1n F +中End if End for End for i i F F ←If ,i i W F W C ∃∈∈ thenReturn falseElse if F 中未出现新的元素 thenReturn true End if//能走到这里,说明F 中有新的元素出现,需继续End loop3. 实现源码#include <iostream> #include <fstream> #include <stdio.h> #include <string.h> using namespace std;#pragma warning (disable :4996) char c[100][50]; //保存码字 char f[300][50]; //保存尾随后缀int N, sum = 0; //N 为码字的个数,sum 为尾随后缀个数 int flag; //判断是否唯一可译标志位//检测尾随后缀void patterson(char c[], char d[]) { int i, j, k; for (i = 0;; i++) { If (c[i] == '\0'&&d[i] == '\0')//两字符串一样长,跳出 break ; if (c[i] == '\0') //d 比c 长,将d 的尾随后缀放入f 中 { for (j = i; d[j] != '\0'; j++) f[sum][j - i] = d[j]; f[sum][j - i] = '\0'; for (k = 0; k<sum; k++) { if (strcmp(f[sum], f[k]) == 0) /*查看当前生成的尾随后缀在f 集合中是否存在*/ { sum--; break ; } } sum++; break ;}if (d[i] == '\0') //c比d长,将c的尾随后缀放入f中{for (j = i; c[j] != '\0'; j++)f[sum][j - i] = c[j];f[sum][j - i] = '\0';for (k = 0; k<sum; k++){if (strcmp(f[sum], f[k]) == 0) /*查看当前生成的尾随后缀在f集合中是否存在*/{sum--; break;}}sum++;break;}if (c[i] != d[i])//字符不一样了也退出(前缀不同)break;}}void main(){int k = 0, N = 0, m = 0, a[50], z = 0;a[m] = N; m++;fstream file1;file1.open("out1.txt");//码字读取FILE *file;file = fopen("in1.txt", "r+");int num = fgetc(file) - 48;for (int n = 0; n < num; n++){int i = 0, j;if (fgetc(file) == ' ')N += (fgetc(file) - 48);else N += (fgetc(file) - 48);a[m] = N; m++;fgetc(file);for (k; k < N; k++){for (int q = 0;; q++){char temp = fgetc(file);c[k][q] = temp;if (temp == ' ' || temp == '$'){c[k][q] = '\0';break;}}}//生成尾随后缀flag = 0;for (i = a[z]; i<N - 1; i++)//判断码本身是否重复for (j = i + 1; j<N; j++){if (strcmp(c[i], c[j]) == 0){flag = 1; break;}}if (flag == 1)//如果码本身有重复,就可以断定它不是唯一可译码{for (int y = a[z]; y < N; y++)file1 << c[y] << ' ';file1 << "不是唯一可译码。
Fisher判别法课程设计
Fisher判别法课程设计一、教学目标本节课的教学目标是使学生掌握Fisher判别法的基本原理和应用方法。
知识目标包括:了解Fisher判别法的数学背景和原理,掌握Fisher判别函数的推导过程,理解Fisher判别法的应用场景。
技能目标包括:能够运用Fisher判别法解决实际问题,能够使用相关软件进行Fisher判别法的计算和分析。
情感态度价值观目标包括:培养学生的数据分析能力和科学思维,激发学生对统计学的兴趣和热情。
二、教学内容本节课的教学内容主要包括Fisher判别法的原理和应用。
首先,介绍Fisher判别法的基本概念和数学背景,解释判别函数的推导过程。
然后,通过实例分析,展示Fisher判别法在实际问题中的应用,如分类问题和判别分析。
最后,结合教材和课外资料,进行深入学习,探讨Fisher判别法的优缺点和适用条件。
三、教学方法为了达到本节课的教学目标,将采用多种教学方法相结合的方式进行教学。
首先,采用讲授法,系统地讲解Fisher判别法的原理和推导过程。
其次,通过案例分析法,引导学生运用Fisher判别法解决实际问题,培养学生的应用能力。
此外,还采用讨论法,鼓励学生积极参与课堂讨论,提出问题和观点,培养学生的思考能力和团队合作精神。
最后,利用实验法,让学生亲自动手进行实验,验证Fisher判别法的有效性,提高学生的实践能力。
四、教学资源为了支持本节课的教学内容和教学方法的实施,将准备以下教学资源。
首先,教材和相关参考书籍,为学生提供系统的学习材料。
其次,多媒体资料,如PPT和教学视频,用于辅助讲解和展示Fisher判别法的原理和应用。
此外,实验设备,如计算机和统计软件,用于学生进行实验和实践操作。
最后,网络资源,如学术期刊和在线课程,为学生提供更多的学习参考和拓展资料。
五、教学评估本节课的教学评估将采用多元化的评估方式,以全面、客观地评价学生的学习成果。
评估方式包括平时表现、作业和考试。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
合肥学院计算机科学与技术系课程设计报告2016~2017学年第1学期课程数据结构与算法课程设计题目名称重言式的判别学生姓名王芳学号**********专业班级计算机科学与技术14级1班指导教师李红何立新2016年9月一、题目【问题描述】一个逻辑表达式如果对于其变元的任一种取值都为真,则称为重言式;反之,如果对于其变元的任一种取值都为假,则称为矛盾式;然而,更多的情况下,既非重言式,也非矛盾式。
试写一个程序,通过真值表判别一个逻辑表达式属于上述哪一类。
【基本要求】(1) 逻辑表达式从终端输入,长度不超过一行。
逻辑运算符包括"|","&" 和"~",分别表示或、与和非,运算优先程度递增,但可由括号改变,即括号内的运算优先。
逻辑变元为大写字母。
表达式中任何地方都可以含有多个空格符。
(2) 若是重言式或矛盾式,可以只显示"True forever",或"False forever",否则显示"Satisfactible" 以及变量名序列,与用户交互。
若用户对表达式中变元取定一组值,程序就求出并显示逻辑表达式的值。
【测试数据】(1) (A|~A)&(B|~B)(2) (A&~A)&C(3) A|B|C|D|E|~A(4) A&B&C&~B(5) (A|B)&(A|~B)(6) A&~B|~A&B;O ,0;0,1;1,0;1,1 。
二、问题分析1、一个逻辑表达式如果对于其变元的任一种取值均为真,则称为重言式;反之,如果对于其变元的任一种取值都为假,则称为矛盾式,若对于其变元的任一种取值既有真,又有假,则称其为可满足式。
写一个程序通过真值表判别一个逻辑表达式属于上述哪一类。
基本要求如下:1)逻辑表达式从终端输入,长度不超过一行。
逻辑运算符包括“|”、“&”、“~”,分别表示或、与、非,运算优先程度递增,但可有括号改变,即括号内的运算优先。
逻辑变元为大写字母。
表达式中任何地方都可以含有多个空格符。
2)若是重言式或矛盾式,可以只显示“True Forever”或“False Forever”,否则显示运算中每种赋值和与其相对应的表达式的值。
2、通过真值表判别逻辑表达式是否为重言式,需解决以下问题:1)对逻辑表达式中空格符的处理。
为了方便对逻辑表达式进行扫描判断,应先去掉表达式中的空格符。
2)算符的优先级问题在带括号的表达式中,界限符包括左右括号以及表达式起始、结束符“#”。
对于一个简单的表达式求值运算规则如下:(1)从左至右依次计算。
(2)先取反,然后相与,后相或。
(3)先括号内,后括号外。
为统一算法的描述,将运算符和界限符统称为算符。
这样,算符集为{~,&,|,(,),#}。
根据上述3条规则,两个前后相继出现的算符a1,a2间的优先关系可以归纳如下:(1)若a1,a2同为“&”或同为“|”,则算符a1的优先级大于a2。
(2)“~”、“&”、“|”的优先级依次减小。
(3)由于先括号内,后括号外,若a1为“|”、“&”、“~”,a2为“(”;或者,a1为“(”,而a2为“|”、“&”、“~”,则a1的优先级小于a2。
(4)同理,若a1为“|”、“&”、“~”,a2为“)”;或者,a1为“)”,而a2为“|”、“&”、“~”,则a1的优先级大于a2。
(5)若a1、a2同为“(”,则a1的优先级小于a2;若a1、a2同为“)”,则a1的优先级大于a2。
(6)表达式的起始、结束符“#”的优先级小于其他所有合法出现的算符。
(7)若a1为“(”,a2为“)”;或者,a1、a2同为“#”,则a1、a2优先级相同。
综上所述,将两个相继出现的算符a1、a2的优先关系进行归纳如表1所示。
表1 算符a1和a2间的优先关系我们可以将逻辑表达式的计算类比算术表达式的计算,通常借助堆栈来实现按运算符的优先级完成表达式的求值计算。
一个是存放运算符栈,另一个是存放变量或中间结果栈。
(1)首先初始化算符栈logic和变量栈,并将表达式的起始符“#”压入算符栈logic。
(2)依次读入表达式中的每个字符。
若是变量,则为其分配结构node的size大小的内存,强制转换为bitree类型,并将其压入变量栈variable;若是运算符,则为其分配结构node的size大小的内存,强制转换为bitree类型,并与运算符栈logic的栈顶算符进行优先级比较,并作如下处理:①若栈顶算符a1的优先级低于刚读入的算符a2,则将a2压入运算符栈logic。
②若栈顶算符a1的优先级高于刚读入的算符a2,则将a1出栈,同时将变量栈variable出栈一次,得到变量A,再判断栈顶算符a1是否为“~”,如果a1不是“~”,则继续出栈变量栈variable一次,得到变量B,将a1作为根结点,B作为a1的左孩子,A作为a1的右孩子,并将根结点a1压入变量栈variable;如果栈顶算符a1是“~”,则将a1作为根结点,A作为a1的右孩子,a1的左孩子则为空,并将根结点a1压入变量栈。
③若栈顶算符a1优先级与刚读入的算符a2的优先级相同,说明左右括号相遇,或者是表达式的起始、结束符相遇,只需将栈顶算符(左括号或起始符)出栈即可;当运算符栈logic空时,算法结束这样就可以将逻辑表达式构造成一棵完整二叉树,根结点是优先级最小的算符(除了括号和起始结束符,在构造二叉树的过程中已被脱去)。
如(A|~A)&(B|~B)构造成的二叉树如图1所示图1 表达式构造的二叉树1)变量的赋值问题若只有1个变量,则有21种情况的赋值;若有2个变量,易知有22种情况的赋值;若有3各变量,则有23种情况的赋值,那么如果有n个变量,就有2n种情况的赋值。
既然要对变量进行赋值,首先要找到逻辑表达式中的变量,并确定变量的个数。
2)逻辑表达式取值的判断由上述对运算符的优先级的分析可知,对逻辑表达式的计算,就是中序遍历由优先级确定的逻辑表达式构成的二叉树。
5)重言式的判别可以将给变量的所有赋值的逻辑表达式的逻辑值相加,如果相加结果与2n 相等,则为重言式;若相加结果为0,则为矛盾式;否则为可满足式。
本问题的关键和难点在于算符优先级的判断和二叉树的构造。
三、数据结构的选择和概要设计1、数据结构的选择通过问题分析可知,需要用到的数据结构有堆栈和二叉树。
1)对于堆栈选用顺序栈结构来进行存放算符或变量,存放的都是二叉树的结点。
设有两个堆栈,一个是存放运算符栈,另一个是存放变量或中间结果栈。
2)对于二叉树,选用二叉树的链接存储结构,其结点存放得都是表达式中的元素。
将表达式构造成一棵二叉树。
2、概要设计从整体上可以分为三个模块:第一个模块:属于堆栈和二叉树结点类型的定义typedef struct stack //识别表达式使用的堆栈定义,它存放的都是树的结构{ //栈中的元素都是树的结点结构bitree *base; //栈底指针bitree *top; //栈顶指针int stacksize; //栈容量}seqstack;typedef struct node //根据表达式建立的二叉树的结点定义{char data;struct node *lchild;struct node *rchild;}BiTNode,*bitree;第二个模块:主要函数及其功能。
堆栈的创建void creatstack(sqstack &st){};初始化栈void setstack(seqstack &st){};进栈void push(sqstack &st,bitree e){};出栈void pop(sqstack &st,bitree &e){};将逻辑表达式中的元素转换为二叉树结点的形式,使栈中存储的都是二叉树的结点。
void creattree(char s[],bitree &tree){};通过优先级将逻辑表达式构造成一颗完整的二叉树void create(bitree &zigen,bitree l,bitree r){};对逻辑表达式求值int valuetree(bitree tree){};生成变量的各种取值组合void creatzuhe(int n,int m,char a[]){};逻辑运算符的优先级判别,返回值为“<”、“>”、“=”char youxianji(char m,char n){};第四个模块为于用户的交互void user(){};流程图:图2 程序流程图四、算法思想1、穷举法思想通过真值表来判断重言式,需要一一给变量赋值,共有2^n中情况(n表示变量的个数),这里用到穷举的思想。
2、递归与分治思想每给变量赋一组值,通过递归中序遍历二叉树求值,这里用到了递归与分治思想。
3、运算符的优先级判断思想(见问题分析算符的优先级问题分析第5页)五、详细设计和主要编码段首先将用户输入的逻辑表达式存到char *str当中,然后去除逻辑表达式中的空格符。
for(;*pstr!=NULL;pstr++,n++){if(str[n]!=' ') stri[i++]=*pstr; //去除表达式中的空格}此时stri当中存储的就是没有空格符的逻辑表达式。
通过问题分析,需找到表达式中的变量,并确定变量的个数。
下面的代码就是实现此功能。
for(int k=0;k<strlen(stri);k++)if(stri[k]>=65&&stri[k]<=90)//找到变量{int mark=0; //标记变量for(int j=0;j<m;j++){if(bl[j]==stri[k])//将找到的变量与bl[]中已找到过的变量比较,若相等则将变量标记置为1,表示找到的变量在前面已出现过{mark=1;break;}}if(mark==0)//若标记为0,表示找到的变量没有重复,并将其记录到bl[]中,变量个数m加1。
{bl[m]=str[k];m++;//m是变量个数}}此时bl[]当中存储的就是变量,m就是变量个数,那么变量赋值的情况就有2m种。
下面对生成变量的各种取值组合的算法进行分析和说明。
int zuhe[30]用来存储变量的取值组合,为了方便说明,采用两个变量进行算法叙述。
表2 变量赋值实例从表2可以发现给变量赋值的次数n与变量的取值组合成的二进制数相等,能得到一个规律:变量的取值组合zuhe[]二进制数(从低位到高位)的第i位数取值等于(n>>i)%2。