【已解决】 TCL面试题(逻辑推理+编程验证)
原 题:
张新、黎民、王亮三位老师分别来自湖南、广西、甘肃,分别教语文、数学和英语。已知:(1)张新不是湖南人,黎明不是广西人;(2)湖南的老师不教英语;(3)广西的老师教语文;(4)黎民不教数学。由此可知,王亮教的是:(A)
A.数学 B.英语 C.语文 D.无法确定
逻辑推理:
步骤1:
(1) 由条件3知,广西老师教语文;
(2) 结合条件2得:湖南老师可能教数学or语文,而上步(1)中知语文已确定由广西老师教,则湖南老师只能教数学;
(3) 则得到如下对应关系:广西-语文 湖南-数学 甘肃-英语
步骤2:
(1) 由条件4得,黎明可能教语文or英语,则步骤1中对应结论表明:他只能是广西or甘肃人。又由条件1得,他可能是湖南or甘肃人,我们通过对这两个约束条件取交集,可以确定他必是甘肃人,即黎民-甘肃-英语;
(2) 由条件1得,张新可能是广西or甘肃人,又因上步(1)中黎民已确定为甘肃人,则张新必为广西人;
(3) 则不难得出如下对应关系:张新-广西-语文 王亮-湖南-数学 黎民-甘肃-英语
推理过程见附图1:
编程验证:
编程思想:
(1) 将名字、省份、学科,共9个元素放入3个长度为3的字符串数组中,分别为name[3],province[3],subject[3]。 然后让它们全部自由组合,得到27种不同小组合。
特别说明:这27种仅仅是由3个元素构成的小组合,我们要得到的最终大组合是由3对这样的子组合构成的由9个无重复元素构成的大组合。
(2) 接下来,我们要解决大组合的构造问题,即利用这27种小组合构建大组合的问题。本文利用了一种有效的组合方法,操作过程见图2。
(3) 经上步可得2925种大组合,遗憾的其中部分大组合并不是由9个不同元素分别构成的,存在一个元素多次出现的情况,不符合题目要求,需剔除。特别提示:文字描述比较抽象,读者可以在代码中自行输出查看。
(4) 如上所述,剔除不合理组合不难,通过判断每条大组合中是否包含全部的9个元素即可。未全部包含则剔除,处理后得到符合要求的36种大组合。
(5) 然后,我们将题中的四个约束条件用’&&’形式连接,用来对36种组合进行判断,从而得到最终的符合要求组合。
程序验证,运行结果见图3:
完整程序Java代码清单:
package Qestion;
import java.util.ArrayList;
public class Qestion {
private String situation[][][] = new String[3][3][3];
private static ArrayList<String[]> set = new ArrayList<>();
private static ArrayList<String[]> list = new ArrayList<>();
private static ArrayList<String[]> list2 = new ArrayList<>();
private static int count = 0; //计数变量
public Qestion() {
// TODO Auto-generated constructor stub
String name[] = { "ZhangXin", "LiMin", "WangLiang" };
String province[] = { "HuNan", "GuangXi", "GanSu" };
String subject[] = { "Chinese", "Math", "English" };
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
for (int k = 0; k < 3; k++) {
this.situation[i][j][k] = name[i] + "," + province[j] + ","
+ subject[k];
list.add(new String[] { name[i], province[j], subject[k] }); // list中放字符串数组
}
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Qestion qes = new Qestion();
qes.list_avail(list);
// Iterator<String[]> it =set.iterator(); //查看set中内容
// while(it.hasNext()){ //输出符合条件的所有情况
qes.func1();
qes.func2();
// System.out.println(list2.size());
}
public static String String_LinkTool(String[] str) {
int N = str.length;
String s = "";
for (int i = 0; i < N; i++) {
s = s + str[i];
}
return s;
}
public static Boolean String_IsexistTool(String... s) {
String FatherStr = s[0];
String SonStr0 = s[1];
String SonStr1 = s[2];
String SonStr2 = s[3];
String SonStr3 = s[4];
String SonStr4 = s[5];
String SonStr5 = s[6];
String SonStr6 = s[7];
String SonStr7 = s[8];
String SonStr8 = s[9];
int result0 = -1, result1 = -1, result2 = -1, result3 = -1, result4 = -1, result5 = -1, result6 = -1, result7 = -1, result8 = -1;
result0 = FatherStr.indexOf(SonStr0);
result1 = FatherStr.indexOf(SonStr1);
result2 = FatherStr.indexOf(SonStr2);
result3 = FatherStr.indexOf(SonStr3);
result4 = FatherStr.indexOf(SonStr4);
result5 = FatherStr.indexOf(SonStr5);
result6 = FatherStr.indexOf(SonStr6);
result7 = FatherStr.indexOf(SonStr7);
result8 = FatherStr.indexOf(SonStr8);
if ((result0 >= 0) && (result1 >= 0) && (result2 >= 0)
&& (result3 >= 0) && (result4 >= 0) && (result5 >= 0)
&& (result6 >= 0) && (result7 >= 0) && (result8 >= 0)) {
// System.out.println(FatherStr);
// count++;
return true;
} else {
return false;
}
}
public static Boolean Judge_assist(String[] str, String a, String b) {
int result00 = -1, result01 = -1;
for (int i = 0; i < str.length; i++) {
result00 = str[i].indexOf(a);
result01 = str[i].indexOf(b);
if ((result00 >= 0) && (result01 >= 0)) {
return false;
}
}
return true;
}
public void list_avail(ArrayList<String[]> list) {
int N = list.size();
for (int i = 0; i < N; i++) { // 得到2925种种组合,放入set中
for (int j = i + 1; j < N; j++) { // 1 2 3 4 5 6 ... 27
for (int k = j + 1; k < N; k++) {
String[] ss = new String[9];
ss[0] = list.get(i)[0];
ss[1] = list.get(i)[1];
ss[2] = list.get(i)[2];
ss[3] = list.get(j)[0];
ss[4] = list.get(j)[1];
ss[5] = list.get(j)[2];
ss[6] = list.get(k)[0];
ss[7] = list.get(k)[1];
ss[8] = list.get(k)[2];
set.add(ss);
}
}
}
}
public void func1() {
for (String[] s : set) { // 符合分别由9个选项组成的,无重复组合(共36个)
if (String_IsexistTool(String_LinkTool(s), "ZhangXin", "LiMin",
"WangLiang", "HuNan", "GuangXi", "GanSu", "Chinese",
"Math", "English")) {
// System.out.println(String_LinkTool(it.next()));
String[] ss = s;
// System.out.println(ss[3]);
String[] temp = new String[3];
temp[0] = ss[0] + ss[1] + ss[2];
temp[1] = ss[3] + ss[4] + ss[5];
temp[2] = ss[6] + ss[7] + ss[8];
list2.add(temp);
count++;
}
}
}
public void func2() {
for (String[] s : list2) { // 判断符合四个条件的组合
if (Judge_assist(s, "ZhangXin", "HuNan")
&& Judge_assist(s, "LiMin", "GuangXi")
&& Judge_assist(s, "English", "HuNan")
&& (!Judge_assist(s, "Chinese", "GuangXi"))
&& Judge_assist(s, "Math", "LiMin")) {
System.out.println(s[0] + " " + s[1] + " " + s[2]);
}
}
}
}
程序说明文档:
Qestion( ) //构造方法,完成27种小组合的构建,并存入list数组列表中。
list_avail(ArrayList<String> ) //够建2925种大组合,并存入set数组列表中。
String_IsexistTool(String…) //剔除工具,处理后得到36种合理组合,并存入list2中。
Judge_assist(String[],String,String) //条件判断辅助工具,由题中判断条件返回布尔值。
String_LinkTool(String[]) //字符串连接工具,将字符串数组中内容连接后返回。
int count //记录个数