01-根據投資關係確定股東和股東之間是否有關聯

題目來源:2020年2月某國企校招其中一道編程筆試題回憶。
備註:筆試的時候並沒有做出來,現在的代碼不能保證沒有邏輯錯誤,請各位大佬批評指正,感謝!

題目回憶

Pi代表股東,Ej代表公司(其中 ij 代表正整數),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
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章