如何从C#数组中删除重复项?

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