问题
编写程序对任何给定的正数和负数整数数组进行排序,使得正数跟随负数,但正数和负数的相对位置保持不变。如下面的示例(1)中所示,( - 7)发生在(-5)之后,因此在排序数组(-7)之后(-5)。
程序只应迭代给定数组一次,不应使用临时数组。
示例1。 给定数组:{2,4,-5,0,-7,-2,2,-5,1,-9,-7,-1}
排序数组:{ - 5,-7,-2,-5,-9,-7,-1,2,4,0,2,1}
示例2。 给定数组:{-3,7,0,-2,-1,3,-3,9,5,5,-5,8}
排序数组:{ - 3,-2,-1,-3,-5,7,0,3,9,5,8}
我的解决方案
class Program
{
public static void Main(string[] args)
{
var intArray = new int[] { 2, 4, -5, 0, -7, -2, 2, -5, 1, -9, -7, -1 };
var sorted_intArray = SortIntArray(intArray);
Console.WriteLine(String.Join(",", sorted_intArray));
intArray = new int[] { -3, -2, -1, -3, -5, 7, 0, 3, 9, 5, 8 };
sorted_intArray = SortIntArray(intArray);
Console.WriteLine(String.Join(",", sorted_intArray));
Console.ReadLine();
}
private static int[] SortIntArray(int[] intArray)
{
var sorted_intArray = intArray.GroupBy(_int => _int < 0 ? -1 : 1)// Create group of +ve and -ve numbers
.OrderBy(group => group.Key) // Bring group of -ve number first
.SelectMany(groupedItems => groupedItems).ToArray(); // Select num from both Group and convert to array
return sorted_intArray;
}
}
问题
i)问题陈述说,数字应该只迭代一次,不应该使用临时数组。我相信我使用linq的解决方案不符合此要求。如果可能,如何用linq解决上述问题?
ii)使用或不使用linq可以解决上述问题的其他可行且有效的方法是什么?使用C / C ++的解决方案也很好。
答案 0 :(得分:3)
根据this OrderBy
稳定如此:
enumerable.OrderBy(x => x >= 0);
答案 1 :(得分:1)
Linq很棒:
private static int[] SortIntArrayWithDuplicates(IEnumerable<int> intArray)
{
var enumerable = intArray as int[] ?? intArray.ToArray();
return enumerable.Where(x => x < 0)
.Concat(enumerable.Where(x => x >= 0))
.ToArray();
}
private static int[] SortIntArrayWithoutDuplicates(IEnumerable<int> intArray)
{
var enumerable = intArray as int[] ?? intArray.ToArray();
return enumerable.Where(x => x < 0)
.Union(enumerable.Where(x => x >= 0))
.ToArray();
}
答案 2 :(得分:0)
根本不需要分组。 Linq-to-objects是稳定的&#34; (meainig在使用OrderBy
时会保留&#34;重复&#34;对象的原始顺序,因此您可以根据数字是否小于零进行排序:
private static int[] SortIntArray(int[] intArray)
{
var sorted_intArray = intArray.OrderBy(i => i < 0 ? 0 : 1).ToArray();
return sorted_intArray;
}
输出:
-5,-7,-2,-5,-9,-7,-1,2,4,0,2,1
-3,-2,-1,-3,-5,7,0,3,9,5,8
请注意,如果您将返回类型更改为IEnumerable<int>
,则可以避免ToArray
调用并减少内存使用量。
您是否将Linq订购计算为&#34;迭代一次&#34;取决于谁给了你这个要求。我不知道任何可以一次完成的排序算法。
使用或不使用linq可以解决上述问题的其他可行且有效的方法是什么?
好吧,我可以通过扫描所有数字来看看你如何在两个传递中做到这一点,首先采取负数,然后再扫描,采取所有非负数。您可以使用yield
语法简化此操作:
private static IEnumerable<int> SortIntArray(int[] intArray)
{
foreach(var i in intArray)
if(i < 0) yield return i;
foreach(var i in intArray)
if(i >= 0) yield return i;
}
答案 3 :(得分:0)
我喜欢这些:
按升序排序
enumerable.OrderBy(x => x);
按降序排列
enumerable.OrderByDescending(x => x);