我一直在处理string[]
从函数调用返回的C#中的数组.我可以投射到一个Generic
集合,但我想知道是否有更好的方法,可能通过使用临时数组.
从C#数组中删除重复项的最佳方法是什么?
您可以使用LINQ查询来执行此操作:
int[] s = { 1, 2, 3, 3, 4}; int[] q = s.Distinct().ToArray();
这是HashSet
public static string[] RemoveDuplicates(string[] s) { HashSetset = new HashSet (s); string[] result = new string[set.Count]; set.CopyTo(result); return result; }
不幸的是,这个解决方案还需要.NET framework 3.5或更高版本,因为在该版本之前不会添加HashSet.您还可以使用array.Distinct(),这是LINQ的一个功能.
如果您需要对其进行排序,那么您可以实现一种也可以删除重复项的排序.
然后用一块石头杀死两只鸟.
以下经过测试和运行的代码将删除数组中的重复项.您必须包含System.Collections命名空间.
string[] sArray = {"a", "b", "b", "c", "c", "d", "e", "f", "f"}; var sList = new ArrayList(); for (int i = 0; i < sArray.Length; i++) { if (sList.Contains(sArray[i]) == false) { sList.Add(sArray[i]); } } var sNew = sList.ToArray(); for (int i = 0; i < sNew.Length; i++) { Console.Write(sNew[i]); }
如果你愿意,你可以把它包装成一个函数.
这可能取决于您希望设计解决方案的程度 - 如果阵列永远不会那么大并且您不关心对列表进行排序,您可能需要尝试类似以下内容:
public string[] RemoveDuplicates(string[] myList) { System.Collections.ArrayList newList = new System.Collections.ArrayList(); foreach (string str in myList) if (!newList.Contains(str)) newList.Add(str); return (string[])newList.ToArray(typeof(string)); }
ListmyStringList = new List (); foreach (string s in myStringArray) { if (!myStringList.Contains(s)) { myStringList.Add(s); } }
这是O(n ^ 2),这对于将被填充到组合中的短列表无关紧要,但可能很快成为大集合上的问题.
- 这是每次询问的面试问题.现在我完成了它的编码.
static void Main(string[] args) { int[] array = new int[] { 4, 8, 4, 1, 1, 4, 8 }; int numDups = 0, prevIndex = 0; for (int i = 0; i < array.Length; i++) { bool foundDup = false; for (int j = 0; j < i; j++) { if (array[i] == array[j]) { foundDup = true; numDups++; // Increment means Count for Duplicate found in array. break; } } if (foundDup == false) { array[prevIndex] = array[i]; prevIndex++; } } // Just Duplicate records replce by zero. for (int k = 1; k <= numDups; k++) { array[array.Length - k] = '\0'; } Console.WriteLine("Console program for Remove duplicates from array."); Console.Read(); }
这是一个使用O(1)空间的O(n*n)方法.
void removeDuplicates(char* strIn) { int numDups = 0, prevIndex = 0; if(NULL != strIn && *strIn != '\0') { int len = strlen(strIn); for(int i = 0; i < len; i++) { bool foundDup = false; for(int j = 0; j < i; j++) { if(strIn[j] == strIn[i]) { foundDup = true; numDups++; break; } } if(foundDup == false) { strIn[prevIndex] = strIn[i]; prevIndex++; } } strIn[len-numDups] = '\0'; } }
上面的hash/linq方法是你在现实生活中通常会使用的方法.然而在采访中他们通常想要设置一些约束,例如常规空间排除哈希或没有内部api - 这排除了使用LINQ.
protected void Page_Load(object sender, EventArgs e) { string a = "a;b;c;d;e;v"; string[] b = a.Split(';'); string[] c = b.Distinct().ToArray(); if (b.Length != c.Length) { for (int i = 0; i < b.Length; i++) { try { if (b[i].ToString() != c[i].ToString()) { Response.Write("Found duplicate " + b[i].ToString()); return; } } catch (Exception ex) { Response.Write("Found duplicate " + b[i].ToString()); return; } } } else { Response.Write("No duplicate "); } }
将所有字符串添加到字典中,然后获取Keys属性.这将生成每个唯一的字符串,但不一定与原始输入所具有的顺序相同.
如果您要求最终结果与原始输入具有相同的顺序,则在考虑每个字符串的第一次出现时,请使用以下算法:
有一个列表(最终输出)和一个字典(检查重复)
对于输入中的每个字符串,检查它是否已存在于字典中
如果没有,请将其添加到字典和列表中
最后,列表包含每个唯一字符串的第一次出现.
确保在构建字典时考虑文化之类的东西,以确保正确处理带有重音字母的重复项.
下面的代码试图从ArrayList中删除重复项,尽管这不是最佳解决方案.我在接受采访时被问到这个问题,通过递归删除重复项,而不使用第二个/临时arraylist:
private void RemoveDuplicate() { ArrayList dataArray = new ArrayList(5); dataArray.Add("1"); dataArray.Add("1"); dataArray.Add("6"); dataArray.Add("6"); dataArray.Add("6"); dataArray.Add("3"); dataArray.Add("6"); dataArray.Add("4"); dataArray.Add("5"); dataArray.Add("4"); dataArray.Add("1"); dataArray.Sort(); GetDistinctArrayList(dataArray, 0); } private void GetDistinctArrayList(ArrayList arr, int idx) { int count = 0; if (idx >= arr.Count) return; string val = arr[idx].ToString(); foreach (String s in arr) { if (s.Equals(arr[idx])) { count++; } } if (count > 1) { arr.Remove(val); GetDistinctArrayList(arr, idx); } else { idx += 1; GetDistinctArrayList(arr, idx); } }
也许hashset不存储重复元素,并默默地忽略添加重复项的请求.
static void Main() { string textWithDuplicates = "aaabbcccggg"; Console.WriteLine(textWithDuplicates.Count()); var letters = new HashSet(textWithDuplicates); Console.WriteLine(letters.Count()); foreach (char c in letters) Console.Write(c); Console.WriteLine(""); int[] array = new int[] { 12, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2 }; Console.WriteLine(array.Count()); var distinctArray = new HashSet (array); Console.WriteLine(distinctArray.Count()); foreach (int i in distinctArray) Console.Write(i + ","); }
简单的解决方案:
using System.Linq; ... public static int[] Distinct(int[] handles) { return handles.ToList().Distinct().ToArray(); }