4

我编写此函数用于合并两个数组。

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 回答
10

不如 Linq 解决方案,但如果您想要传统的 if-then 样式函数,您可以编写:

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 (j == array2.Length || ((i < array1.Length) && (array[i] < array2[j])))
        {
            mergedArray[k] = array1[i];
            i++;
        }
        else
        {
            mergedArray[k] = array2[j];
            j++;
        }
        k++;
    }
    return mergedArray;
}

(编辑:添加了缺少的大括号)

或者用英语:

如果array2为空或者如果array 1中还有值并且array1[i]小于array2[j],则从array1中取值,否则从array 2中取值

或者非常简洁(只是为了好玩):

private static int[] Merge(int[] array1, int[] array2)
{
    var mergedArray = new int[array1.Length + array2.Length];
    int i = 0, j = 0;
    while(i+j < mergedArray.Length)
        if (j == array2.Length || ((i < array1.Length) && (array1[i] < array2[j])))
            mergedArray[i+j] = array1[i++];
        else
            mergedArray[i+j] = array2[j++];
    return mergedArray;
}
于 2012-07-11T20:50:18.447 回答
4

Linq 是你的朋友,这是一种方法:

private static int[] Merge(int[] array1, int[] array2)
{
  List<int> merged = new List<int>(array1.Length + array2.Length);
  merged.AddRange(array1);
  merged.AddRange(array2);
  return merged.GroupBy(x => x)
               .Select(x => x.Key)
               .OrderBy(x => x)
               .ToArray();
}
于 2012-07-11T20:40:30.910 回答
2

我建议不要专门针对数组,而是查看以下问题以获取IEnumerable<T>. 合并排序的 IEnumerable<T> 的最有效算法

我在https://stackoverflow.com/a/14444706/184528提供的答案 只有一个if语句并合并多个枚举。

例如使用它来合并三个不同的数组:

    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();
}

没有比这更简单的了。一个都不if剩了。

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 回答