如何高效地找出給定數組中重復元素的個數?
using System; using System.Collections.Generic; using System.Diagnostics; using System.Threading.Tasks; public class Test { //找出數組中不重復的元素的個數 private static void Main(string[] args) { //構造一個包含大量重復元素的數組 int Count = 100000; string[] arr = new string[Count]; for (int i = 0; i < Count; i++) { arr[i] = Convert.ToString((i % Count) * (new Random().Next(0, 100)) % Count); } //采用不同的算法 ArrQuery arrObj; //記錄執行時間(開始) //DateTime dtBegin = DateTime.Now; Stopwatch monitor = Stopwatch.StartNew(); //方法一 arrObj = new HashQuery(arr); Task t1 = new Task(arrObj.Query); t1.Start(); //等待任務結束 t1.Wait(); //不能用此方法(因為無法確定線程是否執行完畢,無法統計執行時間) //Thread th1 = new Thread(new ThreadStart(md1.HashQuery)); //th1.Start(); //記錄執行時間(結束) //DateTime dtEnd = DateTime.Now; //TimeSpan ts = dtEnd.Subtract(dtBegin); monitor.Stop(); Console.WriteLine("哈希查找:不重復的元素有:{0} 個,用時:{1} 秒", arrObj.total, monitor.Elapsed.TotalSeconds); //記錄執行時間(開始) monitor = Stopwatch.StartNew(); //方法二 arrObj = new NormalQuery(arr); Task t2 = new Task(arrObj.Query); t2.Start(); //等待任務結束 t2.Wait(); //記錄執行時間(結束) monitor.Stop(); Console.WriteLine("普通查找:不重復的元素有:{0} 個,用時:{1} 秒", arrObj.total, monitor.Elapsed.TotalSeconds); Console.WriteLine("請按任意鍵退出..."); Console.ReadKey(); } } /// <summary> /// 找出數組中的相同元素 /// </summary> public abstract class ArrQuery { public ArrQuery() { } public ArrQuery(string[] arr) { this.arr = arr; } /// <summary> /// 原始數組 /// </summary> public string[] arr { get; set; } /// <summary> /// 存儲不重復的元素個數 /// </summary> public int total { get; set; } /// <summary> /// 查找方法 /// </summary> public abstract void Query(); } /// <summary> /// 1. 哈希查找 /// </summary> public class HashQuery : ArrQuery { public HashQuery(string[] arr) : base(arr) { } public override void Query() { //使用C#中的HashSet對象 HashSet<string> hash = new HashSet<string>(); //利用HashSet不包含重復項,也不會自動排序的特點 Array.ForEach(this.arr, t => hash.Add(t)); //hash.UnionWith(arr); //IEnumerable<string> ie = hash.Union(arr); //計算集合中不重復的元素總數 this.total = hash.Count; } } /// <summary> /// 2. 普通查找 /// </summary> public class NormalQuery : ArrQuery { public NormalQuery(string[] arr) : base(arr) { } public override void Query() { int len = this.arr.Length; //新定義一個臨時數組,用來標記重復項 int[] temp = new int[len]; //初始化臨時數組中的元素 for (int i = 0; i < len; i++) { temp[i] = 0; } //查找重復項 for (int i = 0; i < len; i++) { //檢查temp[i]沒有被標記,才繼續查找 if (temp[i] != -1) { for (int j = i + 1; j < len; j++) { if (temp[j] != -1) { if (this.arr[i] == this.arr[j]) { temp[j] = -1; //輸出部分值,用於觀察 //if (j > 100000 && j < 150009) // Console.WriteLine("arr[" + i + "]=" + arr[i] + // ", arr[" + j + "]=" + arr[j]); } } } } } int myCount = 0; //計算數組中不重復的元素總數 for (int i = 0; i < temp.Length; i++) { if (temp[i] != -1) myCount++; } this.total = myCount; } }
運行結果如下:

