2

I have an array in which I have to ignore, delete all the numbers which are repetitive,

for example 1 2 4 3 3 0 1 2 0

What I did is I checked the numbers and tried stuff like \0 and NULL but both of them give the value of 0 so it's not a solution. So is there a way to make an index empty or just to ignore it? The numbers must be random so I can't declare something like

array[i]=123;
if(array[i]==123) dont_print_out();

2 Answers 2

5

If your array is a plain C++ array, you have no method to "remove" items. You only solution is to shift the remaining items to the left.

If your array is a std::vector, you can use the erase function. However, due to the structure of the underlying data in a vector, you do basically the same as before: it is inefficient.

If you want efficient removal of items randomly located in your sequence, consider using another kind of container, like a std::list.

Last, to achieve your goal, take a look at std::set or std::unordered_set. These containers ensure that your items are unique.

Sign up to request clarification or add additional context in comments.

3 Comments

1. Using std::list to support random removal is almost always a mistake. You lose more in traversing the list to find the duplicates than you gain in the removal itself being fast. 2. A vector with std::unique will usually be faster than std::set or even std::unordered_set. 3. You can erase from a vector efficiently as long as you don't care about maintaining the original order.
@Jerry Coffin: 3. OK, if you move the end item to the hole created by the removal, correct ?
You normally want to swap the item to be removed to the end. With int copying will be fine, but with something like std::string or std::vector, swap will typically be faster (and it would be quite unusual for it to be much, if any, slower).
2
  1. Use an std::vector instead of an array, so you can erase items1.
  2. If you don't need to maintain the original order, it's probably easiest to sort, then use std::unique to eliminate the duplicates.

Code could look something like this:

std::vector<int> numbers;

srand(time(NULL));

std::generate_n(std::back_inserter(numbers), 10, rand);
std::sort(numbers.begin(), numbers.end());
std::copy(numbers.begin(), std::unique(numbers.begin(), numbers.end()), 
          std::ostream_iterator<int>(std::cout, "\t"));

 // Or, as @Chris pointed out:
 std::unique_copy(numbers.begin(), numbers.end(),
          std::ostream_iterator<int>(std::cout, "\t"));

Note that since std::unique returns an iterator to the end of the range of unique numbers, we don't actually need to erase the others at all -- we can just use that as the end of the range we display.

Also note that as I've generated the numbers here, it would actually be pretty unusual to remove anything -- given the range of numbers produced by a typical implementation of rand(), it would be fairly unusual to see it produce any duplicates in only 10 iterations.

If you do need to maintain the original order, you have a couple of choices. One is to insert each item in a std::set (or std::unordered_set) as you print it out, and only print it out of inserting in the set was successful (i.e., it wasn't previously present).


1. Though that's only one of many reasons to prefer std::vector over an array.

1 Comment

Don't forget about std::unique_copy :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.