i am writing a code in c# to sort an array, i want all the negative values in the right side and all the positive values in the left side, the should not be in decreasing order
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(" ");
}
}
}
}
but the output is something like this (-20 is on wrong side):
5 10 9 8 -20 6 7 -14 15 -16 -4 -1 -2
but the intended output is:
5 10 9 8 15 6 7 -14 -20 -16 -4 -1 -2
Why is my code not producing my intended output?
Your solution incorrectly decides when to finish the loop. Also, it unconditionally increments i
in the loop header, and never decrements size
even when it points to a negative number.
Here is how you fix it:
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--;
}
}
Here is a demo on ideone .
You can rewrite this loop using a more readable identifiers for your left
and right
pointers, rather than using i
and size
. This would make your algorithm look more "symmetric" in the code, to recognize the symmetry in its design:
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--;
}
}
Try this solution:
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();
The problem with your algorithm is that when you decrease size
, you end up having newInt[size]
point at a negative value, and the if
block is not entered.
The general idea for a pretty easy easy solution would be to start one index, call it left
at the beginning of the array, and another, called right
at the end of the array.
Increment left
until you find a negative number, or until left == right
. When you hit a negative number, decrement right
until you find a positive number, or until right == left
.
If left
is indexing a negative number and right
is indexing a positive number, swap the two items and start incrementing left
again.
The general idea, not tested:
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;
}
This yields the desired order with a minimum of loops
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
if you can use generics and linq than the easiest solution would be :
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();
Hope this will help !!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.