按顺序将两个 int 数组合并为一个数组不起作用

时间:2021-01-09 20:18:58

标签: c# arrays

我需要按数字顺序将数组合并为一个 问题是当数组中的一个在数组中将她的所有部分组合在一起时, iA 或 iB 大于数组长度

static void Merge(int[] a, int[] b)
{
    int[] c = new int[a.Length + b.Length];
    int iA = 0, iB = 0, iC = 0;
    
    while (iA < a.Length && iB < b.Length)
    {
        if (a[iA] < b[iB])
        {
            c[iC] = a[iA];
            iC++; iA++;
        }
        else if (a[iA] > b[iB])
        {
            c[iC] = b[iB];
            iC++; iB++;
        }
        else
        {
            c[iC] = a[iA];
            iC++; iA++;
            c[iC] = b[iB];
            iC++; iB++;
        }
    }

    for (int i = 0; i < c.Length; i++)
    {
        Console.WriteLine(c[i]);
    }
}

然后我执行它

static void Main()
{
    int[] a = { 1, 2, 3, 4, 5};
    int[] b = { 2, 5, 8, 11};
    Merge(a, b);
}

这是输出

5
8
10
11
0
0
0
0
Press any key to continue . . .

求求解决办法

4 个答案:

答案 0 :(得分:2)

我们只需要 for 循环:

static void Merge(int[] left, int[] right) 
  for (int indexLeft = 0, indexRight = 0; 
       indexLeft < left.Length || indexRight < right.Length;) 
    if (indexRight >= right.Length || 
       (indexLeft < left.Length && left[indexLeft] <= right[indexRight])) 
      Console.WriteLine(left[indexLeft++]);
    else
      Console.WriteLine(right[indexRight++]);
}

我们通过两个 leftright 数组(indexLeftindexRight)移动,我们从 left 数组打印项目当且仅当

  1. 我们用完了 right 数组:indexRight >= right.Length
  2. 如果我们在 leftright 数组和 left[indexLeft] <= right[indexRight] 中都有项目

否则我们打印 right 数组项。

编辑:如果要返回合并数组 (result):

static int[] Merge(int[] left, int[] right) {
  int[] result = new int[left.Length + right.Length];
  int index = 0;

  for (int indexLeft = 0, indexRight = 0; 
       indexLeft < left.Length || indexRight < right.Length;) 
    if (indexRight >= right.Length || 
       (indexLeft < left.Length && left[indexLeft] <= right[indexRight])) 
      result[index++] = left[indexLeft++];
    else
      result[index++] = right[indexRight++];

  return result;
}

答案 1 :(得分:1)

这是解决问题的完全不同的方法。它适用于实现 IComparable<T> 的任何类型的任何类型的集合(即,任何 IEnumerable<T> where T: IComparable<T>

它使用简单的枚举,没有索引。它确实需要对输入进行预先排序。我没有测试先决条件为假时会发生什么(我也没有检查先决条件(因为你不想排序))。

 public static IEnumerable<T> Merge<T>(IEnumerable<T> first, IEnumerable<T> second) where T : IComparable<T>
 {
     //assumption: both first and second are already sorted.
     var firstEnumerator = first.GetEnumerator();
     var secondEnumerator = second.GetEnumerator();
     var result = new List<T>();
     if (!firstEnumerator.MoveNext())
     {
         //nothing in first collection, so...
         return second;
     }

     if (!secondEnumerator.MoveNext())
     {
         //nothing in second collection, so...
         return first;
     }

     var firstComplete = false;
     var secondComplete = false;

     while (true)
     {
         if (firstComplete && secondComplete)
         {
             break;
         }
         if (secondComplete || (!firstComplete && firstEnumerator.Current.CompareTo(secondEnumerator.Current) < 0))
         {
             result.Add(firstEnumerator.Current);
             if (!firstEnumerator.MoveNext())
             {
                 firstComplete = true;
             }
         }
         else if (!secondComplete)
         {
             result.Add(secondEnumerator.Current);
             if (!secondEnumerator.MoveNext())
             {
                 secondComplete = true;
             }
         }
     }

     return result;
 }

这是一些测试代码:

var first = new[] {1, 4, 300, 2000};
var second = new[] {2, 4, 6, 8, 10, 12, 14, 2500};
var result = Merge(first, second);
foreach (var item in result)
{
    Debug.WriteLine(item);
}

我试过颠倒第一个和第二个任务,以及其他一些组合。输出看起来像:

1
2
4
4
6
8
10
12
14
300
2000
2500

答案 2 :(得分:0)

Array 实现了 IEnumerable<T>,因此可以使用 IEnumerable 的扩展方法。
下面是一个例子:

int[] array_1 = { 1, 3, 6 };
int[] array_2 = { 2, 5 };
int[] array_3 = array_1.Concat(array_2).OrderBy(nr => nr).ToArray();  
  
// array_3: { 1, 2, 3, 5, 6 }

答案 3 :(得分:0)

这是另一种可能更容易阅读的方法:

private static int[] Merge(int[] a, int[] b)
{
    int[] c = new int[a.Length + b.Length];
    int iA = 0, iB = 0, iC = 0; 
    while (iC < c.Length) 
    {
        c[iC++] = iA < a.Length
            ? iB < b.Length 
                ? a[iA] < b[iB] 
                    ? a[iA++] 
                    : b[iB++]
                : a[iA++]
            : iB < b.Length 
                ? b[iB++] 
                : throw new InvalidOperationException();
    }
    return c;
}
static void Main(string[] args)
{
    int[] a = { 1, 2, 3, 4, 5 };
    int[] b = { 2, 5, 8, 11 };
    int[] c = Merge(a, b);
    for (int i = 0; i < c.Length; i++)
    {
        Console.WriteLine(c[i]);
    }
}