趙大超的學習周志(一)
本周是Java基礎學習的第一周,學習內容包括關鍵字與識別符號、資料型別、運算子、標準輸入、亂數、分支陳述句、回圈陳述句、等內容,并對陣列簡單開了個頭,其中大部分內容都在試學階段學習過并基本掌握,所以學習起來較為輕松,在最后一天陣列的相關練習中有兩道題有所難度,記錄研究如下:
一、約瑟夫環問題
題目:有500個人圍城一個圈,依次報數,每數到3的倍數的人離開圈,數完一圈后繼續從1開始數,直到圈中剩下最后一個人,求剩下的人原來在圈中的位置(約瑟夫環問題)
實作邏輯:
實作關鍵在于如何表示參與游戲者是否被淘汰,以及如何實作圍圈報數,并且需要記錄最侄訓勝者為第幾人,可以用元素所存值來記錄游戲玩家的狀態,如值為0則表示未被淘汰,如被淘汰則將元素值改為1,表示已被淘汰,在游戲報數前先對玩家狀態進行判斷,若已被淘汰則不進入游戲,若未被淘汰則進行報數操作,判斷報數為3的倍數則被淘汰,報數+1,陣列下標+1,進入下一次回圈,每次不論當前下標的元素是否被淘汰,都需要使下標自增以保證輪到下一下標的元素進行判斷,保證游戲正常進行,每當下標進行到陣列長度-1處時,下一次則要輪到下標為0的元素進行判斷,以保證實作圍圈報數的效果,最后當剩余一人未被淘汰時結束回圈,記錄該玩家對應陣列的下標,勝利者即為第下標+1個人,
①由500人圍圈報數,則定義一個長度為500的陣列,不賦值則初始值默認為0,則設定元素值為0表示未被淘汰狀態,值為1為淘汰狀態,
②定義變數count初值為陣列長度,表示未淘汰人數;定義變數num初值為1,表示當前所報的數;定義變數index初值為0,用于記錄當前元素的下標,
③使用回圈進行游戲,當未淘汰人數等于1時結束回圈;回圈判斷當前下標元素是否被淘汰,若被淘汰則判斷當前元素是否為最后一個玩家,若是則重新將index置0開始即可從下一圈繼續報數,若否則將index+1對下一個元素進行判斷;若未被淘汰則進入游戲,判斷當前元素所報數是否為3的倍數,若是3的倍數則將其狀態由0置1表示被淘汰,并將count-1以減少一個未被淘汰人數;之后判斷當前元素是否為最后一個玩家,操作如上,最后將num+1作為下個人報的數,index+1進入下一個元素的判斷,
④回圈遍歷陣列元素值,當元素值為0是退出回圈,記錄當前下標索引,獲勝者則為第該下標+1人,
代碼實作:
//定義陣列
int[] arr = new int[500];
//未被淘汰人數
int count = arr.length;
//當前已報數
int num = 1;
//當前陣列索引
int index = 0;
//未淘汰人數僅剩1人時退出回圈
while(count != 1) {
//未被淘汰則參與游戲
if(arr[index] == 0) {
//報數被3整除
if(num % 3 == 0) {
//狀態置1,淘汰
arr[index] = 1;
//未淘汰人數-1
count --;
}
//若當前報數人為最后一人
if(index == arr.length - 1) {
//下標置0,實作圍圈報數
index = 0;
//下一任所報數
num ++;
//跳出本次進入下次回圈
continue;
}
//下一任所報數
num ++;
}else{ //若為已被淘汰者
if(index == arr.length - 1) {
index = 0;
continue;
}
}
//下標+1,保證游戲向下進行
index ++;
}
int i;
for (i = 0; i < arr.length; i++) {
//找出未淘汰者則記錄下標,退出回圈
if(arr[i] == 0) {
break;
}
}
//勝利者為第該下標+1人
System.out.println("第" + (i + 1) + "個玩家獲得勝利");
然后我對比了一下以前老師寫的約瑟夫環代碼,如下:
// 約瑟夫環
Scanner scanner = new Scanner(System.in);
// 確定游戲引數
System.out.print("請輸入參與人數:");
int n = scanner.nextInt();
System.out.print("請輸入淘汰數值:");
int outN = scanner.nextInt();
// 定義一個陣列保存玩家的狀態: 0-未淘汰 1-淘汰
int[] states = new int[n];
// 定義一個變數記錄當前玩家所報的數
int number = 0;
// 定義一個變數紀錄玩家的下標
int index = 0;
while (true) {
// 如果玩家沒有被淘汰,則進入游戲報數
if (states[index % states.length] == 0) {
// 如果玩家報的數等于淘汰值,則淘汰玩家
if (++number == outN) {
// 修改玩家狀態,讓玩家淘汰出局
states[index % states.length] = 1;
// 玩家淘汰,游戲人數-1,判定游戲是否結束
if (--n == 1) {
break;
}
// 游戲繼續,重置報數值
number = 0;
}
}
// 游戲繼續,讓后一個玩家繼續游戲
index++;
}
for (int i = 0; i < states.length; i++) {
if (states[i] == 0) {
System.out.println("第" + (i + 1) + "個玩家取得勝利!");
break;
}
}
對比后發現自己的代碼可以進行如下改進:
實作圍圈報數時我是將索引重新置0來實作,而老師則是將索引對陣列長度進行取余,所得即為下一圈報數元素的索引,也避免了每次對索引是否超過陣列長度情況的判斷,更加簡潔和巧妙,
二、如何輸出由鍵盤輸入元素的字串
題目:定義一個陣列,由鍵盤輸入值來賦值,并輸出該陣列的各值
實作邏輯:
老師設計題目時應該只是想定義一個已知長度的陣列,再將輸入的元素賦給陣列,但我在實作時給自己加了點難度,一個是將陣列以字串的形式輸入以查看,如何確定陣列長度或者說以字串形式輸出陣列時如何能夠只輸出自己輸入的值,不輸出默認初始化的空值“0”;另一個是如何實作使用戶結束輸入元素,陣列長度采取解決的方案是先創建一個足夠大的陣列用來初步存放陣列,或定義一個動態陣列,即先定義一個較小的陣列,當數值個數超過陣列長度時則再創建一個長度為當前長度的1.5倍的陣列,第一種方式的缺點就是長度可能存在不夠的現象且當初始化時定義的長度過長會浪費記憶體,所以使用第二種方法動態陣列更好,本次為了方便簡介就先使用第一種方法定義長度為1000,動態陣列的實作代碼下次再貼出,如何結束鍵盤輸入陣列采取的方法是在提示用戶輸入整數時同樣提示用戶輸入“over”以結束輸入,然后以Scanner.nextLine()方法接收元素,若為整數則將之存入陣列,若為“over”則跳出回圈不再輸入,并記錄存數次數,得到陣列為帶有空值“0”的陣列,若想讓陣列長度就為輸入元素個數長度時則創建一個新陣列陣列長度為剛才輸入值時記錄的輸入次數值即可,輸出時有兩種方式,若只是將原陣列中非空值“0”輸出的話可以使用字串拼接方式,也可以使用Arrays.toString()方法進行輸出,
代碼如下:
Scanner sc = new Scanner(System.in);
/*
* 盡量將陣列長度定義的大些保證夠用,確定是浪費空間記憶體
* 也可以先定義一個長度較小陣列,
* 再撰寫一個長度不足時增加一半陣列長度的方法進行呼叫
*/
int[] tempArr = new int[1000];
int count = 0;
String str = null;
System.out.println("輸入存入陣列的值(輸入\"over\"結束輸入):");
for (int i = 0; i < tempArr.length; i++) {
str = sc.nextLine();
//當比較參考資料型別的值時使用equals方法,直接使用"=="比較的話比較的是參考地址
if(str.equals("over")) {
break;
}
tempArr[i] = (Integer.parseInt(str));
count ++;
}
System.out.print("生成的陣列為:[");
/*
* 若要使新陣列沒有初始化的值,即陣列長度等于用戶輸入數的次數,
* 則定義新陣列,通過回圈將老陣列中非0值(指初始化的0,手動輸入的0不影響)傳入其中,
* 使用回圈方式輸出陣列中非0(指初始化的0,手動輸入的0可以輸出)的數
* 也采用Arrays.toString()方法以字串形式輸出新陣列
*/
int i = 0;
while(i < count) {
System.out.print(tempArr[i ++]);
if(i != count)
System.out.print(",");
}
System.out.print("]");
int[] arr = new int[count];
在代碼實作時遇到的問題是:判斷是否輸入了字串“over”時的判斷條件寫的是if(str == “over”),運行時輸入“over”后報錯,經過debug除錯后發現,當進行 str == “over” 的判斷時并不符合,導致不跳出回圈而是繼續將"over"轉為int型失敗,故報錯,由此發現參考型別對值進行比較時不能使用"=="進行比較,這樣比較的是兩個參考地址值,所以不會滿足條件跳出回圈,查詢后發現應使用String的equals()方法進行值的比較,使用后滿足條件,程式正常執行,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/200124.html
標籤:python
上一篇:C語言簡易版掃雷
