Вопрос

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

Как лучше всего удалить дубликаты из массива С#?

Это было полезно?

Решение

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

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

Другие советы

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

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

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();
        }
List<String> myStringList = new List<string>();
foreach (string s in myStringArray)
{
    if (!myStringList.Contains(s))
    {
        myStringList.Add(s);
    }
}

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

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

Вот О(п*п) подход, который использует О(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';
    }
}

А хэш/linq Подходы, описанные выше, — это то, что вы обычно используете в реальной жизни.Однако на собеседованиях они обычно хотят поставить некоторые ограничения, например:постоянное пространство, которое исключает хэш или отсутствие внутреннего API - что исключает использование ЛИНК.

Добавьте все строки в словарь и впоследствии получите свойство Keys.Это создаст каждую уникальную строку, но не обязательно в том же порядке, в котором они были в исходном вводе.

Если вам требуется, чтобы конечный результат имел тот же порядок, что и исходные входные данные, при рассмотрении первого появления каждой строки используйте вместо этого следующий алгоритм:

  1. Иметь список (окончательный результат) и словарь (для проверки дубликатов)
  2. Для каждой строки во входных данных проверьте, существует ли она уже в словаре.
  3. Если нет, добавьте его и в словарь, и в список.

В конце список содержит первое появление каждой уникальной строки.

При создании словаря обязательно учитывайте такие вещи, как культура и тому подобное, чтобы правильно обрабатывать дубликаты с акцентированными буквами.

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

Может быть, хэшсет, который не хранит дублирующиеся элементы и молча игнорирует запросы на добавление дубликатов.

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

ПРИМЕЧАНИЕ :Не испытано!

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

Может, сделаю то, что тебе нужно...

РЕДАКТИРОВАТЬ Ааа!!!опередил Роба менее чем на минуту!

Протестировано ниже, и это работает.Что круто, так это то, что он также выполняет поиск с учетом культурных особенностей.

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

}

--АптСенСДЕТ

Этот код на 100% удаляет повторяющиеся значения из массива [поскольку я использовал [i]]..... Вы можете преобразовать его в любой объектно-ориентированный язык.....:)

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

}

Простое решение:

using System.Linq;
...

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

Общий метод расширения:

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

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

Ниже приведена простая логика в Java: вы дважды проходите по элементам массива, и если вы видите какой-либо один и тот же элемент, вы присваиваете ему ноль и не трогаете индекс сравниваемого элемента.

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



}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top