这次老师布置了如下上机作业,不限语言。思前想后,问了几个大神,说了一堆不知道什么鬼的算法名称。。。。
经过一番百度,发现Java可以包含库然后使用JavaScript的一些函数,其中eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码。http://www.w3school.com.cn/jsref/jsref_eval.asp 想到了如下解决办法。。
1 import javax.script.ScriptEngine; 2 import javax.script.ScriptEngineManager; 3 import javax.script.ScriptException; 4 import java.util.*; 5 6 7 /** 8 * Creat by Qjm 9 */ 10 public class Test { 11 12 //A-Z 65-90 13 //a-z 97-122 14 public static Map<Integer, Integer> m = new HashMap<Integer, Integer>(); 15 public static int count = 0; 16 public static List<String> list_true_value = new ArrayList<String>(); 17 18 /** 19 * 获取主和取(析取)范式 20 * String @param problem 要转换的命题公式 21 * int @param flag 标记(1 :和取 2:析取) 22 * 23 * @return 24 * @throws ScriptException 25 */ 26 public static String getMainNormalForm(String problem, int flag) throws ScriptException { 27 ScriptEngineManager manager = new ScriptEngineManager(); 28 ScriptEngine engine = manager.getEngineByName("js"); 29 problem = problem.trim().toUpperCase(); 30 char[] pro_arr = problem.toCharArray(); 31 Set<String> s_variable = new LinkedHashSet<String>(); 32 for (char temp : pro_arr) { 33 if (temp >= 65 && temp <= 90) { 34 s_variable.add(temp + ""); 35 //System.out.println(temp+""); 36 } 37 } 38 39 40 String[] variables = (String[]) s_variable.toArray(new String[0]); 41 Arrays.sort(variables); 42 System.out.println("\n真值指派顺序:" + Arrays.toString(variables)); 43 method(engine, variables, variables.length, problem); 44 String result1 = "Σ("; 45 String result2 = "∏("; 46 for (Integer i : m.keySet()) { 47 if (m.get(i) == 1) { 48 result1 += "m" + i + ","; 49 } else { 50 result2 += "M" + i + ","; 51 } 52 } 53 result1 = result1.substring(0, result1.length() - 1); 54 result2 = result2.substring(0, result2.length() - 1); 55 result1 += ")"; 56 result2 += ")"; 57 58 count = 0; 59 m.clear(); 60 61 return flag == 1 ? result1 : result2; 62 } 63 64 65 /** 66 * 递归函数,给每一个命题变远指派真值,得出每一种真值指派的结果 67 * ScriptEngine @param engine 68 * String[] @param variables 69 * int @param times 命题变元的个数 70 * String @param problem 要转换的命题公式 71 * 将注释掉的打印输出取消,可以看到该算法的具体执行过程 72 * @throws ScriptException 73 */ 74 public static void method(ScriptEngine engine, String[] variables, int times, String problem) throws ScriptException { 75 if (times < 1) { 76 Integer result = (Integer) engine.eval(problem); 77 78 //System.out.println("" + problem + ""); 79 //System.out.println("结果类型:" + result.getClass().getName() + ",计算结果:" + result + ""); 80 m.put(count, result); 81 count++; 82 //System.out.println(transMapToString(m)); 83 return; 84 } else { 85 for (int i = 0; i < 2; i++) { 86 engine.put(variables[variables.length - times], i); 87 //System.out.println("\ntimes : " + times + "\nbool :" + variables[times - 1] + "--->" + i); 88 method(engine, variables, times - 1, problem); 89 } 90 } 91 92 } 93 94 /** 95 /** 96 * 方法名称:transMapToString 97 * 传入参数:map 98 * 返回值:String 形如 username‘chenziwen^password‘1234 99 */ 100 public static String transMapToString(Map map) { 101 Set s = map.keySet(); 102 String temp = ""; 103 for (Object i : s) { 104 temp += "key : " + (Integer) i + "\t\tvalue : " + map.get(i) + "\n"; 105 } 106 return temp; 107 } 108 109 110 public static void main(String[] args) throws ScriptException { 111 String problem = ""; 112 int flag = 0; 113 Scanner s = new Scanner(System.in); 114 while (true) { 115 System.out.println("请输入要转换的合(析)取范式(&->合取 |->析取 !->非):"); 116 try{ 117 problem = s.next(); 118 }catch(NoSuchElementException exception){ 119 System.out.println("mdzz"); 120 System.exit(0); 121 } 122 System.out.println("待转化的命题公式:" + problem); 123 System.out.println("以下是对应的真值表"); 124 System.out.println("主合取范式: " + getMainNormalForm(problem, 1)); 125 System.out.println("主析取范式: " + getMainNormalForm(problem, 2) + "\n"); 126 } 127 128 } 129 }
基本思路是:
- 首先,engine.eval(problem); 可以直接把字符串当作数学表达式运行
- 然后,
engine.put(variables[variables.length - times], i); 可以直接把字符串中的指定字符换为目标数据,,这样就可以实现对表达式的每一个命题变元的真值指派。
- 再利用递归函数实现类似真值表法的遍历, 再记录每一次真值指派的表达式的真值,再化为对应的表达式。
以下是运行截图
时间: 2024-10-06 02:28:28