题目来源:2020年2月某国企校招其中一道编程笔试题回忆。
备注:笔试的时候并没有做出来,现在的代码不能保证没有逻辑错误,请各位大佬批评指正,感谢!
题目回忆
Pi代表股东,Ej代表公司(其中 i 和 j 代表正整数),Pi可以投资不同的Ej,这样就导致Pi和Ej之间是多对多的关系。 股东之间有关联 的定义如下:
①Pi与其本身有关联;
②如果Px投资了Ej,并且Py也投资了Ej,则Px和Py有关联。
输入样例
P2;P1,E1;P2,E1,E2;P3,E3
其中第一个分号之前只有一个Pi,是目标股东;
我们要做的就是找出所有和Pi有关联的股东;
之后的每一个分号,分割了每个股东及其投资的公司。
对输入样例就可以解释为:
已知P1投资了E1;P2投资了E1、E2;P3投资了E3;
求所有和股东P2有关联的股东。
输出结果:
P1,P2
输出结果要按照字典序从小到大的顺序输出,相邻两个股东之间用逗号分隔。
思路
1. 借助split方法对输入的字符串按照分号进行分割,获取目标股东以及每个股东和他投资的所有公司;
2. 计算一共有多少投资人;
3. 借助HashMap<String, String> 来记录每个股东人与他所投资的公司之间的对应关系,将每个投资人作为key,这个投资人投资的所有公司的输入顺序子串作为value存储起来,如输入样例中有三组键值对,分别是 <key:”P1”,value:”E!”>,<key:”P2”,value:”E1,E2”>,<key:”P3”,value:”E3”> ;将这个Map命名为result;
4. 确定目标股东在字符串的位置,并将他记录下来;
5. 遍历result的key,找到目标股东对应的那一组键值对,如样例输入中会找到<key:”P2”,value:”E1,E2”>,找到之后,把这一个键值对的value值,按照逗号 “,” 进行分割,这样会得到目标股东投资的所有公司,把这些公司逐个记录到列表listval中;
6. 双重循环,外层遍历列表listval,取出目标股东投资的所有公司名称Ez ,挨个与之前创建的Map(即result)中的所有键值对的value值进行比对,如果result的某一个键值对的value值(是一个字符串)中包含Ez这个子串,那么就把这个键值对的key值添加进listkey中记录下来,listkey是用TreeSet定义的;
7. 之所以要用TreeSet是因为我们要做到有序输出,而且Set中不会包含重复元素的,重复元素添加是不被完成的;
8. 按照输出要求对listkey进行遍历输出。
代码
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.TreeSet;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
String str = in.next();
// 借助split方法对输入的字符串按照分号进行分割,获取目标股东以及每个股东和他投资的所有公司
String [] relation = str.split(";");
// 计算一共有多少投资人
int count = -1;
for (String s : relation) {
count ++;
}
// 借助HashMap来记录每个股东人与他所投资的公司之间的对应关系
Map<String, String> result = new HashMap<String, String>();
// 将每个投资人作为key,这个投资人投资的所有公司的输入顺序子串作为value存储起来
for (int i = 1; i <= count; i++) {
// 定位投资人
String pp = relation[i].substring(0, 2);
// 定位该投资人投资的所有公司组成的字符串
result.put(pp, relation[i].substring(3, relation[i].length()));
}
// 确定目标股东在字符串的位置
int i = 0;
for (i = 0; i < str.length(); i++) {
if (str.charAt(i) == ';') {
break;
}
}
// 将目标股东target记录下来
String target = str.substring(0, i);
// listval用来记录目标股东投资的所有公司
List<String> listval = new LinkedList<String>();
// listkey用来记录与目标股东有关联的所有股东(包含他自己)
TreeSet<String> listkey = new TreeSet<String>();
for (String key : result.keySet()) {
// 输出检查有没有出错 : System.out.println(key + " " + result.get(key) + " ");
if (key.equals(target)) { // 找到目标股东对应的那一组键值对
// 把这一个键值对的value值,按逗号进行分割,这样会得到目标股东投资的所有公司
String [] relationee = result.get(key).split(",");
// 把目标股东投资的所有公司都添加到listval列表中用于后期的对比
for (int index = 0; index < relationee.length; index++) {
listval.add(relationee[index]);
// 输出检查有没有出错 : System.out.print(relationee[index] + " " + index + '\n');
}
}
}
// 遍历列表listval,取出目标股东投资的所有公司名称
for(Object one : listval) {
// 输出检查有没有出错 : System.out.println(one.toString());
for (Map.Entry<String, String> entry : result.entrySet()) {
// 目标股东投资的所有公司名称挨个与之前创建的Map(即result)中的所有键值对的value值进行比对,
// 如果result的某一个键值对的value值(是一个字符串)中包含Ez这个子串,
// 那么就把这个键值对的key值添加进**listkey**中记录下来
// 输出检查有没有出错 : System.out.println(entry.getValue() + " entry.getValue()");
if (entry.getValue().contains(one.toString())) {
listkey.add(entry.getKey().toString());
// 输出检查有没有出错 : System.out.println(entry.getKey() + " key ");
}
}
}
// 按照输出要求对listkey进行遍历输出
System.out.print(listkey.pollFirst());
while(!listkey.isEmpty()) {
System.out.print("," + listkey.pollFirst());
}
//输入样例: P2;P1,E1;P2,E1,E2;P3,E3
//输出样例: P1,P2
}
}
本文链接: https://hexo.whtli.cn/archives/cee74ffa.html
版权声明: 遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。