[問題] 為什麼陣列從main中拿到global答案就錯?

看板C_and_CPP作者 (SurprisingTW)時間13年前 (2012/05/06 03:42), 編輯推噓3(3017)
留言20則, 3人參與, 最新討論串1/2 (看更多)
開發平台(Platform): (Ex: VC++, GCC, Linux, ...) Microsoft Visual Studio C++ 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) stdio.h iostream 問題(Question): 存放input的二為陣列放到全域之後答案就錯掉了 餵入的資料(Input): 2 2 -1 1 3 4 3 -1 -1 -1 2 2 2 -3 -3 -3 預期的正確結果(Expected Output): 5 -2 錯誤結果(Wrong Output): 5 -1 程式碼(Code):(請善用置底文網頁, 記得排版) #include<stdio.h> #include<iostream> using namespace std; #define MAX 1000 int n=0; int m[MAX][MAX]; int r=0; int t=0; int sum(int a[][1000],int i, int j) { if(i<0)i=0; else if(j<0)j=0; else if(j>n-1)j=n-1; else if(a[i-1][j-1] > a[i-1][j] && a[i-1][j-1] > a[i-1][j+1]){ //cout <<t; m[t][r++]=a[i][j]; return a[i][j]+sum(a, i-1, j-1); } else if(a[i-1][j] >= a[i-1][j-1] && a[i-1][j] >= a[i-1][j+1]){ //cout << t ; m[t][r++]=a[i][j]; return a[i][j]+sum(a, i-1, j); } else if(a[i-1][j+1] > a[i-1][j-1] && a[i-1][j+1] > a[i-1][j]){ //cout << t ; m[t][r++]=a[i][j]; return a[i][j]+sum(a, i-1, j+1); } } int main() { static int a[1000][1000]; //<-----------問題出在這 int cases=0; int q[MAX]; int p=0; int s[MAX]; cin >> cases; while(p<cases){ cin >> n; for(int i=0; i<n; i++)q[i]=0; for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ cin >> a[i][j]; } } /*for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ cout << a[i][j] << " "; } cout << endl; }*/ t=0; for(int j=0; j<n; j++){ sum(a, n-1, j); r=0; t++; //cout << t <<endl; } cout << endl; for(int i=0;i<n; i++){ for(int j=0; j<n; j++){ cout << m[i][j] <<" "; } cout << endl; } cout << endl; for(int i=0; i<n; i++){ for(int j=0; j<n; j++){ cout << q[i] << " " << m[i][j] << endl; q[i]=q[i]+m[i][j]; } cout << q[i] << endl; } //cout << endl; for(int i=0; i<n; i++){ if(q[i]>s[p])s[p]=q[i]; } p++; } for(int i=0; i<p; i++)cout << s[i] << endl; system("pause"); return 0; } 補充說明(Supplement): 這個題目是給一n*n的陣列 從最底層開始往左上 中上 右上走 哪個數字大就走哪邊 最後把路徑上經過的數字都加起來 po出最大的數字 如輸入-1 1 3 4 3走去1 加起來是4 4走去1 加起來是5 最後印出來是5 原本用比較小的陣列a[100][100]跑沒有問題 但是因為題目要求是1000*1000的大小 所以必須將陣列放到全域 不然stack overflow 但是放去global之後就出現奇怪的現象 code裡面有監看各個陣列的cout 陣列m是用來存行走的路徑 原本m[i][j]存入的值應該是-3 2 -1 -3 2 -1 -3 2 -1 卻變成 -3 2 0 -3 2 -1 -3 2 0 在下新手 看不出為什麼 希望高手解惑 另外 這個程式有bug 就是當某一層所有數字相等時 只會往正上方走 但這樣就變成不一定是最佳解 在下試過的判斷式都沒用 不然就是overflow 無奈只能讓他往正上方走 如果能提供解法 在下感激不盡<(_ _)> -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 114.43.161.241 ※ 編輯: initial1635 來自: 1.169.191.106 (05/06 12:11)

05/06 13:52, , 1F
你放到global後,sum裡面修改的a可能會和global的a
05/06 13:52, 1F

05/06 13:52, , 2F
混淆,建議用不同名稱,例如glo_a和sum_a,變數命名
05/06 13:52, 2F

05/06 13:53, , 3F
避免你想要修改函式內的a變成修改global的a
05/06 13:53, 3F

05/06 14:44, , 4F
感謝回復 我把全域的a改成ga main裡面的a都改成ga 跑
05/06 14:44, 4F

05/06 14:44, , 5F
起來結果一樣耶QQ
05/06 14:44, 5F

05/06 17:05, , 6F
sum 裡面某些情況下沒有回傳
05/06 17:05, 6F

05/06 18:56, , 7F
改用動態二維陣列?
05/06 18:56, 7F

05/06 19:21, , 8F
剛剛google了一下,可以修改stack的大小
05/06 19:21, 8F

05/06 20:02, , 9F
sum 裡面有可能 index 到 a 的範圍之外
05/06 20:02, 9F

05/06 20:04, , 10F
例如當 j == 0 時程式有可能會 index 到 a[i][j-1]
05/06 20:04, 10F

05/06 20:22, , 11F
05/06 20:22, 11F

05/06 20:22, , 12F
05/06 20:22, 12F

05/06 20:23, , 13F
直接在遞迴裡面計算下一步的最大值
05/06 20:23, 13F

05/06 20:24, , 14F
如果下一步是在範圍外的就不列入考慮
05/06 20:24, 14F

05/06 20:25, , 15F
把最大值和自己相加以後回傳給上一層
05/06 20:25, 15F

05/06 20:56, , 16F
05/06 20:56, 16F

05/06 20:57, , 17F
用 m[1000][1000] 把結果暫存起來,以避免重複計算
05/06 20:57, 17F

05/08 00:03, , 18F
謝謝回覆<(_ _)> 另外問一下 這題有沒有更快的演算法?
05/08 00:03, 18F

05/08 02:08, , 19F
有。Dynamic Programming
05/08 02:08, 19F

05/08 02:09, , 20F
用 Dynamic Programming 的話每個 m 只算一次,不用遞迴
05/08 02:09, 20F
文章代碼(AID): #1FfVCSmz (C_and_CPP)
文章代碼(AID): #1FfVCSmz (C_and_CPP)