4

2 つの配列をマージするために、この関数を作成します。

private static int[] Merge(int[] array1, int[] array2)
{
    var mergedArray = new int[array1.Length + array2.Length];
    int i = 0, j = 0, k = 0;
    while(k < mergedArray.Length)
    {
        if(i == array1.Length || j == array2.Length)
        {
             if (i <= j)
                {
                    mergedArray[k] = array1[i];
                    i++;
                }
                else
                {
                    mergedArray[k] = array2[j];
                    j++;
                }
        }
        else
        {
            if(array1[i] < array2[j])
            {
                mergedArray[k] = array1[i];
                i++;
            }
            else
            {
                mergedArray[k] = array2[j];
                j++;
            }
        }
        k++;
    }
    return mergedArray;
}

このコードの if ステートメントを減らす方法は?

4

6 に答える 6

11

Linq に適したバージョンを作成することもできます。これは高速で、IEnumerable で動作します。これは、T が IComparable である任意の型 T に簡単に変換できます。

    private static IEnumerable<int> Merge(IEnumerable<int> enum1, IEnumerable<int> enum2)
    {
        IEnumerator<int> e1 = enum1.GetEnumerator();
        IEnumerator<int> e2 = enum2.GetEnumerator();

        bool remaining1 = e1.MoveNext();
        bool remaining2 = e2.MoveNext();

        while (remaining1 || remaining2)
        {
            if (remaining1 && remaining2)
            {
                if (e1.Current > e2.Current)
                {
                    yield return e2.Current;
                    remaining2 = e2.MoveNext();
                }
                else
                {
                    yield return e1.Current;
                    remaining1 = e1.MoveNext();
                }
            }
            else if (remaining2)
            {
                yield return e2.Current;
                remaining2 = e2.MoveNext();
            }
            else
            {
                yield return e1.Current;
                remaining1 = e1.MoveNext();
            }
        }
    }
于 2012-07-11T21:14:15.987 に答える
2

配列に固有のものではなく、次の質問を見て、IEnumerable<T>. 並べ替えられた IEnumerable<T> をマージするための最も効率的なアルゴリズム

https://stackoverflow.com/a/14444706/184528で提供した回答には、 ステートメントが1 つしかなくif、複数の列挙型がマージされています。

たとえば、3 つの異なる配列をマージするために使用するには、次のようにします。

    public static void Main(string[] args)
    {
        var xs = new[] { 1, 5, 9 };
        var ys = new[] { 2, 7, 8 };
        var zs = new[] { 0, 3, 4, 6 };

        foreach (var a in new [] { xs, ys, zs }.Merge())
            Console.WriteLine(a);
    }
于 2013-01-21T18:32:06.590 に答える
0

これが関数の最も「縮小された」バージョンであるように私には思えます:

private static int[] Merge(int[] array1, int[] array2)
{
    return array1.Concat(array2).OrderBy(x => x).ToArray();
}

これ以上簡単なことはありません。if1つも残っていません。

Merge(new [] { 1, 2, 2, 3 }, new [] { 1, 1, 2, 4, })これを元のコードと私のソリューションの両方で実行したところ、同じ答えが得られました。

于 2015-10-06T03:17:23.547 に答える
-1

Queue<int>配列を空にするために使用するのはどうですか:

    private static int[] Merge(int[] array1, int[] array2)
    {
        int N=array1.Length+array2.Length;
        Queue<int> Q1=new Queue<int>(array1);
        Queue<int> Q2=new Queue<int>(array2);
        Queue<int> result=new Queue<int>(N);

        for(int k=0; k<N; k++)
        {
            if(Q1.Count==0)
            {
                result.Enqueue(Q2.Dequeue());
            }
            else if(Q2.Count==0)
            {
                result.Enqueue(Q1.Dequeue());
            }
            else
            {
                result.Enqueue(
                    Q1.Peek()<Q2.Peek()?
                    Q1.Dequeue():
                    Q2.Dequeue());
            }
        }
        return result.ToArray();
    }
于 2012-07-11T21:05:19.650 に答える