2

問題の説明:

ベクトルを表す double[] 値のリストがあります。0 番目のベクトル要素はベクトルの物理的な長さに対応し、他の 3 つ (1 ~ 3) は x、y、および z コンポーネントに対応します。リストには、約 1000000 のエントリが含まれています。したがって、パフォーマンスが問題になります。ベクトルの長さに従ってリストを並べ替えました。次に、例に示すように、異なる長さのベクトルが残るようにリストをフィルター処理する必要があります。また、長さが同じフィルターの場合、位置 1 から 3 に異なるエントリ (順列ではない) を含むものも残ります。さらに情報が必要な場合はお知らせください。フィルタリング プロセス中にベクトルを変更しないでください。

質問: これは、C# を使用して、可能であれば linq を使用してどのように実装できますか?

例:

 0,    0,     0;      0,0000   ->   select 
 0,    1,    -1;      8,2883   ->   select
 1,    0,    -1;      8,2883   ->   not select
 0,   -1,     1;      8,2883   ->   not select
-1,    0,     1;      8,2883   ->   not select
 1,   -1,     0;      8,2883   ->   not select
-1,    1,     0;      8,2883   ->   not select
 1,    1,    -2;     14,3558   ->   select
...
 2,     2,    -5;    38,6145   ->   select
-2,    -2,     5;    38,6145   ->   not select
 1,     4,    -4;    38,6145   ->   select
 4,     1,    -4;    38,6145   ->   not select
-1,    -4,     4;    38,6145   ->   not select
-4,    -1,     4;    38,6145   ->   not select
-1,     4,    -4;    38,6145   ->   not select
 4,    -1,    -4;    38,6145   ->   not select
-4,     1,     4;    38,6145   ->   not select
 1,    -4,     4;    38,6145   ->   not select
-2,     5,    -2;    38,6145   ->   not select
 5,    -2,    -2;    38,6145   ->   not select
 2,    -5,     2;    38,6145   ->   not select
-5,     2,     2;    38,6145   ->   not select
 4,    -4,    -1;    38,6145   ->   not select
-4,     4,    -1;    38,6145   ->   not select
-4,     4,     1;    38,6145   ->   not select
 4,    -4,     1;    38,6145   ->   not select
...

コード:

private static double absm = 0;
private static int[] m = new int[3];
private static int[] m2 = new int[3];
private static List<double[]> ihkl1 = new List<double[]>();
private static List<double[]> ihkl2 = new List<double[]>();

...

private static void init_latt()
{
    for (int i = -kmax[2]; i < kmax[2]; i++ )
    {
        m[2] = i;
        for (int j = -kmax[1]; j < kmax[1]; j++)
        {
            m[1] = j;
            for (int k = -kmax[0]; k < kmax[0]; k++)
            {                        
                m[0] = k;
                absm = calcabsm(metten, m);                                             
                if (absm < gmax)
                {
                    double[] row1 = new double[4];
                    row1[0] = absm;
                    row1[1] = (double)m[0];
                    row1[2] = (double)m[1];
                    row1[3] = (double)m[2];
                    ihkl1.Add(row1);
                }
            }
        }
    }    
    ihkl2 = ihkl1.AsParallel().OrderBy(x => x[0]).ToList();
}
...
4

1 に答える 1

0

まず第一に、これらの配列をカプセル化するクラスを使用するというJon Skeet の提案に同意します。その後、次のことができます。Vectordouble

public class VectorEqualityComparer : IEqualityComparer<Vector>
{
    public bool Equals(Vector x, Vector y)
    {
        //here you implement the equality among vectors you defined in your question
    }

    public int GetHashCode(Vector obj)
    {
        //you can return something like obj.InnerArray.GetHashCode()
    }
}

のリストVector、つまりがあるyourList場合は、次のように呼び出すことができます。

var result = yourList.Distinct(new VectorEqualityComparer());

これがあなたが望むものを達成するのに役立つことを願っています. 幸運を!!!

于 2013-03-12T14:55:55.600 に答える