1. 請改寫程式,指出最長平台的位置。
2. 請寫一個程式,接收一個已經自小到大排好的陣列,
把所有平台與它的位置都找出來。
3. 如果給定的陣列沒有依序排好,
請寫一個程式可以找出所有平台與它們的位置,
但給定的陣列卻不一定要排列好。
(程式還可以只比n次就找到答案嗎?)
4.寫成遞迴的模式。
個人解法:
1. 我們插入一個變數來記錄一個平台的結束點,
按照原方法,當找到一個更長的平台時,
就把結束點再次變更到該索引值。
Code:
// Use *index to remember the end point. int longest_pl(int x[], int n, int* index, int* len) { *len = 1; int i; for(i = 1; i < n; i++) if( x[i] == x[i-*len] ) { *len = *len + 1; *index = i; } return *len; }
2&3. 改寫大概就不能用原來那套的方法了,
因為必定要加入變數來記錄位置,所以就乾脆換方法吧?
Code:
// Complexity is O(n) void all_pldata(int x[], int n, int rec[][3]) { int i; int tmp = 0; int cnt = 0; for(i = 1; i < n; i++) { if( x[i] != x[tmp] ) { rec[cnt][0] = x[tmp]; rec[cnt][1] = tmp; rec[cnt][2] = i-tmp; // printf("%d : Index %d ~ %d\n", x[tmp], tmp, i-1); tmp = i; cnt++; } else if( i + 1 == n ) // Last index { rec[cnt][0] = x[tmp]; rec[cnt][1] = tmp; rec[cnt][2] = i-tmp+1; // printf("%d : Index %d ~ %d\n", x[tmp], tmp, i); cnt++; rec[cnt][0] = -1; } } for(i=0; i<cnt; i++) { printf("%d : Index %d ~ %d\n", rec[i][0], rec[i][1], rec[i][1]+rec[i][2]-1); } }
int rec[][3]的一維長度設為n。每一組rec[]中存的依序為:
平台的數字、平台起始點、平台長度。
當中注意要處理最後一組的狀況,會有一點點差異。
如果不是全部平台長度為1,則rec不會被用完,在尾端補上-1,
可以方便外界想使用的時候,能有迴圈的終止條件。(否則會一路跑下去)
當然如果覺得多花了記憶體空間的話,也可以先找出共有幾組平台,
再進行宣告並把資料丟進去,只是就會多出先跑一次的執行時間。
比較的次數依舊為n次,因為開頭從i=1開始,
但結束的時候可能會跑過if以及else if兩個判斷式。
其實tricky一點來說,還要考慮n==1的狀況XD
// 把它放在函式的開頭! if(n==1) { printf("%d : Index %d ~ %d\n", x[0], 0, 0); return; }
4.其實跟原本的樣子差不多,寫成遞迴不會比較快就是了@@"
Code:
// 丟出來的時候不要忘了用*來取值。 int* recur_pl(int x[], int n, int *i, int* len) { // Let *len = 1, i = 1 when first time calling this function. if(*i == n) return len; if( x[*i] == x[*i-*len] ) *len = *len + 1; *i = *i + 1; return recur_pl(x, n, i, len); }
Hi, 請問你覺得書上特別提到遞迴作法有什麼原因嗎?我看起來覺得它只是把 for-loop 變成遞迴,反而秏在 function call 上面。謝謝~ :p
回覆刪除您好: )
刪除一般來說用遞迴取代for-loop大約有幾點好處:
1.容易思考。
這其實很不負責任XD
因為完全不計較效率的狀況,用遞迴基本上只要會把大的問題拆成小的,
然後再給出最小單位的問題的答案即可。
2.比較不用在意迴圈的執行次數。
很多發生bug情況大多在於差一個1少執行一次,
或多執行一次,遞迴同樣不用考慮這個東西。
3.有些拆分方法會使得遞迴能具有效率且易讀。
可以的話請參照後面的快速Fibonacci算法一文,
在解法中我們使用每次拆成一半的方式,
但碰到奇數次則是拆成n+n+1的型式,
這種拆法可以令程式加快,但如果相同方式要硬寫成迴圈,
可讀性則會大幅降低,每次所要考慮的迴圈條件也較麻煩。
在多個判斷式的條件下,相對於耗在function call上來說,
可能就較不理想了。
謝謝您的回應~
最近因為即將上班的關係,較沒有空來繼續往下解,
之後安定下來以後會繼續的XD 也請持續支持~