2011-10-21 9 views
0

私は、[i] [j]の数が[j] [i]の数と常に等しいという性質を持つN x N個の数の配列を持っているとします。つまり:ミラーリングされたNxNアレイで空間と時間を節約する方法

[ 0 3 9 2 ] 
[ 3 0 5 6 ] 
[ 9 5 0 1 ] 
[ 2 6 1 0 ] 

エレメントへのアクセスに時間とスペースを節約するために使用できる表現はありますか? [i] [j]と[j] [i]をメモリ内の同じ位置にインデックスすることによって、アレイサイズを半分に削減し、可能であればキャッシュミスのペナルティを減らします。

答えて

1

1次元配列を使用するだけで、スペースを節約し、アクセス時間に若干の変更があるかもしれませんが、高速であるかどうかにかかわらず、おそらくコンパイラと言語に依存します。

私はQtの中ですぐにこのソリューションを書きましたが、STLのC++または他の言語に変換するのは簡単でなければなりません:

#include <QVector> 
#include <QDebug> 
#include <QString> 

class MirroredArray 
{ 
public: 
    MirroredArray(int sideLength) 
    { 
     values.fill(0, sideLength*(sideLength+1)/2); 
     this->s = sideLength; 
    } 

    int get(int r, int c) 
    { 
     if(c > r) 
     { 
      return values.at(s*r-(r-1)*r/2 + c-r); 
     } 
     else 
     { 
      return values.at(s*c-(c-1)*c/2 + r-c); 
     } 
    } 

    void set(int r, int c, int value) 
    { 
     if(c > r) 
     { 
      values[s*r-(r-1)*r/2 + c-r] = value; 
     } 
     else 
     { 
      values[s*c-(c-1)*c/2 + r-c] = value; 
     } 
    } 
    int getSide() 
    { 
     return s; 
    } 

    QString contentsToString() 
    { 
     QString temp = "(" + QString::number(values.size()) + ") - "; 
     for(int i = 0; i<values.size(); i++) 
      temp += QString::number(i) + ", "; 
     return temp; 
    } 

private: 
    QVector <int> values; 
    int s; 
}; 

注:このコードは、あなたが渡していることを確認するすべてのエラーを行いません。有効な行と列の値。

+0

ありがとう! 1次元配列の問題は、十分な大きさのデータセットで作業しており、割り当ての単一のチャンクが失敗する可能性が高いことです。しかし、私はこれを多次元配列に適応させることができます。 – sooniln

+0

これを導出するときは、この式を使用して再利用します.1からnの合計はn *(n + 1)/ 2です。コールを見ると、n = m-1を設定し、(m-1)* m/2を1からm-1の合計として取得するようなバリエーションがあります。 [1からNまでの整数をまとめる方法](http://www.wikihow.com/Sum-the-Integers-from-1-to-N)も参照してください。 – phyatt

1

あなたはこのように1次元配列の要素を列挙することができます。

(n=5) 
5678 
    901 
    23 
    4 

配列の位置が(n + (n-y+1))*y/2 + (x-y)です。

x<yの場合は、2つの座標を入れ替えます。

+0

ありがとうございます!あなたが気にしないなら、その式をどのように導いたか説明できますか?その部分は、私が試していた機能に非常によく似ていますが、全体像を見たいのですが。 – sooniln

+1

最初の部分は算術級数(yの前の行)の合計です。S_n =(a_1 + a_n)* n/2、2番目の部分は行yの位置です。注:計算を高速化するには、-yを最初の項に移動することで少し簡単にすることができます。 –

関連する問題