iT邦幫忙

0

為了轉生而點技能-Java難題紀錄 (作業:染病接觸之人員追蹤鏈

前言:

本篇是參加學校開設的java資訊班的作業,由於對於筆者來說花蠻多時間的,所以想記錄下來解題的過程,以供後續參考。

題目:請隨機產生一群可疑接觸的人群,並編號(ID),同時請他們紀錄接觸別人的號碼是多少,假設他們接觸的人都只有一人並且不會重覆;之後隨機選擇一個人為染疫者,並請找出相關傳播鏈的人。如下圖:
https://ithelp.ithome.com.tw/upload/images/20211204/20143762wGhqX36ORR.png


難題一:如何亂數取值不重覆。
剛開始尚未學習method,雖然網路上有一篇文章有寫到[Java]產生不重複之亂數,但是在method回傳應用上,還是一知半解。
後來回頭看上課講義,發現利用shuffle algorithm的swap即可。

		System.out.println("Enter number of citizens");
		Scanner citizens = new Scanner(System.in);
		int c = citizens.nextInt();                    //指定團體人數有幾人
		int[] C = new int[c];
		System.out.printf("%9s", "ID");
		for (int i = 0; i < C.length; i++) {
			System.out.printf("%3d", i);
		}
		;
		System.out.println();

		int[] Contactee; 
		Contactee = new int[c];
		for (int i = 0; i < Contactee.length; i++) {
			Contactee[i] = i;
		}
		;
        
        //以下亂數取值不重覆
		for (int i = 0; i < Contactee.length - 1; i++) {
			int m = (int) (Math.random() * (Contactee.length - i) + i);   
			int temp = Contactee[i];
			Contactee[i] = Contactee[m];
			Contactee[m] = temp;
		}

難題之二:如何串聯ID與接觸者的關係。
雖然在紙上拆解流程都沒問題,但是因為對於本題在while及for迴圈之間的關係,及語法不熟練,想通前要死不活,想通後不禁佩服自己的蠢。

import java.util.Scanner;

public class ContagionControl {

	public static void main(String[] args) {
		
		// part2開始
		System.out.println();
		System.out.println("Enter id of infected citizen :");       //指定一個ID為傳染源頭。
		Scanner id = new Scanner(System.in);
		int idnumber = id.nextInt();
		int enternumber = idnumber;           //紀錄傳染鏈的頭,方便後面對比使否為傳染鏈的尾。
 		System.out.println("These citizens are to br self-isolated in the following 14 days:");
 		System.out.printf("%d",idnumber);
        
        //ID與接觸者關係
 		while (Contactee[idnumber] != enternumber) {
			for (int i = 0; i < C.length; i++) {
				if (Contactee[idnumber] == i) {
					System.out.printf("%3d", i);
					idnumber = i;
				}
				;
			}
			;
			if(Contactee[idnumber] == enternumber) {       //當尾巴連到傳染鏈的頭,等於結束傳染鏈。
				break;
			};
		}
		;
        id.close();
        citizens.close();
        
	};

}

全部的code

import java.util.Scanner;

public class ContagionControl {

	public static void main(String[] args) {
		System.out.println("Enter number of citizens");
		Scanner citizens = new Scanner(System.in);
		int c = citizens.nextInt();
		int[] C = new int[c];
		System.out.printf("%9s", "ID");
		for (int i = 0; i < C.length; i++) {
			System.out.printf("%3d", i);
		}
		;
		System.out.println();

		int[] Contactee; 
		Contactee = new int[c];
		for (int i = 0; i < Contactee.length; i++) {
			Contactee[i] = i;
		}
		;
		for (int i = 0; i < Contactee.length - 1; i++) {
			int m = (int) (Math.random() * (Contactee.length - i) + i);
			int temp = Contactee[i];
			Contactee[i] = Contactee[m];
			Contactee[m] = temp;
		}
		;
		System.out.printf("%5s", "Contactee");
		for (int i = 0; i < C.length; i++) {
			System.out.printf("%3d", Contactee[i]);
		}
		;
		System.out.println();
		System.out.println("-----------------------");
		
		// part2
		System.out.println();
		System.out.println("Enter id of infected citizen :");       //指定一個ID為傳染源頭。
		Scanner id = new Scanner(System.in);
		int idnumber = id.nextInt();
		int enternumber = idnumber;           //紀錄傳染鏈的頭,方便後面對比使否為傳染鏈的尾。
 		System.out.println("These citizens are to br self-isolated in the following 14 days:");
 		System.out.printf("%d",idnumber);
        
        //ID與接觸者關係
 		while (Contactee[idnumber] != enternumber) {
			for (int i = 0; i < C.length; i++) {
				if (Contactee[idnumber] == i) {
					System.out.printf("%3d", i);
					idnumber = i;
				}
				;
			}
			;
			if(Contactee[idnumber] == enternumber) {       //當尾巴連到傳染鏈的頭,等於結束傳染鏈。
				break;
			};
		}
		;
        id.close();
        citizens.close();
        
	};

}

參考文章:

  1. [Java]產生不重複之亂數:https://tw4x.wordpress.com/2016/11/07/java-random/
  2. Java 程式架構與輸入/輸出:http://www.tsnien.idv.tw/Java1_WebBook/chap2/2-5%20%E6%A0%BC%E5%BC%8F%E5%8C%96%E8%BC%B8%E5%87%BA.html

1 則留言

1
GreatSlime
iT邦新手 5 級 ‧ 2021-12-07 13:13:33

關於第二點: 如何串聯ID與接觸者的關係

可以參考LinkedList的原理來實作。

謝謝大大!! 那我找時間再來研究看看如何用LinkedList實作!!!

我要留言

立即登入留言