我需要按数字顺序将数组合并为一个 问题是当数组中的一个在数组中将她的所有部分组合在一起时, 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 . . .
求求解决办法
答案 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++]);
}
我们通过两个 left
和 right
数组(indexLeft
,indexRight
)移动,我们从 left
数组打印项目当且仅当
right
数组:indexRight >= right.Length
。left
和 right
数组和 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]);
}
}