2013-01-06 14 views
3

我在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

@pst我不同意,他們都在問關於他們的具體的解決方案,這是不一個完整的排序,但只是'在右側有負面'。搜索排序算法並不能解決他們的問題。 – us2012

+0

預期輸出爲: 5 10 9 8 15 6 7 -14 -20 -16 -4 -1 -2, 對於不便,我們深表歉意 – Justice

+0

在您預期的輸出情況下,排序也不穩定(15出現在6 ),所以,儘管理解算法不正確的原因很重要,但是像這樣的東西可以在LINQ中工作:arr = arr.OrderBy(e => e> 0?0:1).ToArray()' – 2013-01-06 05:11:06

回答

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--; 
    } 
} 

這裏是一個demo on ideone

您可以使用更易讀的標識符爲leftright指針重寫此循環,而不是使用isize。這將使你的算法的代碼看起來更「對稱」,承認在其設計的對稱性:

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--; 
    } 
} 

這裏是an ideone link to the alternative implementation

+0

非常感謝你這段代碼給了我我想找的東西 – Justice

+0

@MustansirSabir歡迎您!如果您的問題解決了,您可能需要點擊旁邊複選標記的灰色輪廓接受答案。這將表明您不再尋找改進的解決方案來解決這個問題,併爲您獲得堆棧溢出的全新徽章。 – dasblinkenlight

+0

感謝您所需的提示,我在這裏新建 – Justice

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(); 

希望這將幫助!

+2

返回'排序'的類型\t是'無效' –

+0

OP不希望排序。他希望2個分區各有一個負值和正值 – Tilak

+0

謝謝@mikez我已更新答案。 –

2

嘗試這種解決方案:

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塊。

1

一個非常容易的簡單解決方案的一般想法是啓動一個索引,在數組的開頭稱爲left,另一個索引right在數組末尾。

遞增left,直到找到一個負數或直到left == right。當您輸入負數時,請將right減1,直至找到正數,或直至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; 
} 
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 
+0

給定數組「{0,-1,1,0}」,這永遠不會終止。它將永遠交換第一個和最後一個項目。 '0'是正值還是負值? –

+0

你說得對。我現在將0視爲積極的。另一種可能性是在正數和負數之間放置0。但那需要額外的治療。 –

相關問題