Как удалить дубликаты из массива C #? - PullRequest
193 голосов
/ 13 августа 2008

Я работал с массивом string[] в C #, который возвращается из вызова функции. Я мог бы привести к Generic коллекции, но мне было интересно, есть ли лучший способ сделать это, возможно, с использованием временного массива.

Каков наилучший способ удаления дубликатов из массива C #?

Ответы [ 22 ]

398 голосов
/ 13 августа 2008

Вы можете использовать запрос LINQ для этого:

int[] s = { 1, 2, 3, 3, 4};
int[] q = s.Distinct().ToArray();
52 голосов
/ 13 августа 2008

Вот подход HashSet :

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.

11 голосов
/ 13 августа 2008

Если вам нужно было отсортировать его, вы можете реализовать сортировку, которая также удаляет дубликаты.

Убивает двух зайцев одним выстрелом.

10 голосов
/ 13 августа 2008

Следующий проверенный и работающий код удалит дубликаты из массива. Вы должны включить пространство имен 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]);
}

Вы можете обернуть это в функцию, если хотите.

9 голосов
/ 13 августа 2008

Это может зависеть от того, насколько вы хотите разработать решение - если массив никогда не будет таким большим и вам не нужно сортировать список, вы можете попробовать что-то похожее на следующее:

    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));
    }
7 голосов
/ 13 августа 2008
List<String> myStringList = new List<string>();
foreach (string s in myStringArray)
{
    if (!myStringList.Contains(s))
    {
        myStringList.Add(s);
    }
}

Это O (n ^ 2) , что не имеет значения для короткого списка, который будет вставлен в комбо, но может быстро стать проблемой для большой коллекции.

7 голосов
/ 03 июля 2013

- Это Вопрос об интервью , задаваемый каждый раз. Теперь я сделал его кодирование.

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();
        }
6 голосов
/ 14 февраля 2012
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 ");
    }
}
6 голосов
/ 06 декабря 2009

Вот подход 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 .

5 голосов
/ 15 апреля 2010

Следующий фрагмент кода пытается удалить дубликаты из 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);
            }
        }
...