More elegant way to check for duplicates in C++ array?

后端 未结 12 1393
梦如初夏
梦如初夏 2020-12-01 09:36

I wrote this code in C++ as part of a uni task where I need to ensure that there are no duplicates within an array:

// Check for duplicate numbers in user in         


        
相关标签:
12条回答
  • 2020-12-01 10:10

    The following solution is based on sorting the numbers and then removing the duplicates:

    #include <algorithm>
    
    int main()
    {
        int userNumbers[6];
    
        // ...
    
        int* end = userNumbers + 6;
        std::sort(userNumbers, end);
        bool containsDuplicates = (std::unique(userNumbers, end) != end);
    }
    
    0 讨论(0)
  • 2020-12-01 10:12
    #include<iostream>
    #include<algorithm>
    
    int main(){
    
        int arr[] = {3, 2, 3, 4, 1, 5, 5, 5};
        int len = sizeof(arr) / sizeof(*arr); // Finding length of array
    
        std::sort(arr, arr+len);
    
        int unique_elements = std::unique(arr, arr+len) - arr;
    
        if(unique_elements == len) std::cout << "Duplicate number is not present here\n";
        else std::cout << "Duplicate number present in this array\n";
    
        return 0;
    }
    
    0 讨论(0)
  • 2020-12-01 10:15
    //std::unique(_copy) requires a sorted container.
    std::sort(cont.begin(), cont.end());
    
    //testing if cont has duplicates
    std::unique(cont.begin(), cont.end()) != cont.end();
    
    //getting a new container with no duplicates
    std::unique_copy(cont.begin(), cont.end(), std::back_inserter(cont2));
    
    0 讨论(0)
  • 2020-12-01 10:15

    I think @Michael Jaison G's solution is really brilliant, I modify his code a little to avoid sorting. (By using unordered_set, the algorithm may faster a little.)

    template <class Iterator>
    bool isDuplicated(Iterator begin, Iterator end) {
        using T = typename std::iterator_traits<Iterator>::value_type;
        std::unordered_set<T> values(begin, end);
        std::size_t size = std::distance(begin,end);
        return size != values.size();
    }
    
    0 讨论(0)
  • 2020-12-01 10:17

    You could sort the array in O(nlog(n)), then simply look until the next number. That is substantially faster than your O(n^2) existing algorithm. The code is also a lot cleaner. Your code also doesn't ensure no duplicates were inserted when they were re-entered. You need to prevent duplicates from existing in the first place.

    std::sort(userNumbers.begin(), userNumbers.end());
    for(int i = 0; i < userNumbers.size() - 1; i++) {
        if (userNumbers[i] == userNumbers[i + 1]) {
            userNumbers.erase(userNumbers.begin() + i);
            i--;
        }
    }
    

    I also second the reccomendation to use a std::set - no duplicates there.

    0 讨论(0)
  • 2020-12-01 10:25

    It's ok, specially for small array lengths. I'd use more efficient aproaches (less than n^2/2 comparisons) if the array is mugh bigger - see DeadMG's answer.

    Some small corrections for your code:

    • Instead of int j = i writeint j = i +1 and you can omit your if(j != i) test
    • You should't need to declare i variable outside the for statement.
    0 讨论(0)
提交回复
热议问题