ฉันทำงานกับstring[]
อาร์เรย์ใน C # ที่ได้รับคืนจากการเรียกใช้ฟังก์ชัน ฉันอาจจะโยนไปที่Generic
คอลเลกชัน แต่ฉันสงสัยว่ามีวิธีที่ดีกว่าที่จะทำมันอาจจะโดยการใช้อาร์เรย์ชั่วคราว
วิธีที่ดีที่สุดในการลบรายการที่ซ้ำกันออกจากอาร์เรย์ C # คืออะไร
ฉันทำงานกับstring[]
อาร์เรย์ใน C # ที่ได้รับคืนจากการเรียกใช้ฟังก์ชัน ฉันอาจจะโยนไปที่Generic
คอลเลกชัน แต่ฉันสงสัยว่ามีวิธีที่ดีกว่าที่จะทำมันอาจจะโดยการใช้อาร์เรย์ชั่วคราว
วิธีที่ดีที่สุดในการลบรายการที่ซ้ำกันออกจากอาร์เรย์ C # คืออะไร
คำตอบ:
คุณอาจใช้การสืบค้น LINQ เพื่อทำสิ่งนี้:
int[] s = { 1, 2, 3, 3, 4};
int[] q = s.Distinct().ToArray();
.Distinct(StringComparer.OrdinalIgnoreCase)
เพื่อรับชุดสตริงที่แตกต่างกัน
The Distinct() method returns an unordered sequence that contains no duplicate values.
นี่คือ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
รหัสที่ทดสอบและใช้งานได้ดังต่อไปนี้จะลบรายการที่ซ้ำกันออกจากอาร์เรย์ คุณต้องรวม System.Collections namespace
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); } }
นี่คือO (n ^ 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 ");
}
}
นี่คือ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';
}
}
วิธีการแฮช / ลินุกข้างต้นเป็นสิ่งที่คุณมักจะใช้ในชีวิตจริง อย่างไรก็ตามในการสัมภาษณ์พวกเขามักจะต้องการที่จะนำพื้นที่อย่างต่อเนื่องเช่นข้อ จำกัด บางอย่างที่ออกกฎกัญชาหรือไม่ภายในAPI - ซึ่งออกกฎการใช้LINQ
strIn[j] == strIn[i]
) จะเปรียบเทียบสตริงกับตัวเองยกเว้นคิดด้วยคำสั่ง if
เพิ่มสตริงทั้งหมดลงในพจนานุกรมและรับคุณสมบัติ Keys หลังจากนั้น สิ่งนี้จะสร้างสตริงที่ไม่ซ้ำกัน แต่ไม่จำเป็นต้องอยู่ในลำดับเดียวกันกับอินพุตต้นฉบับของคุณ
หากคุณต้องการให้ผลลัพธ์สุดท้ายมีลำดับเดียวกันกับอินพุตต้นฉบับเมื่อคุณพิจารณาการเกิดครั้งแรกของแต่ละสตริงให้ใช้อัลกอริทึมต่อไปนี้แทน:
ในตอนท้ายรายการจะมีการเกิดขึ้นครั้งแรกของแต่ละสตริงที่ไม่ซ้ำกัน
ตรวจสอบให้แน่ใจว่าคุณพิจารณาสิ่งต่าง ๆ เช่นวัฒนธรรมและเมื่อสร้างพจนานุกรมเพื่อให้แน่ใจว่าคุณจัดการรายการที่ซ้ำกันด้วยตัวอักษรที่เน้นเสียงอย่างถูกต้อง
ชิ้นส่วนของรหัสต่อไปนี้พยายามที่จะลบรายการที่ซ้ำกันออกจาก ArrayList แม้ว่านี่จะไม่ใช่ทางออกที่ดีที่สุด ฉันถูกถามคำถามนี้ในระหว่างการสัมภาษณ์เพื่อลบรายการที่ซ้ำกันผ่านการเรียกซ้ำและไม่ใช้ 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);
}
}
วิธีแก้ปัญหาง่าย ๆ :
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();
}
อาจทำสิ่งที่คุณต้องการ ...
แก้ไข 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--;
}
}
}
วิธีการขยายทั่วไป:
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;
}
}
}
strINvalues = "1,1,2,2,3,3,4,4";
strINvalues = string.Join(",", strINvalues .Split(',').Distinct().ToArray());
Debug.Writeline(strINvalues);
Kkk ไม่แน่ใจว่านี่เป็นคาถาหรือรหัสที่สวยงาม
1 strINvalues .Split (','). Distinct (). ToArray ()
2 string.Join (",", XXX);
1แบ่งอาร์เรย์และใช้ Distinct [LINQ] เพื่อลบรายการที่ซ้ำกัน 2เข้าร่วมได้โดยไม่ทำซ้ำ
ขออภัยฉันไม่เคยอ่านข้อความใน StackOverFlow เพียงแค่รหัส มันสมเหตุสมผลมากกว่าข้อความ;)
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--;
}
}
}
วิธีที่ดีที่สุด ยากที่จะบอกว่าวิธี 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;
}