How do I remove duplicates from a C# array?
我一直在使用C中的string[]数组,该数组从函数调用返回。我可以将其强制转换为一个Generic集合,但我想知道是否有更好的方法,可能是使用一个temp数组。 从C数组中删除重复项的最佳方法是什么?
您可以使用LINQ查询来执行此操作:
1 2
| int[] s = { 1, 2, 3, 3, 4};
int[] q = s.Distinct().ToArray(); |
以下是hashset方法:
1 2 3 4 5 6 7
| public static string[] RemoveDuplicates(string[] s)
{
HashSet<string> set = new HashSet<string>(s);
string[] result = new string[set.Count];
set.CopyTo(result);
return result;
} |
不幸的是,此解决方案还需要.NET Framework 3.5或更高版本,因为在该版本之前未添加哈希集。您还可以使用array.distinct(),这是linq的一个特性。
如果需要对其进行排序,那么可以实现一个同时删除重复项的排序。 那就一石二鸟吧。
以下测试和工作代码将从数组中删除重复项。必须包含System.Collections命名空间。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 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]);
} |
如果您愿意的话,可以将它包装成一个函数。
这可能取决于您对解决方案的设计程度-如果数组永远不会这么大,并且您不关心对列表进行排序,那么您可能需要尝试类似于以下内容的操作:
1 2 3 4 5 6 7 8
| 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));
} |
1 2 3 4 5 6 7 8
| List<String> myStringList = new List<string>();
foreach (string s in myStringArray)
{
if (!myStringList.Contains(s))
{
myStringList.Add(s);
}
} |
这是O(n^2),对于一个将被填充到组合中的短列表来说并不重要,但对于一个大集合来说,这可能很快就会成为一个问题。
--这是每次都要问的面试问题。现在我完成了编码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| 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();
} |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| 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");
}
} |
这里有一个使用O(1)空间的O(n*n)方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| 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。
将所有字符串添加到字典中,然后获取keys属性。这将生成每个唯一的字符串,但不一定按照原始输入的顺序来生成。 如果需要最终结果与原始输入具有相同的顺序,则在考虑每个字符串的第一次出现时,请改用以下算法:
有一个列表(最终输出)和一个字典(检查重复项)
对于输入中的每个字符串,检查字典中是否已存在该字符串。
如果没有,请将其同时添加到字典和列表中
最后,列表包含每个唯一字符串的第一次出现。 在构建字典时,请确保考虑到文化等因素,以确保正确处理带有重音字母的重复项。
可能是哈希集,它不存储重复的元素,并且静默地忽略要添加的请求复制品。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| static void Main()
{
string textWithDuplicates ="aaabbcccggg";
Console.WriteLine(textWithDuplicates.Count());
var letters = new HashSet<char>(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<int>(array);
Console.WriteLine(distinctArray.Count());
foreach (int i in distinctArray) Console.Write(i +",");
} |
下面的代码尝试从数组列表中删除重复项,尽管这不是最佳解决方案。在一次访问中,我被问到这个问题,通过递归删除重复项,而不使用第二个/temp数组列表:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| 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);
}
} |
测试了下面的功能。很酷的是,它也会进行文化敏感的搜索
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| class RemoveDuplicatesInString
{
public static String RemoveDups(String origString)
{
String outString = null;
int readIndex = 0;
CompareInfo ci = CultureInfo.CurrentCulture.CompareInfo;
if(String.IsNullOrEmpty(origString))
{
return outString;
}
foreach (var ch in origString)
{
if (readIndex == 0)
{
outString = String.Concat(ch);
readIndex++;
continue;
}
if (ci.IndexOf(origString, ch.ToString().ToLower(), 0, readIndex) == -1)
{
//Unique char as this char wasn't found earlier.
outString = String.Concat(outString, ch);
}
readIndex++;
}
return outString;
}
static void Main(string[] args)
{
String inputString ="aAbcefc";
String outputString;
outputString = RemoveDups(inputString);
Console.WriteLine(outputString);
} |
} ——AptSenSDET
此代码100%从数组中删除重复值[正如我使用的[I]一样]…。您可以用任何OO语言转换它…..:)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| for(int i=0;i<size;i++)
{
for(int j=i+1;j<size;j++)
{
if(a[i] == a[j])
{
for(int k=j;k<size;k++)
{
a[k]=a[k+1];
}
j--;
size--;
}
}
} |
简单解决方案:
1 2 3 4 5 6 7
| using System.Linq;
...
public static int[] Distinct(int[] handles)
{
return handles.ToList().Distinct().ToArray();
} |
注:未测试!
1 2 3 4 5 6 7 8 9 10 11 12
| string[] test(string[] myStringArray)
{
List<String> myStringList = new List<string>();
foreach (string s in myStringArray)
{
if (!myStringList.Contains(s))
{
myStringList.Add(s);
}
}
return myStringList.ToString();
} |
可能会做你需要的… 编辑啊!!!!被罗布打败不到一分钟!
通用扩展方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public static IEnumerable<TSource> Distinct<TSource>(this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
HashSet<TSource> set = new HashSet<TSource>(comparer);
foreach (TSource item in source)
{
if (set.Add(item))
{
yield return item;
}
}
} |
使用ArrayList时可以使用此代码
1 2 3 4 5 6 7 8 9 10 11 12
| ArrayList arrayList;
//Add some Members :)
arrayList.Add("ali");
arrayList.Add("hadi");
arrayList.Add("ali");
//Remove duplicates from array
for (int i = 0; i < arrayList.Count; i++)
{
for (int j = i + 1; j < arrayList.Count ; j++)
if (arrayList[i].ToString() == arrayList[j].ToString())
arrayList.Remove(arrayList[j]); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public static int RemoveDuplicates(ref int[] array)
{
int size = array.Length;
// if 0 or 1, return 0 or 1:
if (size < 2) {
return size;
}
int current = 0;
for (int candidate = 1; candidate < size; ++candidate) {
if (array[current] != array[candidate]) {
array[++current] = array[candidate];
}
}
// index to count conversion:
return ++current;
} |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| using System;
using System.Collections.Generic;
using System.Linq;
namespace Rextester
{
public class Program
{
public static void Main(string[] args)
{
List<int> listofint1 = new List<int> { 4, 8, 4, 1, 1, 4, 8 };
List<int> updatedlist= removeduplicate(listofint1);
foreach(int num in updatedlist)
Console.WriteLine(num);
}
public static List<int> removeduplicate(List<int> listofint)
{
List<int> listofintwithoutduplicate= new List<int>();
foreach(var num in listofint)
{
if(!listofintwithoutduplicate.Any(p=>p==num))
{
listofintwithoutduplicate.Add(num);
}
}
return listofintwithoutduplicate;
}
}
} |
下面是Java中的一个简单的逻辑,你遍历数组元素两次,如果你看到任何相同的元素,你给它分配零,再加上你不接触你正在比较的元素的索引。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import java.util.*;
class removeDuplicate{
int [] y ;
public removeDuplicate(int[] array){
y=array;
for(int b=0;b<y.length;b++){
int temp = y[b];
for(int v=0;v<y.length;v++){
if( b!=v && temp==y[v]){
y[v]=0;
}
}
}
} |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| private static string[] distinct(string[] inputArray)
{
bool alreadyExists;
string[] outputArray = new string[] {};
for (int i = 0; i < inputArray.Length; i++)
{
alreadyExists = false;
for (int j = 0; j < outputArray.Length; j++)
{
if (inputArray[i] == outputArray[j])
alreadyExists = true;
}
if (alreadyExists==false)
{
Array.Resize<string>(ref outputArray, outputArray.Length + 1);
outputArray[outputArray.Length-1] = inputArray[i];
}
}
return outputArray;
} |
|