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

时间:2008-08-13 11:48:44

标签: c# arrays duplicates

我一直在使用C#中的string[]数组从函数调用返回。我可能会转换为Generic集合,但我想知道是否有更好的方法可以使用临时数组。

从C#数组中删除重复项的最佳方法是什么?

28 个答案:

答案 0 :(得分:398)

您可以使用LINQ查询来执行此操作:

int[] s = { 1, 2, 3, 3, 4};
int[] q = s.Distinct().ToArray();

答案 1 :(得分:52)

以下是HashSet<string>方法:

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或更高版本,因为在该版本之前未添加HashSet。您还可以使用array.Distinct(),这是LINQ的一项功能。

答案 2 :(得分:11)

如果您需要对其进行排序,那么您可以实现一种也可以删除重复项的排序。

然后一石二鸟。

答案 3 :(得分:10)

以下经过测试和运行的代码将删除数组中的重复项。您必须包含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]);
}

如果你愿意,你可以把它包装成一个函数。

答案 4 :(得分:9)

这可能取决于您希望设计解决方案的程度 - 如果阵列永远不会那么大而且您不关心对列表进行排序,您可能需要尝试类似以下内容:

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

答案 5 :(得分:7)

List<String> myStringList = new List<string>();
foreach (string s in myStringArray)
{
    if (!myStringList.Contains(s))
    {
        myStringList.Add(s);
    }
}

这是 O(n ^ 2),这对于将被填充到组合中的短列表无关紧要,但可能很快成为大集合的问题。

答案 6 :(得分:7)

- 每次都会询问面试问题。现在我完成了编码。

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

答案 7 :(得分:6)

这是 O(n * n)方法,使用 O(1)空格。

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

答案 8 :(得分:6)

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

答案 9 :(得分:5)

将所有字符串添加到字典中,然后获取Keys属性。这将产生每个唯一的字符串,但不一定与原始输入所具有的顺序相同。

如果您要求最终结果与原始输入具有相同的顺序,则在考虑每个字符串的第一次出现时,请使用以下算法:

  1. 有一个列表(最终输出)和一个字典(用于检查重复项)
  2. 对于输入中的每个字符串,检查字典中是否已存在
  3. 如果没有,请将其添加到词典和列表中
  4. 最后,列表包含每个唯一字符串的第一次出现。

    确保在构建词典时考虑文化等问题,确保正确处理带有重音字母的重复项。

答案 10 :(得分:5)

以下代码试图从ArrayList中删除重复项,尽管这不是最佳解决方案。我在接受采访时被问到这个问题是为了通过递归来删除重复项,而不使用第二个/ temp 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);
            }
        }

答案 11 :(得分:5)

也许hashset不存储重复元素并静默忽略要添加的请求 重复。

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 + ",");
}

答案 12 :(得分:4)

此代码100%从数组中删除重复值[因为我使用了[i]] .....你可以用任何OO语言转换它.....:)

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

}

答案 13 :(得分:4)

简单的解决方案:

using System.Linq;
...

public static int[] Distinct(int[] handles)
{
    return handles.ToList().Distinct().ToArray();
}

答案 14 :(得分:4)

测试以下&amp;有用。很酷的是,它也会进行文化敏感搜索

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

答案 15 :(得分:4)

注意:未经测试!

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

可能做你需要的......

编辑唉!!!不到一分钟就被抢劫打败了它!

答案 16 :(得分:3)

通用扩展方法:

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

答案 17 :(得分:1)

使用ArrayList时可以使用此代码

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]);

答案 18 :(得分:1)

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

答案 19 :(得分:0)

下面是java中的一个简单逻辑,你遍历数组的元素两次,如果你看到任何相同的元素,你给它分配零加上你不要触摸你正在比较的元素的索引。

<context-param>
    <param-name>net.bootsfaces.get_fontawesome_from_cdn</param-name>
    <param-value>false</param-value>
</context-param>

答案 20 :(得分:0)

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

答案 21 :(得分:0)

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



}

答案 22 :(得分:0)

my_other_layout

Kkk不确定这是巫术还是精美的密码

1 strINvalues .Split(',')。Distinct()。ToArray()

2 字符串。Join(“,”,XXX);

1 拆分数组并使用Distinct [LINQ]删除重复项 2 将其重新加入,而不会重复。

对不起,我从来没有只阅读代码在StackOverFlow上的文字。它比文字更有意义;)

答案 23 :(得分:0)

最好的方法?很难说,HashSet方法看起来很快, 但是(取决于数据)使用排序算法(CountSort吗?) 可以更快。

using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
    static void Main()
    {
        Random r = new Random(0); int[] a, b = new int[1000000];
        for (int i = b.Length - 1; i >= 0; i--) b[i] = r.Next(b.Length);
        a = new int[b.Length]; Array.Copy(b, a, b.Length);
        a = dedup0(a); Console.WriteLine(a.Length);
        a = new int[b.Length]; Array.Copy(b, a, b.Length);
        var w = System.Diagnostics.Stopwatch.StartNew();
        a = dedup0(a); Console.WriteLine(w.Elapsed); Console.Read();
    }

    static int[] dedup0(int[] a)  // 48 ms  
    {
        return new HashSet<int>(a).ToArray();
    }

    static int[] dedup1(int[] a)  // 68 ms
    {
        Array.Sort(a); int i = 0, j = 1, k = a.Length; if (k < 2) return a;
        while (j < k) if (a[i] == a[j]) j++; else a[++i] = a[j++];
        Array.Resize(ref a, i + 1); return a;
    }

    static int[] dedup2(int[] a)  //  8 ms
    {
        var b = new byte[a.Length]; int c = 0;
        for (int i = 0; i < a.Length; i++) 
            if (b[a[i]] == 0) { b[a[i]] = 1; c++; }
        a = new int[c];
        for (int j = 0, i = 0; i < b.Length; i++) if (b[i] > 0) a[j++] = i;
        return a;
    }
}

几乎没有分支。怎么样?调试模式,步入(F11),带有一个小数组:{1,3,1,1,0}

    static int[] dedupf(int[] a)  //  4 ms
    {
        if (a.Length < 2) return a;
        var b = new byte[a.Length]; int c = 0, bi, ai, i, j;
        for (i = 0; i < a.Length; i++)
        { ai = a[i]; bi = 1 ^ b[ai]; b[ai] |= (byte)bi; c += bi; }
        a = new int[c]; i = 0; while (b[i] == 0) i++; a[0] = i++;
        for (j = 0; i < b.Length; i++) a[j += bi = b[i]] += bi * i; return a;
    }

具有两个嵌套循环的解决方案可能需要一些时间, 尤其是对于较大的阵列。

    static int[] dedup(int[] a)
    {
        int i, j, k = a.Length - 1;
        for (i = 0; i < k; i++)
            for (j = i + 1; j <= k; j++) if (a[i] == a[j]) a[j--] = a[k--];
        Array.Resize(ref a, k + 1); return a;
    }

答案 24 :(得分:0)

int size = a.Length;
        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++)
                    {
                        if (k != size - 1)
                        {
                            int temp = a[k];
                            a[k] = a[k + 1];
                            a[k + 1] = temp;

                        }
                    }
                    j--;
                    size--;
                }
            }
        }

答案 25 :(得分:0)

使用Distinct&StringComparer.InvariantCultureIgnoreCase删除重复项并忽略大小写

string[] array = new string[] { "A", "a", "b", "B", "a", "C", "c", "C", "A", "1" };
var r = array.Distinct(StringComparer.InvariantCultureIgnoreCase).ToList();
Console.WriteLine(r.Count); // return 4 items

答案 26 :(得分:0)

在下面找到答案。

class Program
{
    static void Main(string[] args)
    {
        var nums = new int[] { 1, 4, 3, 3, 3, 5, 5, 7, 7, 7, 7, 9, 9, 9 };
        var result = removeDuplicates(nums);
        foreach (var item in result)
        {
            Console.WriteLine(item);
        }
    }
    static int[] removeDuplicates(int[] nums)
    {
        nums = nums.ToList().OrderBy(c => c).ToArray();
        int j = 1;
        int i = 0;
        int stop = 0;
        while (j < nums.Length)
        {
            if (nums[i] != nums[j])
            {
                nums[i + 1] = nums[j];
                stop = i + 2;
                i++;
            }
            j++;
        }
        nums = nums.Take(stop).ToArray();
        return nums;
    }
}

仅基于我刚刚解决的测试就可以做出一点贡献,这可能会有所帮助,并且有待其他杰出贡献者加以改进。 这是我所做的事情:

  1. 我使用了OrderBy,可以使用LINQ从最小到最大对订单进行排序或排序
  2. 然后我将其转换回数组,然后将其重新分配回主数据源
  3. 因此,我然后将数组的右手边的j初始化为1,将数组的左手边的i初始化为0,同时将要停止的地方初始化为0。 li>
  4. 我使用了while循环,从一个位置到另一个位置从左到右递增整个数组,对于每次递增,停止位置都是i + 2的当前值,以后我将用它来截断数组中的重复项数组。
  5. 然后,我在if语句的外部从左向右移动,并从右向右移动,直到遍历数组的整个值为止。
  6. 然后,我从第一个元素开始选择到最后一个i索引加2的停止位置,这样我就可以从int数组中删除所有重复项。然后重新分配。

答案 27 :(得分:0)

假设输入是一串数字 (strInput),并且您希望从中获得一串唯一数字。 输入字符串以逗号分隔。

string strInput = "22125, 25489, 22125, 36975, 25489, 22125, 22125";
string[] strValues = strInput.Split(',', ' ');
List<string> strList = new List<string>();
strList.AddRange(strValues);
strList.Sort();
strList = strList.Where(s => !string.IsNullOrWhiteSpace(s)).Distinct().ToList();
string strJoinUnique = String.Empty;         
strJoinUnique = string.Join(", ", strList);

strJoinUnique 将是按排序顺序的唯一数字的输出字符串。