1.若f[]和g[]都有n個元素,試證明這個程式最多只會比較2n次。
2.如果f[]與g[]中有相同元素時,這個程式還正確嗎?為什麼?
3.請修改程式,把在g[]中小於每一個f[i]的元素都顯示出來。
個人解法:
1. 在程式中,每次比較的結果必定是f[]的index++,
或者g[]的index++。
所以最多可能產生的比較次數的狀況就是兩者都跑到底,也就是2n次。
可能成立嗎?可以的XD
只要考慮g[n-1]<f[n-1]<g[n]<f[n]這樣的情況,
就可以保證兩邊都會跑到尾了。
2. f[]中有相同元素的時候程式不會影響,
因為由小到大排序,當f[]如像11,12,12,12,13,13,g[]像8,12,13,14,15,
我們找到第一個12去比較8時,仍然可以保證其後的值仍大於8。
g[]的狀況也是一樣,因為比較都是一個一個去比的,
f[]不夠大會找下一個來比,g[]不夠大也會找自己的下一個來比,
所以不會影響程式的正確性。
3.我們可以另外產生一個陣列h[]來記錄。
h[i]的值表f[i]是從g[]的第幾個值以前比較大。
注意要控制迴圈的條件,如果因為g[]的序列先跑完的話,
h[]要把後面的值補滿。(皆為n)
Code大概長這樣:
int gt_cnt(int f[], int g[], int h[], int m, int n) { int cnt = 0, _fi = 0, _gi = 0, _hi = 0; while( (_fi < m) && (_gi < n) ) if(f[_fi] <= g[_gi]) { h[_fi] = _gi; _fi++; } else { cnt += m-_fi; _gi++; } while( _fi < m ) h[_fi++] = n; printf("For all elements in g[] "); printf("which are less than f[i]:"); while( _hi < m ) { _gi = 0; printf("\nf[%2d]: ", _hi); while( _gi < h[_hi]) printf("%d ", g[_gi++]); _hi++; } return cnt; }
執行結果像這樣子:
測資: f[] = {1,3,5,7,9,10,11,12,13,15,17,18,19,20,21} g[] = {5,6,7,8,9,10,12,13,18,19,20,21,22,23,24,25,26} // Output For all elements in g[] which are less than f[i]: f[ 0]: f[ 1]: f[ 2]: f[ 3]: 5 6 f[ 4]: 5 6 7 8 f[ 5]: 5 6 7 8 9 f[ 6]: 5 6 7 8 9 10 f[ 7]: 5 6 7 8 9 10 f[ 8]: 5 6 7 8 9 10 12 f[ 9]: 5 6 7 8 9 10 12 13 f[10]: 5 6 7 8 9 10 12 13 f[11]: 5 6 7 8 9 10 12 13 f[12]: 5 6 7 8 9 10 12 13 18 f[13]: 5 6 7 8 9 10 12 13 18 19 f[14]: 5 6 7 8 9 10 12 13 18 19 20 Count: 84
沒有留言:
張貼留言