[英]Place all distinct elements of the array to the left in C#
我正在嘗試編寫一個程序,將數組的所有不同元素放置在同一數組的左側,而所有其他(非不同的)元素則以任意順序緊隨其后。 時間復雜度必須為O(n log n),即使用排序並且不必創建其他數組。 我嘗試使用以下代碼打印不同的元素:
using System;
using System.Diagnostics;
public class Program
{
public static void Main()
{
int []arr = {1, 1, 6, 5, 4, 3, 4, 6, 1, 7, 2, 1, 4, 9};
allDistinct(arr);
}
public static void allDistinct(int[] x)
{
int n = x.Length;
Trace.Assert(n>0);
Array.Sort(x); //O(n log n)
for (int i = 0; i < n; i++)
{
// Move the index ahead while
// there are duplicates
while (i < n - 1 && x[i] == x[i + 1])
i++;
}
Console.WriteLine(x[i]);
}
}
但是,我希望函數的形式為
public static int[] allDistinct(int[] x)
然后使用輔助函數在Main()中打印數組
printArray(allDistinct(arr));
哪里
public static void printArray(int[] array)
{
for(int i=0; i<array.Length; ++i)
{
Console.Write("" + array[i] + " ");
}
Console.WriteLine("");
}
我嘗試使用swap函數,但沒有成功獲得想要的結果,即給出了數組
1 1 6 5 4 3 4 6 1 7 2 1 4 9
我的輸出應該是
1 2 3 4 5 6 7 9 + (duble elements in whatever order, e.g. 1 1 1 4 4 6)
感謝您的意見
我有一個完整的例子 :
using System.IO;
using System;
class Program
{
static void Main()
{
int[] array = {1, 1, 6, 5, 4, 3, 4, 6, 1, 7, 2, 1, 4, 9};
allDistinct(array);
}
static int[] allDistinct(int[] array)
{
Array.Sort(array);
printArray(array); // first step monitoring
int n = array.Length;
// iterate through array
for(int i=0;i<n-1;i++)
{
// bubble push duplicates to the back
while(array[i] == array[i+1])
{
for(int j=i+1;j<n-1;j++)
{
array[j] = array[j+1];
}
array[n-1] = array[i];
n--;
}
printArray(array); // loop steps monitoring
}
return array;
}
static void printArray(int[] array)
{
Console.WriteLine(string.Join(" ", array));
}
}
這將產生以下輸出:
1 1 1 1 2 3 4 4 4 5 6 6 7 9
1 2 3 4 4 4 5 6 6 7 9 1 1 1
1 2 3 4 4 4 5 6 6 7 9 1 1 1
1 2 3 4 4 4 5 6 6 7 9 1 1 1
1 2 3 4 5 6 6 7 9 4 4 1 1 1
1 2 3 4 5 6 6 7 9 4 4 1 1 1
1 2 3 4 5 6 7 9 6 4 4 1 1 1
1 2 3 4 5 6 7 9 6 4 4 1 1 1
請注意,這將更改原始數組的順序 並返回它,因為數組無法在C#中按值傳遞。
編輯:
關於冒泡推送,您可以計算重復次數並加倍努力:
static int[] allDistinct2(int[] array)
{
Array.Sort(array);
printArray(array);
int n = array.Length;
for(int i=0;i<n;i++)
{
int countDup = 0;
int iValue = array[i];
// Count the number of duplicates
for(int j=i+1;j<n && array[j] == iValue;j++)
{
countDup++;
}
Console.WriteLine("// " + countDup + " time(s) the value " + iValue);
if(countDup > 0)
{
for(int j=i+1;j<n-countDup;j++)
{
array[j] = array[j+countDup];
}
for(int j=n-countDup;j<n;j++)
{
array[j] = iValue;
}
}
n-=countDup;
printArray(array);
}
return array;
}
這樣產生:
1 1 1 1 2 3 4 4 4 5 6 6 7 9
// 3 time(s) the value 1
1 2 3 4 4 4 5 6 6 7 9 1 1 1
// 0 time(s) the value 2
1 2 3 4 4 4 5 6 6 7 9 1 1 1
// 0 time(s) the value 3
1 2 3 4 4 4 5 6 6 7 9 1 1 1
// 2 time(s) the value 4
1 2 3 4 5 6 6 7 9 4 4 1 1 1
// 0 time(s) the value 5
1 2 3 4 5 6 6 7 9 4 4 1 1 1
// 1 time(s) the value 6
1 2 3 4 5 6 7 9 6 4 4 1 1 1
// 0 time(s) the value 7
1 2 3 4 5 6 7 9 6 4 4 1 1 1
// 0 time(s) the value 9
1 2 3 4 5 6 7 9 6 4 4 1 1 1
將數組的所有不同元素放在同一數組的左側
我沒有要求對結果集進行排序。 唯一的要求是元素的排列方式應使所有重復項晚於所有不同值。
如果不需要對結果集進行排序,則沒有理由調用Array.Sort()
(這實際上是一種作弊); 我們可以編寫自己的解決方案來自行整理數字。
該算法通過從頭開始並查找重復項來解決問題。 找到一個后,將其交換到位,並將數組的上邊界向下移動。 如果末尾的元素沒有重復項,我們將其與第一個元素交換,並向上調整下邊界,以免再次查看。
public class Program
{
public static int[] DistinctFirst(int[] arr)
{
var lbound = 0;
var ubound = arr.GetUpperBound(0);
var i = ubound;
while ( i>lbound )
{
var k = i;
for (int j=i-1; j>=lbound; j--)
{
if (arr[j] == arr[i])
{
Swap(ref arr[j], ref arr[i-1]);
i--;
}
}
if (k == i)
{
Swap(ref arr[i], ref arr[lbound]);
lbound++;
}
else
{
i--;
}
}
return arr;
}
public static void Swap(ref int a, ref int b)
{
int c = a;
a = b;
b = c;
}
public static void Main()
{
int[] arr = {1, 1, 6, 5, 4, 3, 4, 6, 1, 7, 2, 1, 4, 9};
int[] result = DistinctFirst(arr);
foreach (var i in result)
{
Console.WriteLine(i);
}
}
}
輸出:
9
7
2
3
5
4
4
4
6
6
1
1
1
1
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.