C# 배열에서 중복 항목을 제거하려면 어떻게 해야 합니까?
저는 A와 함께 일해왔습니다.string[]
함수 호출에서 반환되는 C#의 배열입니다.내가 할 수 있는 일은Generic
수집, 하지만 더 나은 방법이 있는지 궁금했습니다. 아마도 임시 배열을 사용하는 것입니다.
C# 배열에서 중복을 제거하는 가장 좋은 방법은 무엇입니까?
LINQ 쿼리를 사용하여 다음 작업을 수행할 수 있습니다.
int[] s = { 1, 2, 3, 3, 4};
int[] q = s.Distinct().ToArray();
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;
}
HashSet이 해당 버전까지 추가되지 않았기 때문에 이 솔루션에는 .NET 프레임워크 3.5 이상도 필요합니다.배열을 사용할 수도 있습니다.LINQ의 특징인 고유()입니다.
정렬이 필요한 경우 중복 항목도 제거하는 정렬을 구현할 수 있습니다.
그렇다면 일석이조입니다.
다음 테스트 및 작동 코드는 배열에서 중복 항목을 제거합니다.시스템을 포함해야 합니다.컬렉션 네임스페이스입니다.
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));
}
List<String> myStringList = new List<string>(); foreach (string s in myStringArray) { if (!myStringList.Contains(s)) { myStringList.Add(s); } }
이것은 O(n^2)이며, 콤보에 채워질 짧은 목록에는 문제가 되지 않지만, 큰 컬렉션에서는 빠르게 문제가 될 수 있습니다.
매번 묻는 인터뷰 질문입니다.이제 코딩을 해봤습니다.
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();
}
다음은 O(1) 공간을 사용하는 O(n*n) 접근 방식입니다.
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가 없는 등의 제약 조건을 넣기를 원합니다.
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 ");
}
}
사전에 모든 문자열을 추가하고 나중에 Keys 속성을 가져옵니다.이렇게 하면 각 고유 문자열이 생성되지만 원래 입력한 문자열의 순서가 같을 필요는 없습니다.
각 문자열의 첫 번째 발생을 고려할 때 최종 결과의 순서가 원래 입력과 동일해야 하는 경우 대신 다음 알고리즘을 사용합니다.
- 목록(최종 출력)과 사전(중복 확인)이 있어야 합니다.
- 입력의 각 문자열에 대해 사전에 이미 있는지 확인합니다.
- 그렇지 않으면 사전과 목록에 모두 추가합니다.
마지막에 목록에는 각 고유 문자열의 첫 번째 항목이 포함됩니다.
사전을 구성할 때 문화 등을 고려하여 악센트가 있는 문자가 있는 중복을 올바르게 처리하도록 하십시오.
다음 코드는 최적의 솔루션이 아니지만 배열 목록에서 중복 항목을 제거하려고 시도합니다.인터뷰 도중 두 번째/temp 배열 목록을 사용하지 않고 재귀를 통해 중복 항목을 제거하기 위해 다음과 같은 질문을 받았습니다.
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);
}
}
간단한 솔루션:
using System.Linq;
...
public static int[] Distinct(int[] handles)
{
return handles.ToList().Distinct().ToArray();
}
중복 요소를 저장하지 않고 중복 추가 요청을 자동으로 무시하는 해시 집합일 수 있습니다.
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();
}
필요한 일을 할 수도...
에디트 아크!!!1분도 채 안 돼 강도짓으로 얻어맞았습니다!
아래 테스트를 해보았고 작동합니다.멋진 것은 문화에 민감한 검색도 한다는 것입니다.
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--;
}
}
}
일반 확장 메서드:
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;
//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]);
아래는 Java의 간단한 논리로 배열 요소를 두 번 통과하고 동일한 요소가 보이면 0을 할당하고 비교 중인 요소의 인덱스를 건드리지 않습니다.
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;
}
}
}
}
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;
}
가장 좋은 방법은?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;
}
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;
}
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--;
}
}
}
그래서 저는 인터뷰 세션을 하고 있었고 분류하고 구별하기 위해 같은 질문을 받았습니다.
static void Sort()
{
try
{
int[] number = new int[Convert.ToInt32(Console.ReadLine())];
for (int i = 0; i < number.Length; i++)
{
number[i] = Convert.ToInt32(Console.ReadLine());
}
Array.Sort(number);
int[] num = number.Distinct().ToArray();
for (int i = 0; i < num.Length; i++)
{
Console.WriteLine(num[i]);
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
Console.Read();
}
제 경우에는, 여러 가지 물건들을 가지고도 이렇게 작동했습니다.필터로 사용할 속성 선택;
var objectArrayDuplicate = new List<Usuario>();
objectArrayDuplicate.Add(new Usuario { Nome = "Jose", Id = 5 });
objectArrayDuplicate.Add(new Usuario { Nome = "Jose", Id = 5 });
objectArrayDuplicate.Add(new Usuario { Nome = "Maria", Id = 3 });
objectArrayDuplicate.Add(new Usuario { Nome = "Josh", Id = 6 });
List<Usuario> objectArray =
objectArrayDuplicate.GroupBy(o => o.Nome).Select(o => o.First()).ToList();
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;
}
}
}
strINvalues = "1,1,2,2,3,3,4,4";
strINvalues = string.Join(",", strINvalues .Split(',').Distinct().ToArray());
Debug.Writeline(strINvalues);
Kkk 이게 마법인지 그냥 아름다운 코드인지 확실하지 않습니다.
1 strIN 값.분할(',',')구별().대상 배열()
2줄.가입(",", XXX);
1 배열을 분할하고 중복 제거를 위해 고유 [LINQ] 사용 2 중복 없이 다시 결합.
죄송합니다. StackOverFlow의 텍스트는 코드만 읽어본 적이 없습니다.텍스트보다 더 말이 됩니다 ;)
구분 & StringComparer를 사용하여 대/소문자를 구분하지 않고 중복 항목을 제거합니다.불변의 문화 무시 사례
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
아래에서 답을 찾으십시오.
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;
}
}
방금 해결한 테스트를 기반으로 약간의 기여만 하면 다른 주요 기여자들의 도움이 될 수 있고 개선의 여지가 있을 수 있습니다.제가 한 일은 다음과 같습니다.
- 나는 LINQ를 사용하여 가장 작은 항목부터 가장 높은 항목까지 주문하거나 정렬할 수 있는 OrderBy를 사용했습니다.
- 그런 다음 이를 어레이로 다시 변환한 다음 주 데이터 소스에 다시 할당합니다.
- 그래서 저는 배열의 오른쪽에 있는 j를 1로 초기화하고 배열의 왼쪽에 있는 i를 0으로 초기화합니다. 또한 제가 멈출 위치를 0으로 초기화합니다.
- 저는 한 위치에서 다른 위치로 왼쪽에서 오른쪽으로 이동하여 배열 전체를 증가시키기 위해 잠시 루프를 사용했습니다. 각 증가에 대해 정지 위치는 나중에 배열에서 중복 항목을 잘라내는 데 사용할 i + 2의 현재 값입니다.
- 그런 다음 if 문에서 왼쪽에서 오른쪽으로 이동하고 if 문 밖에서 오른쪽으로 이동하여 배열의 전체 값을 반복할 때까지 증가합니다.
- 그런 다음 첫 번째 요소에서 마지막 i 인덱스 + 2가 되는 정지 위치까지 선택합니다. 그러면 int 배열에서 중복된 항목을 모두 제거할 수 있습니다.그런 다음 재할당됩니다.
언급URL : https://stackoverflow.com/questions/9673/how-do-i-remove-duplicates-from-a-c-sharp-array
'prosource' 카테고리의 다른 글
Swift는 설명서 생성을 지원합니까? (0) | 2023.05.28 |
---|---|
Python asyncio와의 동시성을 제한하는 방법은 무엇입니까? (0) | 2023.05.28 |
Node.js + Nginx - 이제 어떻게 됩니까? (0) | 2023.05.28 |
C#에서 VB의 As() 및 Chr() 함수에 해당하는 것은 무엇입니까? (0) | 2023.05.28 |
datetime picker의 기본 형식을 dd-MM-yyyy로 설정합니다. (0) | 2023.05.28 |