前幾天寫得要死要活的東西…
雖然根本沒人會想看,但是花那麼久時間寫的東西總該拿來餵一餵小水滴,要不然牠真的要餓死了吧我想。
public class Homework2{
public static void main(String args[]){
/* 變數宣告 */
int i = 0, j = 0;
String cal[][] = new String[5][9];
for(j = 0;j <= 8;j++){for(i = 0; i <= 4; i++) cal[i][j] = (" ");}
/* 首次列印行事曆 */
System.out.println (" | 一 | 二 | 三 | 四 | 五 |");
for(j = 0;j <= 8;j++){
System.out.println ((j+1) + "|" + cal[0][j] + "|" + cal[1][j] + "|" + cal[2][j] + "|" + cal[3][j] + "|" +cal[4][j] + "|");
}
/* 使用說明 */
System.out.println ("指令一覽:add,[行程時間],[行程內容] - 增加行程");
System.out.println (" copy,[來源時間],[目標時間] - 複製行程");
System.out.println (" del,[行程時間] - 刪除行程");
System.out.println (" exit - 離開本系統");
System.out.println ("注意事項:行程內容長度限定為4個字元。\n");
/* 首次摘取輸入選項 */
System.out.print("請輸入指令:");
String input = ConsoleIn.readLine();
String parts[] = input.split(",");
String op = parts[0];
while(op.equals("exit") == false || parts.length != 1){
/* 檢查指令格式是否有誤 */
if( op.equals("add") == false && op.equals("del") == false && op.equals("copy") == false){
System.out.println("\n輸入狀況有誤,請重新輸入。");
}
else
/* 判斷指令選項並執行 */
/* add,新增行程 */
if(op.equals("add") == true ){
/* 檢查格式是否錯誤 */
/* 檢查逗號是否正確 */
if(parts.length != 3)System.out.println("\n輸入狀況有誤,請重新輸入。");
else
/* 檢查時間格式是否錯誤 */
if(parts[1].matches("[1-5]{1}[1-9]{1}") == false && parts[1].matches("[1-5]{1}[1-9]{1}-[1-5]{1}[1-9]{1}") == false)System.out.println("\n輸入狀況有誤,請重新輸入。");
else
/* 檢查行程字數是否符合格式 */
if(parts[2].matches("[a-zA-z0-9]{4}") == false && parts[2].matches("[^a-zA-z0-9]{1}[a-zA-z0-9]{2}") == false && parts[2].matches("[a-zA-z0-9]{2}[^a-zA-z0-9]{1}") == false && parts[2].matches("[^a-zA-z0-9]{2}") == false && parts[2].matches("[a-zA-z0-9]{1}[^a-zA-z0-9]{1}[a-zA-z0-9]{1}") == false )System.out.println("\n輸入狀況有誤,請重新輸入。");
else
/* 檢查輸入的時間格式:單一時間或是一列時間 */
/* 選擇輸入「一整列的時間」的場合 */
if (parts[1].length() == 5){
String[] time = parts[1].split("-");
/* 檢查格式是否正確 */
if( (Integer.parseInt(time[0])/10) != (Integer.parseInt(time[1])/10) || (Integer.parseInt(time[0]) - 10*(Integer.parseInt(time[0])/10)) >= (Integer.parseInt(time[1]) - 10*(Integer.parseInt(time[1])/10)) )System.out.println("\n輸入狀況有誤,請重新輸入。");
else {
i = (Integer.parseInt(time[0])/10) - 1;
j = (Integer.parseInt(time[0]) - 10*(Integer.parseInt(time[0])/10)) - 1;
while(j <= ((Integer.parseInt(time[1]) - 10*(Integer.parseInt(time[1])/10)) - 1) ){
if(cal[i][j].equals(" ") == false)j = 123;
else j++;
}
if (j == 123)System.out.println("\n輸入狀況有誤,請重新輸入。");
else {
for (j=(Integer.parseInt(time[0])-10*(Integer.parseInt(time[0])/10))-1; j <= (Integer.parseInt(time[1])-10*(Integer.parseInt(time[1])/10))-1;j++)cal[i][j] = parts[2];
System.out.println ("\n | 一 | 二 | 三 | 四 | 五 |");
for(j = 0;j <= 8;j++)System.out.println ((j+1) + "|" + cal[0][j] + "|" + cal[1][j] + "|" + cal[2][j] + "|" + cal[3][j] + "|" +cal[4][j] + "|");
}
}
}
/* 選擇輸入「單一時間」的場合 */
else {
i = (Integer.parseInt(parts[1])/10) - 1;
j = (Integer.parseInt(parts[1]) - 10*(Integer.parseInt(parts[1])/10)) - 1;
/* 檢查是否該時段已有安排 */
if(cal[i][j].equals(" ") == false)System.out.println("\n輸入狀況有誤,請重新輸入。");
else cal[i][j] = parts[2];
System.out.println ("\n | 一 | 二 | 三 | 四 | 五 |");
for(j = 0;j <= 8;j++)System.out.println ((j+1) + "|" + cal[0][j] + "|" + cal[1][j] + "|" + cal[2][j] + "|" + cal[3][j] + "|" +cal[4][j] + "|");
}
}
/* del,刪除行程 */
if(op.equals("del") == true ){
/* 檢查格式是否正確 */
/* 檢查逗號是否正確 */
if(parts.length != 2)System.out.println("\n輸入狀況有誤,請重新輸入。");
else
/* 檢查時間格式是否錯誤 */
if(parts[1].matches("[1-5]{1}[1-9]{1}") == false && parts[1].matches("[1-5]{1}[1-9]{1}-[1-5]{1}[1-9]{1}") == false)System.out.println("\n輸入狀況有誤,請重新輸入。");
else
/* 檢查輸入的時間格式:單一時間或是一列時間 */
/* 選擇刪除「一整列的時間」的場合 */
if (parts[1].length() == 5){
String[] time = parts[1].split("-");
/* 檢查格式是否正確 */
if( (Integer.parseInt(time[0])/10) != (Integer.parseInt(time[1])/10) || (Integer.parseInt(time[0]) - 10*(Integer.parseInt(time[0])/10)) >= (Integer.parseInt(time[1]) - 10*(Integer.parseInt(time[1])/10)) )System.out.println("\n輸入狀況有誤,請重新輸入。");
else {
i = (Integer.parseInt(time[0])/10) - 1;
j = (Integer.parseInt(time[0]) - 10*(Integer.parseInt(time[0])/10)) - 1;
for (j=(Integer.parseInt(time[0])-10*(Integer.parseInt(time[0])/10))-1; j <= (Integer.parseInt(time[1])-10*(Integer.parseInt(time[1])/10))-1;j++)cal[i][j] = (" ");
System.out.println ("\n | 一 | 二 | 三 | 四 | 五 |");
for(j = 0;j <= 8;j++)System.out.println ((j+1) + "|" + cal[0][j] + "|" + cal[1][j] + "|" + cal[2][j] + "|" + cal[3][j] + "|" +cal[4][j] + "|");
}
}
/* 選擇刪除「單一時間」的場合 */
else {
i = (Integer.parseInt(parts[1])/10) - 1;
j = (Integer.parseInt(parts[1]) - 10*(Integer.parseInt(parts[1])/10)) - 1;
cal[i][j] = (" ");
System.out.println ("\n | 一 | 二 | 三 | 四 | 五 |");
for(j = 0;j <= 8;j++)System.out.println ((j+1) + "|" + cal[0][j] + "|" + cal[1][j] + "|" + cal[2][j] + "|" + cal[3][j] + "|" +cal[4][j] + "|");
}
}
/* copy,複製行程 */
if(op.equals("copy") == true ){
/* 檢查格式是否錯誤 */
/* 檢查逗號是否正確 */
if(parts.length != 3)System.out.println("\n輸入狀況有誤,請重新輸入。");
else
/* 檢查時間格式是否錯誤 */
if(parts[1].matches("[1-5]{1}[1-9]{1}") == false && parts[1].matches("[1-5]{1}[1-9]{1}-[1-5]{1}[1-9]{1}") == false)System.out.println("\n輸入狀況有誤,請重新輸入。");
else
if(parts[2].matches("[1-5]{1}[1-9]{1}") == false && parts[2].matches("[1-5]{1}[1-9]{1}-[1-5]{1}[1-9]{1}") == false)System.out.println("\n輸入狀況有誤,請重新輸入。");
else
/* 檢查被複製的區塊和貼上的區塊類別(單一時間或是一列時間)是否一致 */
if (parts[1].length() != parts[2].length())System.out.println("\n輸入狀況有誤,請重新輸入。");
else
/* 檢查輸入的時間格式:單一時間或是一列時間 */
/* 選擇複製「一整列的時間」的場合 */
if (parts[1].length() == 5){
String[] time = parts[1].split("-");
String[] time2 = parts[2].split("-");
/* 檢查格式是否正確 */
if( (Integer.parseInt(time[0])/10) != (Integer.parseInt(time[1])/10) || (Integer.parseInt(time[0]) - 10*(Integer.parseInt(time[0])/10)) >= (Integer.parseInt(time[1]) - 10*(Integer.parseInt(time[1])/10)) )System.out.println("\n輸入狀況有誤,請重新輸入。");
else
if( (Integer.parseInt(time2[0])/10) != (Integer.parseInt(time2[1])/10) || (Integer.parseInt(time2[0]) - 10*(Integer.parseInt(time2[0])/10)) >= (Integer.parseInt(time2[1]) - 10*(Integer.parseInt(time2[1])/10)) )System.out.println("\n輸入狀況有誤,請重新輸入。");
else
{
i = (Integer.parseInt(time2[0])/10) - 1;
j = (Integer.parseInt(time2[0]) - 10*(Integer.parseInt(time2[0])/10)) - 1;
while(j <= ((Integer.parseInt(time2[1]) - 10*(Integer.parseInt(time2[1])/10)) - 1) ){
if(cal[i][j].equals(" ") == false)j = 123;
else j++;
}
if (j == 123)System.out.println("\n輸入狀況有誤,請重新輸入。");
else
if ( (Integer.parseInt(time[1])-Integer.parseInt(time[0])) != (Integer.parseInt(time2[1])-Integer.parseInt(time2[0])))System.out.println("\n輸入狀況有誤,請重新輸入。");
else {
int k = (Integer.parseInt(time2[0]) - 10*(Integer.parseInt(time2[0])/10)) - 1;
for (j=(Integer.parseInt(time[0])-10*(Integer.parseInt(time[0])/10))-1; j <= (Integer.parseInt(time[1])-10*(Integer.parseInt(time[1])/10))-1;j++){
cal[(Integer.parseInt(time2[0])/10) - 1][k] = cal[(Integer.parseInt(time[0])/10) - 1][j];
k++;
}
System.out.println ("\n | 一 | 二 | 三 | 四 | 五 |");
for(j = 0;j <= 8;j++)System.out.println ((j+1) + "|" + cal[0][j] + "|" + cal[1][j] + "|" + cal[2][j] + "|" + cal[3][j] + "|" +cal[4][j] + "|");
}
}
}
/* 選擇複製「單一時間」的場合 */
else {
i = (Integer.parseInt(parts[1])/10) - 1;
j = (Integer.parseInt(parts[1]) - 10*(Integer.parseInt(parts[1])/10)) - 1;
/* 檢查是否該時段已有安排 */
if(cal[(Integer.parseInt(parts[2])/10 - 1)][(Integer.parseInt(parts[2]) - 10*(Integer.parseInt(parts[2])/10)) - 1].equals(" ") == false)System.out.println("\n輸入狀況有誤,請重新輸入。");
else cal[(Integer.parseInt(parts[2])/10 - 1)][(Integer.parseInt(parts[2]) - 10*(Integer.parseInt(parts[2])/10)) - 1] = cal[i][j];
System.out.println ("\n | 一 | 二 | 三 | 四 | 五 |");
for(j = 0;j <= 8;j++)System.out.println ((j+1) + "|" + cal[0][j] + "|" + cal[1][j] + "|" + cal[2][j] + "|" + cal[3][j] + "|" +cal[4][j] + "|");
}
}
System.out.print("請輸入指令:");
input = ConsoleIn.readLine();
parts = input.split(",");
op = parts[0];
}
}
}
如果整理一下多分成幾個 function ,會更好啊。
回覆刪除例如
/* add,新增行程 */ /* del,刪除行程 */ /* copy,複製行程 */
那幾段就可以整理出來獨立的 function 叫做 AddSchedule()、DelSchedule()、CopySchedule()
因為一段程式超過 100 行,就會開始很難看懂了。(助教都很忙,可能一邊改作業還要一邊打魔獸,一次只能吸收一小段標明意義的 code)
還有 else if 的層級有點多了。
有個方法叫做這樣這樣,雖然也不見得每個人都覺得它很好用啦:
http://www.refactoring.com/catalog/replaceNestedConditionalWithGuardClauses.html
還有在判斷式裡面, true false 放在左邊比較省力,免得寫錯成 「 op.equals("del") = true 」(== 打成 =),又找半天找不到…
「 true = op.equals("del") 」就會讓 compiler 幫你查出寫錯了。
還有變數名稱叫做 i j 蠻容易找不到的,因為1.小 2.長得像,叫做 outeridx inneridx 可能會好找一點。
喔如果要寫三層的迴圈怎麼辦啊?三層的迴圈根本就不該被寫出來,因為沒有 programmer 會看得懂(包括一個月後的自己)。
對,我現在自己也看不懂...
回覆刪除不過這玩意兒會寫成這樣,是因為我寫完之後,教授才教我們什麼是物件導向...
物件導向實在是太方便了!為什麼不第一節課就教阿!(用力跺腳)
多謝學長的經驗分享(跪)