2016-05-13 5 views
-2

2次元配列の列を追加し、最小の合計を返すプログラムを作成する必要があります。これは私が書いたプログラムですが、より効果的な方法があるかどうかを知りたいのです。主なプログラムは教授によって私たちに与えられました。私は、各列の整数を宣言することなく、これを行う方法があるかどうかを知りたいのです。C++で2次元配列の列を集計する方法は?

#include <iostream> 
    #include <string> 
    using namespace std; 

    int smallCol(int x[][3], int row, int col){ 

    int c1 = 0; 
    int c2 = 0; 
    int c3 = 0; 
    int min; 

    for (int r = 0; r < row; r++){ 
     for(int c = 0; c < col; c++){ 
      if(c==0) 
       c1 += x[r][c]; 
      if(c==1) 
       c2 += x[r][c]; 
      if(c==2) 
       c3 += x[r][c];  

      } 


     } 

    min = c1; 

    if(c2 < c1) 
     min = c2; 

    if(c3 < c2) 
     min = c3; 

    return min;  
} 


    int main() { 
    int x[2][3] = {{3, 1, 4}, {1, 5, 9}}; 
    cout << "Smallest column sum is " << smallCol (x, 2, 3) << endl; 
    // from the 2-d array x that has size 2 x 3, find the smallest col sum 
    // output will be 4 since col#0 contains 3 and 1 is smallest. 
    return 0; 
    } 
+0

100カラムの2dアレイをサポートするにはどのくらいの時間がかかりますか?それは比較的小さい2次元アレイです。 –

答えて

2

あなたがネストされたループに切り替える場合は、1つの変数のみを使用することができます。

#include <limits> 

int smallCol(int x[][3], int row, int col){ 

    int min = std::numeric_limits<int>::max(); 
    // or something really big... like 2147483647 

    for (int c = 0; c < col; ++c) { 
     int sum = 0; 
     for(int r = 0; r < row; ++r) { 
      sum += x[r][c]; 
     } 
     if (min > sum) { 
      min = sum; 
     } 
    } 
    return min;  
} 

EDIT

を、それが割り当てられているとして、あなたがプログラムの主要な構成を変更することはできません場合は、ベクトルを使用して部分合計を保存し、それをスキャンして最小値を見つけることができます。

std::vector<int> sums(col); 

for (int r = 0; r < row; ++r) { 
    for(int c = 0; c < col; ++c) { 
     sums[c] += x[r][c]; 
    } 
} 
for(int c = 0; c < col; ++c) { 
    if (min > sums[c]) { 
     min = sums[c]; 
    } 
} 

メモリ内の要素が連続しているため、非常に大きな行列の方がキャッシュフレンドリになり、結果としてコードが高速になります。

+0

列の前の行を反復処理すると、ほとんどの場合、キャッシュの問題のためにコードが非常に遅くなります(私は10倍以上を見たことがあります)。 – RyanP

+0

もちろん@RyanPですが、小さな2次元配列について話しています。 –

+0

はこれに同意しました。これは巨大ではありません。私はちょうど "効率的な方法があるかどうかを知りたがっているか"と思っていました。なぜなら、それが必ずしも3列でなくても、1つの変数を使ってそれを行う方法を見つけることそれはより良い/より効率的でした。 – RyanP

2

ネストしたループの順序を変更します。最初に列をループし、その列のすべての行の合計を計算します。次に、各列の合計に変数は必要ありません。

int min; 
for (int c = 0; c < col; c++) { 
    int total = 0; 
    for (int r = 0; r < row; r++) { 
     total += x[r][c]; 
    } 
    if (c == 0 || total < min) { 
     min = total; 
    } 
} 

c == 0試験は、最初の列は特別に処理されることができるので、最初の列から合計minを初期化します。残りの列はそれと比較されます。

+0

少なくとも、異なる方法で 'min'を初期化しています...;) –

0
int smallCol 
{ 
    auto min = std::numeric_limits<int>::max(); 

    for (auto i = 0; i < col; ++i) 
    { 
     auto m = std::accumulate(x, x + row, 0, [i](int sum, auto && row) { return sum + row[i]; }); 
     if (m < min) min = m; 
    } 

    return min; 
}