WEBVTT

00:00.150 --> 00:05.850
Hello again! In this video, we are going to continue looking at removing algorithms. As is often the

00:05.850 --> 00:07.890
case, there are other versions of remove().

00:08.530 --> 00:14.190
There is remove_if(), which takes a predicate, and _copy() versions, which will write the result

00:14.190 --> 00:15.660
to a destination container,

00:16.080 --> 00:18.600
instead of modifying the iterator range in place.

00:21.000 --> 00:27.920
The remove() algorithm uses the equality operator to decide whether to remove an element. With remove underscore

00:27.920 --> 00:31.440
if(), we can provide our own predicate as the third argument.

00:32.670 --> 00:37.200
This will be called with each element as the argument. And then, if this returns true, the element

00:37.200 --> 00:37.950
will be removed.

00:38.430 --> 00:41.010
And if it returns false, the element will be kept.

00:41.880 --> 00:47.880
In this example, we want to remove elements which are exactly divisible by 3, and keep the rest.

00:48.900 --> 00:54.900
The return value will be an iterator, again, to the first [removed] value, and we can pass that as a argument

00:54.900 --> 00:55.770
to erase().

00:56.730 --> 00:58.440
So here is some code.

00:58.440 --> 00:59.490
We have our vector.

01:01.320 --> 01:06.090
We have the call to remove_if(), with the callable object as the third argument.

01:07.740 --> 01:13.920
Then we have the iterator as the return value. And then we call erase(), using that iterator.

01:18.410 --> 01:24.170
So we get a result in which the elements 3 and 9 have been removed, because they are divisible

01:24.170 --> 01:24.800
by 3.

01:25.100 --> 01:26.240
But the others have been kept.

01:28.250 --> 01:35.390
remove_copy() will write the results to a destination. It will write the data from this is iterator range

01:35.600 --> 01:40.220
into this destination, but it will omit any elements which have this value.

01:40.820 --> 01:46.700
So this will populate "vec2" with all these elements, except for the ones which have the value 1.

01:47.240 --> 01:53.060
If you remember the copy_if() algorithm, we could get that to do the same thing by copying all the

01:53.060 --> 01:54.680
elements which are not equal to 1.

01:55.190 --> 02:00.740
So these two are the same, but with the logic inverted. In this one, we say that 1 is the value we

02:00.740 --> 02:03.260
do not want to copy. In this.

02:03.590 --> 02:07.520
we say that anything except 1 is the value that we want to copy.

02:09.520 --> 02:13.120
So let's try this out. We have our call to remove_copy().

02:13.840 --> 02:17.110
So this will remove the elements with the value 1.

02:17.770 --> 02:19.390
Then we have the equivalenct code with copy_if()

02:19.390 --> 02:22.950
So this will copy everything except the elements with value 1.

02:25.810 --> 02:26.950
So let's see what we get.

02:27.310 --> 02:32.020
So the new vector has those elements, without the elements with value one.

02:35.960 --> 02:38.720
And there is also remove_copy_if() which combines both these.

02:39.130 --> 02:45.200
It will take a lambda expression and do a copy of all the elements for which the expression is [true].

02:47.260 --> 02:51.220
So that would give us a container in which the elements are, 1, 4, 1, 5.

02:55.040 --> 02:57.500
So here is our call to remove_copy_if().

02:59.940 --> 03:06.000
There is the lambda expression. And there is the equivalent code using copy_if().

03:10.310 --> 03:15.260
So this will populate the container with all the elements which are not exactly divisible by 3.

03:18.960 --> 03:21.120
The other main algorithm is unique().

03:21.360 --> 03:24.810
This will remove duplicate elements, but they have to be adjacent.

03:25.350 --> 03:30.810
So this means that the elements in the iterator range must be sorted. Otherwise, unique() will not work properly.

03:31.470 --> 03:37.140
This has the similar behaviour, in that elements are only "logically" removed from the container and not physically

03:37.140 --> 03:37.590
removed.

03:38.220 --> 03:42.570
If we wants to physically remove them, we pass the returned iterartor to erase().

03:46.090 --> 03:48.220
So we have code like this. We have our vector.

03:49.090 --> 03:58.720
We sort it, and then we call unique(). We get an iterator to the first removed element, and then

03:58.720 --> 04:00.010
we pass that to erase().

04:03.260 --> 04:04.760
So there is our original vector.

04:05.060 --> 04:10.430
There is the sorted vector. It has an adjacent duplicates element, so that gets moved to the back

04:10.430 --> 04:11.030
of the container.

04:11.690 --> 04:14.660
And then we call erase(), and that element is destroyed.

04:15.470 --> 04:21.140
So the result is the elements, in order, without the duplicate elements with value 1.

04:26.520 --> 04:32.910
Unique uses the equality operator. We can also provide our own predicate for deciding what constitutes

04:32.910 --> 04:34.230
being a duplicate.

04:35.850 --> 04:41.040
The predicate will take 2 arguments, which correspond to successive elements. So this could be,

04:41.040 --> 04:44.460
for example, the first and second, or the second and third elements in the container.

04:45.480 --> 04:49.620
And in this case, we want to remove elements which differ by one.

04:50.040 --> 04:55.050
So if we have 3, followed by 4, then we want to remove the elements with value 4.

05:00.370 --> 05:02.410
So there is our call to unique().

05:03.460 --> 05:05.140
Again, we have sorted the vector.

05:05.530 --> 05:06.130
(Do not forget that!)

05:07.300 --> 05:12.400
So we call unique with our predicate, and then we call erase() on the return value.

05:13.000 --> 05:14.410
So what do you think we will get?

05:17.090 --> 05:18.710
(Just go back to our original vector.)

05:21.380 --> 05:26.510
So there is our original version: there it is, sorted. 1 is followed by 1, which is not more than 1.

05:27.140 --> 05:33.560
1 is followed by 3, which is not one more than 1. 3 is followed by 1, which is one more

05:33.560 --> 05:34.850
than 3.

05:35.150 --> 05:40.550
So 4 gets moved to the end of the container and now 3 is followed by 5, which is not one

05:40.550 --> 05:40.840
more.

05:41.210 --> 05:43.190
And 5 is followed by 9, which is not one more.

05:43.610 --> 05:45.800
So this will only remove the element with value

05:45.800 --> 05:46.160
4.

05:46.460 --> 05:48.140
It keeps the elements with value 5.

05:51.810 --> 05:55.350
And again, we have the _copy version, which writes the result to a destination.

05:55.920 --> 05:59.040
So this will do the copy, but omit any duplicate elements.

06:01.170 --> 06:03.570
And we can also call it with a predicate.

06:07.410 --> 06:09.510
So here is the unique copy version.

06:14.540 --> 06:17.480
So this just copies the result, without the duplicate value 1.

06:19.760 --> 06:22.070
And this is the version with the predicate.

06:23.730 --> 06:27.240
So this will populate a new container with the result that we had before.

06:27.960 --> 06:29.640
Okay, so that is it for this video.

06:30.000 --> 06:32.850
I will see you next time, but until then, keep coding!
