您的位置:首页 > 编程语言 > Java开发

离散数学输入表达式打印真值表和主析/合取范式

2016-09-17 21:38 267 查看
这是我们学校离散数学的作业题目,我用JAVA写的,不废话,上代码:

package lisanExperiment;

import java.io.BufferedReader;
import java.io.InputStreamReader;
public class li {
//用户输入的表达式(以字符串形式输入)
StringBuilder inputStr;
//用于作为inputStr的副本,当每次计算完成后重置inputStr
String inputStr2;
//flag代表表达式的结果
int flag=0;
//用于统计最初输入的表达式有几个括号
int count=0;
//用于控制递归次数
int COUNT;
//下面的数组用于存储真值表
int [][]table=new int[8][4];
//用于表示是否含有括号
boolean ifHas=false;
//用于存放P,Q,R
String[]pqr=new String[]{"P","Q","R"};
//用于让用户输入字符串的函数
public void input(StringBuilder string)
{
inputStr=string;
inputStr2=string.toString();
}
//每轮循环之后重置
public void restart()
{
inputStr=new StringBuilder(inputStr2);
}
//用于处理"!"运算符
public int changeI(int x)
{
if(x==0)
return 1;

return 0;
}
public String changeS(int x)
{
if(x==0)
return "1";

return "0";
}
//用于处理析取运算符
public int extract(int x,int y)
{
return (x|y);
}
//用于处理合取运算符
public int conjunct(int x,int y)
{
return (x&y);
}
//运算不同情况下的表达式值,x是P的值,y的Q的值,z是R的值
public void Calculate(int x,int y,int z)
{
// System.out.println("FIRST\t"+inputStr);
if(count==0&&ifHas==false)
{
for(int i=0;i<inputStr.length();i++)
{
if(inputStr.charAt(i)==')')
{
count++;
ifHas=true;
}
COUNT=count;
}
}
//System.out.println("COUNT"+COUNT);
if(COUNT!=0)
{
COUNT--;
for(int i=0;i<inputStr.length();i++)
{

if(inputStr.charAt(i)==')')
{
for(int j=i;;j--)
{

if(inputStr.charAt(j)=='(')
{
int result;
String[]strs=new String[3];
strs[0]=inputStr.substring(0,j);
strs[1]=inputStr.substring(j+1,i);
strs[2]=inputStr.substring(i+1);

StringBuilder s=new StringBuilder(strs[1]);
result=computeSim(s,x,y,z);
String string=strs[0]+result+strs[2];
inputStr= new StringBuilder(string);
//System.out.println("LAST\t"+inputStr);
break;
}
}
break;
}
}

if(COUNT!=0)
{
Calculate(x,y,z);
}
if(COUNT==0)
{
//System.out.println("我被调用了");
flag=computeSim(inputStr,x,y,z);
}
}
}
//用于计算最内侧括号里的值
public int computeSim(StringBuilder sb,int x,int y,int z)
{
//这是已经计算的部分的真值
int been=0;
for(int i=0;i<sb.length();i++)
{
if(sb.charAt(i)=='!')
{
if(sb.charAt(i+1)=='P')
sb.replace(i, i+2, changeS(x));
else if(sb.charAt(i+1)=='Q')
sb.replace(i, i+2, changeS(y));
else if(sb.charAt(i+1)=='R')
sb.replace(i, i+2, changeS(z));
else if(sb.charAt(i+1)=='1')
sb.replace(i, i+2, "0");
else if(sb.charAt(i+1)=='0')
sb.replace(i, i+2, "1");
//System.out.println("删除了一个非");
}
}
for(int i=0;i<sb.length();i++)
{
//以下代码用于初始化been
if(i==0)
{
if(sb.charAt(i)=='P')
been=x;
else if(sb.charAt(i)=='Q')
been=y;
else if(sb.charAt(i)=='R')
been=z;
else if(sb.charAt(i)=='1')
been=1;
else if(sb.charAt(i)=='0')
been=0;
}
switch(sb.charAt(i))
{
case'!':
break;
case '|':
if(sb.charAt(i+1)=='P')
been=extract(been,x);
if(sb.charAt(i+1)=='Q')
been=extract(been,y);
if(sb.charAt(i+1)=='R')
been=extract(been,z);
if(sb.charAt(i+1)=='1')
been=extract(been,1);
if(sb.charAt(i+1)=='0')
been=extract(been,0);
break;
case '&':
if(sb.charAt(i+1)=='P')
been=conjunct(been,x);
if(sb.charAt(i+1)=='Q')
been=conjunct(been,y);
if(sb.charAt(i+1)=='R')
been=conjunct(been,z);
if(sb.charAt(i+1)=='0')
been=conjunct(been,0);
if(sb.charAt(i+1)=='1')
been=conjunct(been,1);
break;
default:
break;
}
}
return been;
}

public void init()
{
int n=0;
for(int i=1;i>=0;i--)
{
for(int j=1;j>=0;j--)
{
for(int k=1;k>=0;k--)
{
Calculate(i,j,k);
table
[0]=i;
table
[1]=j;
table
[2]=k;
table
[3]=flag;
n++;
restart();
COUNT=count;
// System.out.println(inputStr);
}
}
}
}
//用于把1和0转换为T和F
public String replace(int x)
{
if(x==1)
return "T";
return "F";
}
public void print()
{
System.out.println("P\tQ\tR\t"+inputStr);
for(int i=0;i<8;i++)
{
for(int j=0;j<4;j++)
System.out.print(replace(table[i][j])+"\t");
System.out.println();
}
}
public void mainX()
{
int x=0;
for(int i=0;i<8;i++)
if(table[i][3]==1)
x=i;
System.out.println("该式的主析取范式");
for(int i=0;i<8;i++)
{
if(table[i][3]==1)
{
System.out.print("(");
for(int j=0;j<3;j++)
{

if(table[i][j]==0)
System.out.print("!"+pqr[j]);
else
System.out.print(pqr[j]);
if(j!=2)
System.out.print("&");
else
System.out.print(")");
}
if(i!=x)
System.out.print("|");
}
}
System.out.println();
}

public void mainH()
{
int x=0;
for(int i=0;i<8;i++)
if(table[i][3]==0)
x=i;
System.out.println("该式的主合取范式");
for(int i=0;i<8;i++)
{
if(table[i][3]==0)
{
System.out.print("(");
for(int j=0;j<3;j++)
{

if(table[i][j]==1)
System.out.print("!"+pqr[j]);
else
System.out.print(pqr[j]);
if(j!=2)
System.out.print("|");
else
System.out.print(")");
}
if(i!=x)
System.out.print("&");
}
}
System.out.println();
}
public static void main(String []args)throws Exception
{
li l=new li();
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入表达式,三个命题分别为P,Q,R,非号用!代替,析取号用|代替,合取号用&代替");
System.out.println("输入不当可能导致未知错误,请注意输入格式");
String s=null;
s=br.readLine();
StringBuilder sb=new StringBuilder(s);
l.input(sb);
l.init();
l.print();
l.mainX();
l.mainH();
}
}


事后感觉自己写的蠢了,另外要完成不确定个数的变元输入并不困难,甚至比确定的三个还要简单。

水平有限,敬请指教。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息