Как удалить дубликаты из массива C#?
Я работал с A string[] массив в C#, который возвращается из вызова функции. Я мог бы бросить в Generic коллекция, но мне было интересно, есть ли лучший способ сделать это, возможно, с помощью временного массива.
каков наилучший способ удаления дубликатов из массива C#?
20 ответов:
вы могли бы использовать запрос 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.
Если вам нужно было отсортировать его, то вы можете реализовать сортировку, которая также удаляет дубликаты.
убивает двух зайцев одним выстрелом.
Это может зависеть от того, насколько вы хотите спроектировать решение - если массив никогда не будет таким большим, и вы не заботитесь о сортировке списка, вы можете попробовать что-то похожее на следующее:
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)); }
следующий проверенный и рабочий код удалит дубликаты из массива. Вы должны включить систему.Пространство имен коллекций.
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]); }вы можете обернуть это в функцию, если хотите.
- Это Вопросы спрашивает каждый раз. Теперь я сделал его кодирование.
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] = ''; } Console.WriteLine("Console program for Remove duplicates from array."); Console.Read(); }
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 "); } }
List<String> myStringList = new List<string>(); foreach (string s in myStringArray) { if (!myStringList.Contains(s)) { myStringList.Add(s); } }Это O (n^2), что не будет иметь значения для короткого списка, который будет набит в комбо, но может быть быстро проблемой в большой коллекции.
добавьте все строки в словарь и получите свойство Keys после этого. Это приведет к каждой уникальной строки, но не обязательно в том же порядке, введенному в.
Если требуется, чтобы конечный результат имел тот же порядок, что и исходный ввод, при рассмотрении первого появления каждой строки используйте вместо этого следующий алгоритм:
- есть список (окончательный вывод) и словарь (для проверки дубликатов)
- для каждого строка во входных данных, проверьте, существует ли она в словаре уже
- если нет, добавьте его как в словарь, так и в список
в конце списка содержится первое появление каждой уникальной строки.
убедитесь, что вы учитываете такие вещи, как культура и т. д. При создании своего словаря, чтобы убедиться, что вы правильно обрабатываете дубликаты с акцентированными буквами.
следующий фрагмент кода пытается удалить дубликаты из 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); } }
может быть, 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 + ","); }
здесь O (n*n) подход, который использует O (1) пространство.
void removeDuplicates(char* strIn) { int numDups = 0, prevIndex = 0; if(NULL != strIn && *strIn != '') { 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] = ''; } }на hash / linq подходы выше-это то, что вы обычно используете в реальной жизни. Однако в интервью они обычно хотят поставить некоторые ограничения, например, постоянное пространство, которое исключает хэш или нет внутреннего api - что исключает использование LINQ.
примечание: не проверено!
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(); }может делать то, что вам нужно...
EDIT Argh!!! избитый до этого Робом менее чем за минуту!
протестировано ниже , и это работает. Что здорово, что он делает чувствительный к культуре поиск тоже
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..... :)
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(); }
вы можете использовать этот код при работе с 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; }
Comments