我在c#中编写一个代码来对数组进行排序,我希望右侧的所有负值和左侧的所有正值都不应该按降序排列
namespace SortApp
{
class Program
{
static void Main(string[] args)
{
int[] newInt = new int[] { 5, -2, -1, -4, -20, 6, 7, -14, 15, -16, 8, 9, 10 };
int size = 12, i= 0; // or newInt.Length
for (i = 0; i < newInt.Length; i++)
{
if (newInt[i] < 0 && newInt[size] > 0)
{
int temp = newInt[i];
newInt[i] = newInt[size];
newInt[size] = temp;
size--;
}
}
for (i = 0; i < newInt.Length; i++)
{
Console.Write(newInt[i]);
Console.Write(" ");
}
}
}
}
但输出是这样的(-20是错误的一面):
5 10 9 8 -20 6 7 -14 15 -16 -4 -1 -2
但预期的输出是:
5 10 9 8 15 6 7 -14 -20 -16 -4 -1 -2
为什么我的代码没有产生我想要的输出?
答案 0 :(得分:5)
您的解决方案错误地决定何时完成循环。此外,它无条件地在循环标题中递增i
,并且即使它指向负数也不会递减size
。
以下是解决问题的方法:
for (i = 0; i < size ; ) {
if (newInt[i] < 0 && newInt[size] >= 0) {
int temp = newInt[i];
newInt[i] = newInt[size];
newInt[size] = temp;
size--;
i++;
continue;
}
if (newInt[i] >= 0) {
i++;
}
if (newInt[size] < 0) {
size--;
}
}
您可以使用left
和right
指针的更易读的标识符重写此循环,而不是使用i
和size
。这将使您的算法在代码中看起来更“对称”,以识别其设计中的对称性:
int left = 0, right = newInt.Length-1;
while (left < right) {
if (newInt[left] < 0 && newInt[right] >= 0) {
int temp = newInt[left];
newInt[left] = newInt[right];
newInt[right] = temp;
right--;
left++;
continue;
}
if (newInt[left] >= 0) {
left++;
}
if (newInt[right] < 0) {
right--;
}
}
答案 1 :(得分:3)
试试这个解决方案:
var newInt = new[] {5, -2, -1, -4, -20, 6, 7, -14, 15, -16, 8, 9, 10};
var solution = newInt.GroupBy(i => i > 0).
SelectMany(g => g).
ToArray();
您的算法存在的问题是,当您减少size
时,最终会将newInt[size]
指向负值,并且不会输入if
块。
答案 2 :(得分:1)
一个非常简单的解决方案的一般想法是启动一个索引,在数组的开头调用它left
,在数组的末尾调用另一个索引right
。 / p>
增加left
,直到找到负数,或直到left == right
。当您点击一个负数时,递减right
直到找到正数,或直到right == left
。
如果left
正在为负数编制索引而right
正在为正数编制索引,则交换这两项并再次开始递增left
。
一般的想法,未经测试:
int left = 0;
int right = a.Length-1;
while (left < right)
{
if (a[left] < 0)
{
while (right > left)
{
if (a[right] >= 0)
{
// swap here
int temp = a[left];
a[left] = a[right];
a[right] = temp;
break;
}
--right;
}
}
++left;
}
答案 3 :(得分:1)
这产生了具有最小循环的期望顺序
int[] newInt = new int[] { 5, -2, -1, -4, -20, 6, 7, -14, 15, -16, 8, 9, 10 };
int lt = 0;
int rt = newInt.Length - 1;
while (true) {
// Find first negative number
while (newInt[lt] >= 0 && lt < rt) {
lt++;
}
// Find last positive number
while (newInt[rt] < 0 && rt > lt) {
rt--;
}
if (lt == rt) {
break; // Finished
}
// Swap
int temp = newInt[lt];
newInt[lt] = newInt[rt];
newInt[rt] = temp;
}
//TODO: Print result
答案 4 :(得分:0)
如果您可以使用泛型和linq而不是最简单的解决方案:
int[] newInt = new int[] { 5, -2, -1, -4, -20, 6, 7, -14, 15, -16, 8, 9, 10 };
newInt.ToList().Sort();
newInt.Reverse();
newInt = newInt.ToArray();
希望这会有所帮助!!