मैं C # सरणी से डुप्लिकेट कैसे निकालूं?


209

मैं एक के साथ काम कर रहा हूँ string[] सी # में सरणी के एक फ़ंक्शन कॉल से वापस आती है। मैं संभवतः एक Genericसंग्रह में जा सकता था, लेकिन मैं सोच रहा था कि क्या ऐसा करने का एक बेहतर तरीका था, संभवतः एक अस्थायी सरणी का उपयोग करके।

C # सरणी से डुप्लिकेट को निकालने का सबसे अच्छा तरीका क्या है?


4
डिस्टिक्ट एक्सटेंशन विधि का उपयोग करें।
कोकोज

वास्तव में। यह अधिक मजेदार है जब सरणी पहले से ही सॉर्ट की जाती है - उस स्थिति में इसे O (n) समय में इन-प्लेस किया जा सकता है।
डेविड एरापिएटन

@ विटिम.स नोप। मेरे मामले में, यह एक सरणी भी नहीं है, लेकिन सूची <string> है। मैं किसी भी उत्तर को स्वीकार करता हूं जो काम करता है। शायद, यह कागज पर ऐसा करने का एक झटका है।
एंग्रीहैकर

जवाबों:


427

आप संभवतः ऐसा करने के लिए LINQ क्वेरी का उपयोग कर सकते हैं:

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

22
ध्यान दें कि आप एक IEqualityComparer पैरामीटर के रूप में उपयोग कर सकते हैं, जैसे कि .Distinct(StringComparer.OrdinalIgnoreCase)केस-असंवेदनशील अलग-अलग स्ट्रिंग्स प्राप्त करने के लिए।
justisb

क्या विकृत सम्मान तत्वों का मूल क्रम है?
asyrov

@ नास्ट्रोव: एमएसडीएन से:The Distinct() method returns an unordered sequence that contains no duplicate values.
टिग्रो

52

यहाँ हैशसेट <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;
}

दुर्भाग्य से इस समाधान के लिए .NET फ्रेमवर्क 3.5 या बाद के संस्करण की भी आवश्यकता होती है क्योंकि उस संस्करण तक हाशस को नहीं जोड़ा गया था। आप array.Distinct () का भी उपयोग कर सकते हैं , जो LINQ की एक विशेषता है।


11
यह शायद मूल आदेश को संरक्षित नहीं करेगा।
हामिश ग्रुबीजान

11

निम्नलिखित परीक्षण और कार्य कोड एक सरणी से डुप्लिकेट को निकाल देंगे। आपको 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]);
}

यदि आप चाहते हैं तो आप इसे एक फ़ंक्शन में लपेट सकते हैं।


यह O (N ^ 2) प्रतीत होता है ... आप एक ArrayList के बजाय एक ढेर का उपयोग कर सकते हैं
नील चौधरी

10

यदि आपको इसे क्रमबद्ध करने की आवश्यकता है, तो आप एक ऐसे प्रकार को लागू कर सकते हैं जो डुप्लिकेट को भी हटाता है।

एक पत्थर से दो पक्षियों को मारता है, फिर।


7
डुप्लिकेट कैसे हटाता है?
डैन १

2
इसे किसने वोट दिया? यह कोई जवाब नहीं है। "मैं पेनकेक्स कैसे बनाऊं?" "एक धनुष और मिश्रण में कुछ सामग्री डालें।"
क्वार्कली

9

यह इस बात पर निर्भर हो सकता है कि आप समाधान को कितना इंजीनियर करना चाहते हैं - यदि सरणी कभी भी इतनी बड़ी नहीं होगी और आप सूची को क्रमबद्ध करने के बारे में परवाह नहीं करते हैं, तो आप निम्नलिखित के समान कुछ करने की कोशिश कर सकते हैं:

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

4
आपको ArrayList के बजाय List का उपयोग करना चाहिए।
डग एस

7

- यह इंटरव्यू प्रश्न है जो हर बार पूछा जाता है। अब मैंने इसकी कोडिंग की।

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

3
आपको इस प्रश्न के लिए O (n * 2) समय जटिलता नहीं करनी चाहिए।
डैन १


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

यह O (n ^ 2) है , जो एक छोटी सूची के लिए मायने नहीं रखेगा जो कॉम्बो में भर जाने वाली है, लेकिन तेजी से एक बड़े संग्रह पर एक समस्या हो सकती है।


6
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

यहाँ एक 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';
    }
}

हैश / LINQ ऊपर दृष्टिकोण क्या आप आम तौर पर वास्तविक जीवन में प्रयोग करेंगे रहे हैं। हालांकि साक्षात्कार में वे आम तौर पर कुछ कमी जैसे निरंतर अंतरिक्ष में जो हैश या कोई आंतरिक बाहर नियम रखना चाहते हैं एपीआई जो का उपयोग कर बाहर नियम - LINQ


1
जब आप पूरी सूची को स्टोर करना चाहते हैं, तो यह ओ (1) स्थान का उपयोग कैसे कर सकता है? एक inplace तरह से शुरू करके, आप O (nlogn) समय और O (n) मेमोरी, बहुत कम कोड के साथ कर सकते हैं।
थॉमस अहले

1
आपको क्या लगता है कि यह पूरी सूची को संग्रहीत कर रहा है? यह वास्तव में इन-प्लेस कर रहा है। और हालांकि प्रश्न में कोई शर्त नहीं है, मेरा कोड मूल स्ट्रिंग में वर्णों के क्रम को बनाए रखता है। छँटाई वह निकाल देंगे।
शेष

1
आंतरिक लूप ( strIn[j] == strIn[i]) की तुलना एक स्ट्रिंग से खुद से की जाएगी जब तक कि यदि वह एक कथन के साथ हिसाब न करे।
उपयोगकर्ता 3219

5

सभी स्ट्रिंग्स को डिक्शनरी में जोड़ें और बाद में कीज़ प्रॉपर्टी प्राप्त करें। यह प्रत्येक अद्वितीय स्ट्रिंग का उत्पादन करेगा, लेकिन जरूरी नहीं कि उसी क्रम में आपके मूल इनपुट में उन्हें था।

यदि आपको मूल इनपुट के समान ऑर्डर करने के लिए अंतिम परिणाम की आवश्यकता होती है, जब आप प्रत्येक स्ट्रिंग की पहली संभावना पर विचार करते हैं, तो निम्न एल्गोरिथ्म का उपयोग करें:

  1. एक सूची (अंतिम आउटपुट) और एक शब्दकोश (डुप्लिकेट के लिए जांच करने के लिए) है
  2. इनपुट में प्रत्येक स्ट्रिंग के लिए, जांचें कि क्या यह पहले से ही शब्दकोश में मौजूद है
  3. यदि नहीं, तो इसे शब्दकोश और सूची में जोड़ें

अंत में, सूची में प्रत्येक अद्वितीय स्ट्रिंग का पहला रोड़ा है।

सुनिश्चित करें कि आप संस्कृति जैसी चीजों पर विचार करें और जैसे कि अपना शब्दकोश बनाते समय, यह सुनिश्चित करने के लिए कि आप उच्चारण अक्षरों के साथ डुप्लिकेट को सही ढंग से संभालते हैं।


5

कोड का निम्नलिखित टुकड़ा एक 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);
            }
        }


5

शायद हैशसेट जो डुप्लिकेट तत्वों को संग्रहीत नहीं करता है और डुप्लिकेट को जोड़ने के अनुरोधों को चुपचाप अनदेखा करता है।

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

4

नोट: परीक्षण नहीं किया गया!

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

हो सकता है कि आपको क्या चाहिए ...

संपादित करें !!! यह एक मिनट के नीचे से लूटने के लिए पीटा!


रोब ने आपको कुछ भी नहीं हराया। वह ArrayList का उपयोग कर रहा है, जबकि आप सूची का उपयोग कर रहे हैं। आपका संस्करण बेहतर है।
डग एस

4

नीचे परीक्षण किया गया और यह काम करता है। क्या अच्छा है कि यह एक संस्कृति संवेदनशील खोज भी करता है

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


4

यह कोड 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--;
        }
    }

}

4

सामान्य विस्तार विधि:

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

1

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

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

0

नीचे 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;
            }
        }
    }
}

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

1
कृपया अपना उत्तर स्पष्ट करें।
बादीपर्मगी

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



}

यह ऐसा करने का एक बहुत ही अक्षम तरीका है। अन्य उत्तरों पर एक नज़र डालें कि वे क्या करते हैं।
वाई हा ली

0
strINvalues = "1,1,2,2,3,3,4,4";
strINvalues = string.Join(",", strINvalues .Split(',').Distinct().ToArray());
Debug.Writeline(strINvalues);

Kkk यकीन नहीं अगर यह जादू टोना या सिर्फ सुंदर कोड है

1 स्ट्रिनवल्यूज .Split (',') 'Distinct' ()। ToArray ()

2 स्ट्रिंग। जॉइन (",", एक्सएक्सएक्स);

1 ऐरे को विभाजित करना और डुप्लिकेट को हटाने के लिए डिस्टिंच [लिंकन] का उपयोग करना 2 डुप्लिकेट के बिना इसे वापस जोड़ना।

क्षमा करें, मैंने कभी भी StackOverFlow के कोड को पाठ नहीं पढ़ा। यह पाठ की तुलना में अधिक समझ में आता है;)


कोड-केवल उत्तर निम्न-गुणवत्ता वाले उत्तर हैं। कुछ स्पष्टीकरण जोड़ें कि यह क्यों काम करता है।
तस्लीम ओसेनी

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

1
एसओ में आपका स्वागत है। हालांकि यह कोड स्निपेट समाधान हो सकता है, जिसमें स्पष्टीकरण भी शामिल है, जो आपके पोस्ट की गुणवत्ता को बेहतर बनाने में मदद करता है। याद रखें कि आप भविष्य में पाठकों के लिए प्रश्न का उत्तर दे रहे हैं, और उन लोगों को आपके कोड सुझाव के कारणों का पता नहीं चल सकता है।
alan.elkin

अफसोस कि यह कोड कुछ भी नहीं हटाता है, इसलिए यह डुप्लिकेट को नहीं हटाता है।
P_P

0

सबसे अच्छा तरीका? कहना मुश्किल है, हैशसेट दृष्टिकोण तेजी से दिखता है, लेकिन (डेटा के आधार पर) एक तरह के एल्गोरिथ्म (काउंट्सर्ट?) का उपयोग करके बहुत तेज हो सकता है।

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;
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.