एक सूची में डुप्लिकेट की पहचान करें


119

मेरे पास इंटेगर प्रकार की सूची है जैसे:

[1, 1, 2, 3, 3, 3]

मैं सभी डुप्लिकेट को वापस करने के लिए एक विधि चाहूंगा जैसे:

[1, 3]

इसे करने का बेहतरीन तरीका क्या है?


2
क्या इनपुट सूची को क्रमबद्ध करने की गारंटी दी गई है (जैसा कि आपके उदाहरण में)?
NPE

7
सूची को क्रमबद्ध करें, फिर इसे चालू और पूर्व मानों को रखते हुए चलें। यदि वर्तमान == पहले आपके पास एक डुप्लिकेट है।
mcfinnigan

नहीं, सूची आवश्यक रूप से क्रमबद्ध नहीं है।
ताज़े

जवाबों:


183

विधि addका Setरिटर्न एक बूलियन एक मूल्य पहले से ही मौजूद है या नहीं (सच अगर यह मौजूद नहीं है, झूठी अगर यह पहले से मौजूद है, को देखने के सेट प्रलेखन )।

तो बस सभी मूल्यों के माध्यम से पुनरावृति:

public Set<Integer> findDuplicates(List<Integer> listContainingDuplicates)
{ 
  final Set<Integer> setToReturn = new HashSet<>(); 
  final Set<Integer> set1 = new HashSet<>();

  for (Integer yourInt : listContainingDuplicates)
  {
   if (!set1.add(yourInt))
   {
    setToReturn.add(yourInt);
   }
  }
  return setToReturn;
}

1
आपके पास सेटटॉर्न क्यों है? क्या आप सिर्फ set1.add (yourInt) और रिटर्न सेट 1 का उपयोग नहीं कर सकते हैं?
फिल

3
हाँ बिल्कुल। लेकिन जब निर्दिष्ट सूची में एक बार केवल एक एलमेन्ट मौजूद होता है, तो तत्व को भी जोड़ा जाता है। प्रश्न में उदाहरण देखें: मेरा समाधान वापस आ जाएगा [1,3] क्योंकि नंबर 2 को सेट 1 में डाला गया है, लेकिन सेटटॉर्न में नहीं। आपका समाधान वापस आ जाएगा [1,2,3] (जिसकी आवश्यकता नहीं है)
leifg

1
मेरा सुझाव है कि आप for (Integer yourIntअनावश्यक बॉक्सिंग और अनबॉक्सिंग से बचने के लिए उपयोग करते हैं , खासकर जब से आपके इनपुट में पहले से ही Integerएस है।
होसम ऐली

1
@JonasThelemann एक सेट का पूरा विचार यह है कि इसमें डुप्लिकेट नहीं हो सकते। इसलिए: कोई फर्क नहीं पड़ता कि आप कितनी बार 3 जोड़ेंगे यह हमेशा केवल एक बार समाप्त होगा।
लीफग

1
वैसे, आप के मामले में HashSetभी लोड फैक्टर पर विचार करना होगा, उदाहरण के लिए जब आप एक प्रारंभिक क्षमता निर्दिष्ट करते हैं 100, क्योंकि आप तत्वों की उस संख्या को जोड़ना चाहते हैं, यह 2 की अगली शक्ति पर गोल हो जाता है ( 128), जिसका अर्थ है कि के डिफ़ॉल्ट लोड कारक के साथ 0.75f, आकार सीमा होगी 96, इसलिए आपके द्वारा जोड़े गए 100तत्वों को जोड़ने से पहले एक आकार होगा । शुक्र है, आकार बदलना अब महंगा नहीं है। JRE को अद्यतित करने के साथ, आकार बदलना अब फिर से नहीं हो रहा है, तत्वों को संबंधित बिट के आधार पर उनके दो संभावित परिणाम स्थानों के बीच वितरित किया जाता है।
होल्गर

50

मुझे इसके समाधान की आवश्यकता थी। मैंने लीफग के घोल का इस्तेमाल किया और इसे सामान्य बनाया।

private <T> Set<T> findDuplicates(Collection<T> collection) {

    Set<T> duplicates = new LinkedHashSet<>();
    Set<T> uniques = new HashSet<>();

    for(T t : collection) {
        if(!uniques.add(t)) {
            duplicates.add(t);
        }
    }

    return duplicates;
}

1
मुझे पता है कि यह 3 साल बाद है, लेकिन एक लिंक्डहेडसेट, यानी आप ऑर्डर के बारे में क्यों परवाह करते हैं?
अहमद रगब

4
@ अहमदबाग आप सही कह रहे हैं, लिंक्डहाशसेट की आवश्यकता तब तक नहीं है जब तक आप उस आदेश की परवाह नहीं करते जब डुप्लिकेट पाए गए (जो मुझे लगता है कि मैंने उस समय किया था)
जॉन स्ट्रिकलर

फॉलो करने के लिए धन्यवाद!
अहमद रगब

यदि आपके पास इतना इनपुट डेटा है कि आप इस इष्टतम समाधान (इनपुट को सॉर्ट करने के बजाय) का उपयोग करना चाहते हैं, तो आप हाशसेट () ऑब्जेक्ट के आकार को पूर्व-आवंटित करना भी चाहेंगे। उपदेश के बिना, आपको HashSet () में डालने पर O (1) डालने का समय नहीं मिलता है। इसका कारण यह है कि आंतरिक हैश सरणी बार-बार आकार दिया जाता है। आवेषण तो ओ (लॉग एन) समय की तरह कुछ करने के लिए औसत। इसका मतलब है कि सभी N आइटम O (N लॉग N) हो जाते हैं जब यह O (N) हो सकता था।
जॉनस्टोश

39

मैंने जॉन स्ट्रिकलर के समाधान को लिया और इसे JDK8 में शुरू की गई स्ट्रीम API का उपयोग करने के लिए रीमेक किया:

private <T> Set<T> findDuplicates(Collection<T> collection) {
    Set<T> uniques = new HashSet<>();
    return collection.stream()
        .filter(e -> !uniques.add(e))
        .collect(Collectors.toSet());
}

3
यह पढ़ना कठिन है, नहीं? आप स्ट्रीम ऑपरेशन में एक साइड-इफ़ेक्ट कर रहे हैं, जिससे यह तर्क के लिए कठिन हो जाता है। लेकिन यह सिर्फ मुझे कार्यात्मक शैली सोच रहा है। यह संक्षिप्त है और शायद सबसे छोटा तरीका है;)।
फ्रेजिनवासियन

बड़ी सूचियों के लिए आप इसे कई थ्रेड पर समानांतर रूप से निष्पादित कर सकते हैं?
जॉनस्टॉश

@froginvasion निर्मित distinct()विधि भी स्टेटफुल है। एक कुशल (O (n)) विशिष्ट ऑपरेशन के बारे में नहीं सोच सकते हैं जो स्टेटफुल नहीं है।
विलेमोल

18

यहां जावा 8 के साथ स्ट्रीम का उपयोग करके एक समाधान है

// lets assume the original list is filled with {1,1,2,3,6,3,8,7}
List<String> original = new ArrayList<>();
List<String> result = new ArrayList<>();

आप बस देखते हैं कि क्या इस वस्तु की आवृत्ति आपकी सूची में एक से अधिक बार है। तब .distinct () को केवल आपके परिणाम में अनन्य तत्व होने के लिए कहें

result = original.stream()
    .filter(e -> Collections.frequency(original, e) > 1)
    .distinct()
    .collect(Collectors.toList());
// returns {1,3}
// returns only numbers which occur more than once

result = original.stream()
    .filter(e -> Collections.frequency(original, e) == 1)
    .collect(Collectors.toList());
// returns {2,6,8,7}
// returns numbers which occur only once

result = original.stream()
    .distinct()
    .collect(Collectors.toList());
// returns {1,2,3,6,8,7}
// returns the list without duplicates

1
यह पठनीयता के मामले में अच्छा है, लेकिन यह वास्तव में प्रदर्शन के लिए बुरा है। Collections::frequencyहै ओ (एन)। किसी वस्तु की आवृत्ति का पता लगाने के लिए उसे पूरे संग्रह से गुजरना पड़ता है। और हम इसे संग्रह में प्रत्येक आइटम के लिए एक बार कॉल कर रहे हैं, जो इन स्निपेट को बनाता है O(n^2)। आप एक से अधिक तत्वों के किसी भी संग्रह में अंतर देखेंगे। मैं वास्तविक कोड में इसका इस्तेमाल कभी नहीं करूंगा।
पवन

13

जावा 8 बेस समाधान:

List duplicates =    
list.stream().collect(Collectors.groupingBy(Function.identity()))
    .entrySet()
    .stream()
    .filter(e -> e.getValue().size() > 1)
    .map(Map.Entry::getKey)
    .collect(Collectors.toList());

इनपुट सूची को नक्शे में बदल दिया जाता है, (समान मानों का समूह)। तब अद्वितीय मान वाले मानचित्र के मान "हटाए गए" होते हैं, फिर कुंजी का उपयोग करके मानचित्र, फिर सूची की सूची को एक सूची में बदल दिया जाता है
بلال الملمودي

सुंदर और तेज समाधान, सीधे आइटम के विशिष्ट
गेटर्स

11
int[] nums =  new int[] {1, 1, 2, 3, 3, 3};
Arrays.sort(nums);
for (int i = 0; i < nums.length-1; i++) {

    if (nums[i] == nums[i+1]) {
        System.out.println("duplicate item "+nums[i+1]+" at Location"+(i+1) );
    }

}

स्पष्ट रूप से आप उनके साथ जो चाहें कर सकते हैं (यानी डुप्लिकेट मूल्यों की एक अनूठी सूची प्राप्त करने के लिए सेट में डाल दें) मुद्रण के बजाय ... इससे डुप्लिकेट आइटम के स्थान को रिकॉर्ड करने का भी लाभ होता है।


7

जावा 8 पर अमरूद का उपयोग करना

private Set<Integer> findDuplicates(List<Integer> input) {
    // Linked* preserves insertion order so the returned Sets iteration order is somewhat like the original list
    LinkedHashMultiset<Integer> duplicates = LinkedHashMultiset.create(input);

    // Remove all entries with a count of 1
    duplicates.entrySet().removeIf(entry -> entry.getCount() == 1);

    return duplicates.elementSet();
}

7

यह भी काम करता है:

public static Set<Integer> findDuplicates(List<Integer> input) {
    List<Integer> copy = new ArrayList<Integer>(input);
    for (Integer value : new HashSet<Integer>(input)) {
        copy.remove(value);
    }
    return new HashSet<Integer>(copy);
}

यह काम करता है, लेकिन एक सरणी सूची पर कॉल हटाने () को कॉल करने के बाद से यह धीमी गति से होता है।
जॉनस्टॉश

सच। ध्यान दें कि यदि आपके इनपुट में कई डुप्लिकेट हैं, तो प्रदर्शन हिट की तुलना में कम है यदि उनमें से कुछ ही हैं।
एड्रियन कोस्टर

6

आप कुछ इस तरह का उपयोग कर सकते हैं:

List<Integer> newList = new ArrayList<Integer>();
for(int i : yourOldList)
{
    yourOldList.remove(i);
    if(yourOldList.contains(i) && !newList.contains(i)) newList.add(i);
}

2
यहाँ सूची का उपयोग करना बहुत ही अप्रभावी है
अलेक्जेंडर फार्बर

2
और मुझे intयहाँ वैरिएबल टाइप के रूप में उपयोग करने की शुरुआत नहीं है। इसका अर्थ है कि प्रत्येक एकल पुनरावृत्ति के लिए, एक इंटेगर को एक बार अनबॉक्स किया जाता है और एक इंट को चार बार बॉक्स किया जाता है!
सीन पैट्रिक फ्लॉयड

1
मुझे लगता है कि सूची से एक तत्व को हटाने की कोशिश करते समय आप आसानी से एक समवर्ती
(एक्सट्रैक्ट) मॉडिफ़िकेशन अपवाद

1
जब से आप किसी सूची पर पुनरावृति करते हैं और आप मक्खी पर मौजूद तत्वों को हटा देते हैं, तो यह 100% समवर्ती है।
theo231022

5

लेम्बस एक समाधान हो सकता है

Integer[] nums =  new Integer[] {1, 1, 2, 3, 3, 3};
List<Integer> list = Arrays.asList(nums);

List<Integer> dps = list.stream().distinct().filter(entry -> Collections.frequency(list, entry) > 1).collect(Collectors.toList());

1
काम करता है, लेकिन यह प्रत्येक प्रविष्टि के लिए संग्रह.फ्रीक्वेंसी चलाता है और इस प्रकार धीमा है।
arberg

4

कुंजी / मान सेट के रूप में प्रत्येक मान को संग्रहीत करने के लिए एक मल्टीपॉइंट का उपयोग करें। फिर कुंजियों के माध्यम से पुनरावृति करें और लोगों को कई मानों के साथ खोजें।


3

यदि आप ग्रहण संग्रह का उपयोग करते हैं , तो यह काम करेगा:

MutableList<Integer> list = Lists.mutable.with(1, 1, 2, 3, 3, 3);
Set<Integer> dupes = list.toBag().selectByOccurrences(i -> i > 1).toSet();
Assert.assertEquals(Sets.mutable.with(1, 3), dupes);

अद्यतन: ग्रहण संग्रह ९ .२ के रूप में अब आप उपयोग कर सकते हैंselectDuplicates

MutableList<Integer> list = Lists.mutable.with(1, 1, 2, 3, 3, 3);
Set<Integer> dupes = list.toBag().selectDuplicates().toSet();
Assert.assertEquals(Sets.mutable.with(1, 3), dupes);

इसे पूरा करने के लिए आप आदिम संग्रह का भी उपयोग कर सकते हैं:

IntList list = IntLists.mutable.with(1, 1, 2, 3, 3, 3);
IntSet dupes = list.toBag().selectDuplicates().toSet();
Assert.assertEquals(IntSets.mutable.with(1, 3), dupes);

नोट: मैं एक्लिप्स कलेक्शंस के लिए कमिट हूं।


2
public class practicese {
       public static void main(String[] args) {   

           List<Integer> listOf = new ArrayList<Integer>();
           listOf.add(3);
           listOf.add(1);
           listOf.add(2);
           listOf.add(3);
           listOf.add(3);
           listOf.add(2);
           listOf.add(1);

           List<Integer> tempList = new ArrayList<Integer>();
           for(Integer obj:listOf){
                if(!tempList.contains(obj)){
                    tempList.add(obj);

                }
            }
            System.out.println(tempList);

    }

}

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

2

यहाँ कुछ उत्तरों के समान है, लेकिन यदि आप कुछ संपत्ति के आधार पर डुप्लिकेट ढूंढना चाहते हैं:

  public static <T, R> Set<R> findDuplicates(Collection<? extends T> collection, Function<? super T, ? extends R> mapper) {
    Set<R> uniques = new HashSet<>();
    return collection.stream()
        .map(mapper)
        .filter(e -> !uniques.add(e))
        .collect(toSet());
  }

1

सूची बनाएं Map<Integer,Integer>, सूची को पुनरावृत्त करें, यदि कोई तत्व नक्शे में है, तो इसका मान बढ़ाएं, अन्यथा इसे कुंजी = 1 मानचित्र के साथ
मैप में जोड़ें और सूचियों को कुंजी> = 2 के साथ सभी तत्वों में जोड़ें।

public static void main(String[] args) {
        List<Integer> list = new LinkedList<Integer>();
        list.add(1);
        list.add(1);
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(3);
        Map<Integer,Integer> map = new HashMap<Integer, Integer>();
        for (Integer x : list) { 
            Integer val = map.get(x);
            if (val == null) { 
                map.put(x,1);
            } else {
                map.remove(x);
                map.put(x,val+1);
            }
        }
        List<Integer> result = new LinkedList<Integer>();
        for (Entry<Integer, Integer> entry : map.entrySet()) {
            if (entry.getValue() > 1) {
                result.add(entry.getKey());
            }
        }
        for (Integer x : result) { 
            System.out.println(x);
        }

    }

यह बहुत अच्छा है। यह सबसे अच्छा समाधान है अगर आपको यह जानने की आवश्यकता है कि कितने डुप्लिकेट थे। कुछ नोट: (1) आपको पुट () करने से पहले कॉल () हटाने की आवश्यकता नहीं है। (2) आप बार-बार जोड़ने () कॉल का उपयोग करने के बजाय एक लिंक से लिंक्डलिस्ट सेट कर सकते हैं। (३) जब वैल! = अशक्त हो, तो आप परिणाम के लिए तुरंत x जोड़ सकते हैं। परिणाम एक सेट या एक सूची हो सकती है जो इस बात पर निर्भर करती है कि आप डुप्लिकेट की संख्या की गणना करना चाहते हैं या नहीं।
जॉन्स्टॉश

1

शीर्ष उत्तर के कॉम्पैक्ट जनरेटेड संस्करण, ने खाली चेक भी जोड़ा और सेट आकार का प्रचार किया:

public static final <T> Set<T> findDuplicates(final List<T> listWhichMayHaveDuplicates) {
    final Set<T> duplicates = new HashSet<>();
    final int listSize = listWhichMayHaveDuplicates.size();
    if (listSize > 0) {
      final Set<T> tempSet = new HashSet<>(listSize);
      for (final T element : listWhichMayHaveDuplicates) {
        if (!tempSet.add(element)) {
          duplicates.add(element);
        }
      }
    }
    return duplicates;
  }

क्या आपको शून्य चेक की आवश्यकता है? क्या नया HashSet <> (0) समझदार खाली सेट लौटाएगा?
जॉनस्टोश

@johnstosh इस कोड को सरल किया जा सकता है, लेकिन शून्य के लिए जाँच केवल init करने की अनुमति देता tempSetके साथ listSizeजब आवश्यक। यह एक मामूली अनुकूलन है लेकिन मुझे यह पसंद है।
क्रिस्टोफ रूसो

1

मैंने सेबस्टियन का जवाब लिया और उसमें एक keyExtractor जोड़ा -

    private <U, T> Set<T> findDuplicates(Collection<T> collection, Function<? super T,? extends U> keyExtractor) {
        Map<U, T> uniques = new HashMap<>(); // maps unique keys to corresponding values
        return collection.stream()
            .filter(e -> uniques.put(keyExtractor.apply(e), e) != null)
            .collect(Collectors.toSet());
    }

1

एक धागा-सुरक्षित विकल्प यह है:

/**
 * Returns all duplicates that are in the list as a new {@link Set} thread-safe.
 * <p>
 * Usually the Set will contain only the last duplicate, however the decision
 * what elements are equal depends on the implementation of the {@link List}. An
 * exotic implementation of {@link List} might decide two elements are "equal",
 * in this case multiple duplicates might be returned.
 * 
 * @param <X>  The type of element to compare.
 * @param list The list that contains the elements, never <code>null</code>.
 * @return A set of all duplicates in the list. Returns only the last duplicate.
 */
public <X extends Object> Set<X> findDuplicates(List<X> list) {
    Set<X> dups = new LinkedHashSet<>(list.size());
    synchronized (list) {
        for (X x : list) {
            if (list.indexOf(x) != list.lastIndexOf(x)) {
                dups.add(x);
            }
        }
    }
    return dups;
}

0

सूची में डुप्लिकेट आइटम खोजने के लिए इसे आज़माएं:

ArrayList<String> arrayList1 = new ArrayList<String>(); 

arrayList1.add("A"); 
arrayList1.add("A"); 
arrayList1.add("B"); 
arrayList1.add("B"); 
arrayList1.add("B"); 
arrayList1.add("C"); 

for (int x=0; x< arrayList1.size(); x++) 
{ 
System.out.println("arrayList1 :"+arrayList1.get(x)); 
} 
Set s=new TreeSet(); 
s.addAll(arrayList1); 
Iterator it=s.iterator(); 
while (it.hasNext()) 
{ 
System.out.println("Set :"+(String)it.next()); 
} 

हां, यह सेट ढूंढता है, लेकिन यह उन वस्तुओं की सूची या सेट नहीं ढूंढता है जो डुप्लिकेट हैं।
जॉनस्टोश

0

इसके लिए छंटनी और अनसोल्ड के लिए काम करना चाहिए।

public void testFindDuplicates() {

    List<Integer> list = new ArrayList<Integer>();
    list.add(1);
    list.add(1);
    list.add(2);
    list.add(3);
    list.add(3);
    list.add(3);

    Set<Integer> result = new HashSet<Integer>();
    int currentIndex = 0;
    for (Integer i : list) {
        if (!result.contains(i) && list.subList(currentIndex + 1, list.size()).contains(i)) {
            result.add(i);
        }
        currentIndex++;
    }
    assertEquals(2, result.size());
    assertTrue(result.contains(1));
    assertTrue(result.contains(3));
}

ArrayList के सबलिस्ट पर कॉल करना () शामिल है क्योंकि यह एक रैखिक खोज है। तो यह 10 आइटम के लिए ठीक है, लेकिन 10 मिलियन के लिए नहीं।
जॉनस्टॉश

0

यह एक ऐसी समस्या है जहाँ कार्यात्मक तकनीक चमकती है। उदाहरण के लिए, निम्नलिखित एफ # समाधान दोनों सबसे अच्छा अनिवार्य जावा समाधान की तुलना में स्पष्ट और कम बग प्रवण है (और मैं जावा और एफ # दोनों के साथ दैनिक काम करता हूं)।

[1;1;2;3;3;3] 
|> Seq.countBy id 
|> Seq.choose (fun (key,count) -> if count > 1 then Some(key) else None)

बेशक, यह सवाल जावा के बारे में है। इसलिए मेरा सुझाव एक पुस्तकालय को अपनाना है जो जावा में कार्यात्मक विशेषताएं लाता है। उदाहरण के लिए, इसे अपने स्वयं के पुस्तकालय का उपयोग करके हल किया जा सकता है (और वहाँ कई अन्य लोग भी देखने लायक हैं):

Seq.of(1,1,2,3,3,3)
.groupBy(new Func1<Integer,Integer>() {
    public Integer call(Integer key) {
        return key;
    }
}).filter(new Predicate<Grouping<Integer,Integer>>() {
   public Boolean call(Grouping<Integer, Integer> grouping) {
        return grouping.getGrouping().count() > 1;
   }
}).map(new Func1<Grouping<Integer,Integer>,Integer>() {
    public Integer call(Grouping<Integer, Integer> grouping) {
        return grouping.getKey();
    }
});

और फिर आप देखते हैं कि जावा वास्तव में कार्यात्मक प्रोग्रामिंग में कितना बेकार है। इस तरह की एक साधारण समस्या, जावा में जो आप चाहते हैं उसे व्यक्त करना इतना कठिन।
फ्रेजिनवासियन

0
public class DuplicatesWithOutCollection {

    public static void main(String[] args) {

        int[] arr = new int[] { 2, 3, 4, 6, 6, 8, 10, 10, 10, 11, 12, 12 };

        boolean flag = false;
        int k = 1;
        while (k == 1) {

            arr = removeDuplicate(arr);
            flag = checkDuplicate(arr, flag);
            if (flag) {
                k = 1;
            } else {
                k = 0;
            }

        }

    }

    private static boolean checkDuplicate(int[] arr, boolean flag) {
        int i = 0;

        while (i < arr.length - 1) {

            if (arr[i] == arr[i + 1]) {

                flag = true;

            } else {
                flag = false;
            }
            i++;

        }

        return flag;
    }

    private static int[] removeDuplicate(int[] arr) {

        int i = 0, j = 0;
        int[] temp = new int[arr.length];
        while (i < arr.length - 1) {

            if (arr[i] == arr[i + 1]) {

                temp[j] = arr[i + 1];
                i = i + 2;

            } else {

                temp[j] = arr[i];
                i = i + 1;

                if (i == arr.length - 1) {
                    temp[j + 1] = arr[i + 1];
                    break;
                }

            }
            j++;

        }
        System.out.println();
        return temp;
    }

}

संग्रह कक्षाओं का उपयोग किए बिना लागू करना। लेकिन लूप में बहुत कम सुधार की आवश्यकता है। ऊपर दी गई मदद के लिए स्वयंसेवी मदद सराहनीय है। -> 2 3 4 6 8 10 11 11 12
सम्राट रॉय

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

@ जॉन्स्टॉश हाँ मुझे इस बारे में पता है, लेकिन मैं कलेक्शन दैट का उपयोग किए बिना इसे बनाने के बारे में सोच रहा था कि मैंने अपनी टिप्पणी में उल्लेख क्यों किया है। जैसा कि आप देख रहे हैं कि मैंने फरवरी 2017 से पहले टिप्पणी की है, [ऐसी तकनीकें हैं जहां आपको संग्रह का उपयोग करने की आवश्यकता नहीं है। कम समय की जटिलता के साथ] geeksforgeeks.org/…। मैंने DS और Algo प्रथाओं को जाने बिना उस कार्यक्रम की कोशिश की है। आपको इसके लिए मुझे कम नहीं करना है। धन्यवाद धन्यवाद।
सम्राट रॉय

0
import java.util.Scanner;

public class OnlyDuplicates {
    public static void main(String[] args) {
        System.out.print(" Enter a set of 10 numbers: ");
        int[] numbers = new int[10];
        Scanner input = new Scanner(System.in);
        for (int i = 0; i < numbers.length; i++) {
            numbers[i] = input.nextInt();
        }
        numbers = onlyDuplicates(numbers);
        System.out.print(" The numbers are: ");
        for (int i = 0; i < numbers.length; i++) {
            System.out.print(numbers[i] + "");
        }
    }

    public static int[] onlyDuplicates(int[] list) {
        boolean flag = true;
        int[] array = new int[0];
        array = add2Array(array, list[0]);
        for (int i = 0; i < list.length; i++) {
            for (int j = 0; j < array.length; j++) {
                if (list[i] == array[j]) {
                    flag = false;
                    break;
                }
            }
            if (flag) {
                array = add2Array(array, list[i]);
            }
            flag = true;
        }
        return array;
    }
    // Copy numbers1 to numbers2
    // If the length of numbers2 is less then numbers2, return false
    public static boolean copyArray(int[] source, int[] dest) {
        if (source.length > dest.length) {
            return false;
        }

        for (int i = 0; i < source.length; i++) {
            dest[i] = source[i];
        }
        return true;
    }
    // Increase array size by one and add integer to the end of the array
    public static int[] add2Array(int[] source, int data) {
        int[] dest = new int[source.length + 1];
        copyArray(source, dest);
        dest[source.length] = data;
        return dest;
    }
}

डुप्लिकेट को वापस करने के लिए मुझे क्या बदलने की आवश्यकता है?
ब्रेंडेन

इसे नए प्रश्न के रूप में पूछा जाना चाहिए।
22

0

यह सेट का उपयोग किए बिना, डुप्लिकेट मानों को खोजने के लिए एक अच्छा तरीका होगा।

public static <T> List<T> findDuplicates(List<T> list){

List<T> nonDistinctElements = new ArrayList<>();

  for(T s : list)
    if(list.indexOf(s) != list.lastIndexOf(s))
      if(!nonDistinctElements.contains(s))
        nonDistinctElements.add(s);

  return nonDistinctElements;
}

और कहते हैं, कि आप एक ऐसी विधि चाहते हैं जो आपको एक अलग सूची लौटाए, अर्थात यदि आप एक सूची पास करते हैं जहाँ तत्व एक से अधिक बार हो रहे हैं, तो आपको अलग-अलग तत्वों के साथ एक सूची मिलेगी।

public static <T> void distinctList(List<T> list){

List<T> nonDistinctElements = new ArrayList<>();
for(T s : list)
  if(list.indexOf(s) != list.lastIndexOf(s))
    nonDistinctElements.add(s);

for(T nonDistinctElement : nonDistinctElements)
  if(list.indexOf(nonDistinctElement) != list.lastIndexOf(nonDistinctElement))
    list.remove(nonDistinctElement);
}

0

और संस्करण जो commons-collections CollectionUtils.getCardinalityMapविधि का उपयोग करता है:

final List<Integer> values = Arrays.asList(1, 1, 2, 3, 3, 3);
final Map<Integer, Integer> cardinalityMap = CollectionUtils.getCardinalityMap(values);
System.out.println(cardinalityMap
            .entrySet()
            .stream().filter(e -> e.getValue() > 1)
            .map(e -> e.getKey())
            .collect(Collectors.toList()));

`` `


0

इस कोड के बारे में कैसे -

public static void main(String[] args) {

    //Lets say we have a elements in array
    int[] a = {13,65,13,67,88,65,88,23,65,88,92};

    List<Integer> ls1 = new ArrayList<>();
    List<Integer> ls2 = new ArrayList<>();
    Set<Integer> ls3 = new TreeSet<>();

    //Adding each element of the array in the list      
    for(int i=0;i<a.length;i++) {
     {
    ls1.add(a[i]);
    }
    }

    //Iterating each element in the arrary
    for (Integer eachInt : ls1) {

    //If the list2 contains the iterating element, then add that into set<> (as this would be a duplicate element)
        if(ls2.contains(eachInt)) {
            ls3.add(eachInt);
        }
        else {ls2.add(eachInt);}

    }

    System.out.println("Elements in array or ls1"+ls1); 
    System.out.println("Duplicate Elements in Set ls3"+ls3);


}

0

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

इस कोड का उपयोग करें (उस प्रकार को बदलें जिसकी आपको आवश्यकता है)

public Set<String> findDup(List<String> Duplicates){
    Set<String> returning = new HashSet<>();
    Set<String> nonreturning = new HashSet<>();
    Set<String> setup = new HashSet<>();
    for(String i:Duplicates){
        if(!setup.add( i )){
            returning.add( i );
        }else{
            nonreturning.add( i );
        }
    }
    Toast.makeText( context,"hello set"+returning+nonreturning+" size"+nonreturning.size(),Toast.LENGTH_SHORT ).show();
    return nonreturning;
}

0

Https://stackoverflow.com/a/52296246 के संस्करण के रूप में अधिक सामान्य विधि

    /**
     * Returns a duplicated values found in given collection based on fieldClassifier
     *
     * @param collection given collection of elements
     * @param fieldClassifier field classifier which specifies element to check for duplicates(useful in complex objects).
     * @param <T> Type of element in collection
     * @param <K> Element which will be returned from method in fieldClassifier.
     * @return returns list of values that are duplocated.
     */
    public static <T, K> List<K> lookForDuplicates(List<T> collection, Function<? super T, ? extends K> fieldClassifier) {

        return collection.stream().collect(Collectors.groupingBy(fieldClassifier))
                         .entrySet()
                         .stream()
                         .filter(e -> e.getValue().size() > 1)
                         .map(Map.Entry::getKey)
                         .collect(Collectors.toList());
    }

-1

यदि आप अधिकतम मूल्य जानते हैं (उदाहरण के लिए <10000) तो आप गति के लिए स्थान का त्याग कर सकते हैं। मुझे इस तकनीक का सटीक नाम याद नहीं है।

छद्म कोड:

//does not handle case when mem allocation fails 
//probably can be extended to unknown values /larger values .
maybe by sorting first
public List<int> GetDuplicates(int max)
{   
    //allocate and clear memory to 0/false
    bit[] buckets=new bit[max]
    memcpy(buckets,0,max);
    //find duplicates
    List<int> result=new List<int>();
    foreach(int val in List)
    {
        if (buckets[val])
        {
            result.add(value);
        }
        else
        {
            buckets[val]=1;
        }
    }
    return  result
}

मुझे लगता है कि आप "बिट" के बजाय "बूलियन" चाहते हैं? क्या आपने पोस्ट करने से पहले अपने कोड को निष्पादित किया? यह एक अच्छी शुरुआत है। यदि आप हैशसेट () पर एक नज़र डालेंगे तो आप देखेंगे कि यह 'बकेट' का कार्यान्वयन है जिसे आप चाहते हैं।
जॉनस्टॉश

-1

बस यह प्रयास करें:

उदाहरण यदि सूची मान हैं: [1, 2, 3, 4, 5, 6, 4, 3, 7, 8] डुप्लिकेट आइटम [3, 4]।

Collections.sort(list);
        List<Integer> dup = new ArrayList<>();
        for (int i = 0; i < list.size() - 1; i++) {
            if (list.get(i) == list.get(i + 1)) {
                if (!dup.contains(list.get(i + 1))) {
                    dup.add(list.get(i + 1));
                }
            }
        }
        System.out.println("duplicate item " + dup);

ArrayList पर () शामिल करना एक महंगा ऑपरेशन है, इसलिए आपको इसके बजाय सेट का उपयोग करने पर विचार करना चाहिए। आप हैशसेट () या इसके जुड़े संस्करणों का उपयोग कर अन्य समाधान देखेंगे।
जॉनस्टॉज
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.