jlb wrote: |
---|
Did you even read any documentation for that standard function? Short answer, no. For more information find and read some documentation. |
|
|
|
|
cont.erase(it)
, performance may not be a requirement, and overall using the naive approach is still super fast.
it
to the new iterator returned by erase.
|
|
|
|
jlb wrote: |
---|
Long answer is that it may be possible but it will take some work. You will need to either create a third vector and copy the elements of the other two vectors to the new vector (or if you won't need one of the two original vectors just append one vector into the other). Now once you have a vector that contains all the elements you will probably need to sort the vector before you try using std::unique. |
|
|
poteto wrote: |
---|
The most efficient way (from my point of view) of doing this would be to ignore what I said before and use the method that std::remove uses, its more complicated, and you have to rewrite it to use 2 ranges (the implementation is originally ~10 lines of code), the core logic is still the same you are just avoiding cont.erase(it), performance may not be a requirement, and overall using the naive approach is still super fast. |
mbozzi wrote: | ||
---|---|---|
<algorithm> is your friend here. The operation you're looking for is closely related to std::set_symmetric_difference. It yields elements corresponding to the disjunctive union of two sets: elements not in both. Unfortunately, that function will not solve the problem in one step because it only has one output range. You can compute v1 ∩ (v1 △ v2) and v2 ∩ (v1 △ v2); alternatively, compute v1 ⊖ (v1 ∩ v2) and v2 ⊖ (v1 ∩ v2). The latter approach is taken in the program below. Note that △ is the binary operation corresponding to the symmetric difference, and ∩ corresponds to set intersection:
http://coliru.stacked-crooked.com/a/7dba7692b7fd2528 |
std::begin(v1)
instead of v1.begin()
? I read on:4. To clarify, your program (for your first msg) does these steps (in order): a. Creates the two vectors and makes sure they are sorted. b. Prints the vector's original information. c. Creates a new vector called intersection and stores copies of all data from v1 and v2 that are in both vectors (such as 2). Note to self: '∩' means it is in both data sets. - This will check both vectors from step a for data that is the same (such as the 2 from both vectors). - Then it will copy the data that is the same in both vectors (such as 2) and store it in the intersection vector. * If there are multiple of the same number, it will add all of those to the intersection vector. For example, let's say in v1 there were {1, 2, 2, 2, 3, 4, 5}. Then in v2 there were {1}. Then the inersection vector would have {1, 1, 2, 2, 2} right? And it preserves the order. So it would NOT be: {2, 1, 2, 2, 1} for example. * Note: I'm reading https://gyazo.com/b63aec527009a8534860ade9edc3b496 from https://en.cppreference.com/w/cpp/algorithm/set_intersection. d. Then program will use set_difference() function to compare v1 with intersection vector. The function will: * Create a new vector called diff. * Copy all items from v1 that are NOT in intersection vector then stores it into diff vec. - It does the copy part with std::set_difference() and it does the storing info part with std::back_inserter(). https://en.cppreference.com/w/cpp/iterator/back_inserter * The purpose of std::back_inserter() is it's push_back() but allows adding multiple of the same number at once. Although for this program I don't see why you'd use it instead of push_back()? * Then function returns diff vector and prints result in main(). e. Does same as part d but for v2. |
I can't figure out why it's not working though. Do you know why it's not working? |
The input consists of a sequence of test cases. |
The first line of each test case contains two positive integers N and M, each at most one million, specifying the number of CDs owned by Jack and by Jill, respectively. |
void storeInputInVec(const unsigned int &numOfCDs, std::vector<unsigned int> &catalogOfCDs);
int countDuplicates(const int &jackCDCount, const std::vector<unsigned int> &catalog); // counts & returns number of CDs both Jack AND Jill have.
|
|
1. Why did you use std::begin(v1) instead of v1.begin()? |
3. Does ⊖ mean the numbers that are NOT in both vectors (so everything except 2)? |
2. Is there a reason to use this over the other, simpler, solutions mentioned by others? |
4. To clarify, your program (for your first msg) does these steps (in order) |
Edit: Now reading your second message and experiencing the "super difficult" part again. |
lastchance wrote: | ||
---|---|---|
|
mbozzi wrote: |
---|
Only because std::begin came to mind first. There's no reason to choose one over the other in this limited case. Yes, you got it. ⊖ means "set difference": a ⊖ b is the set of elements in a that are not in b, and v2 ⊖ (v1 ∩ v2) is the elements in v2 that are not in both v1 and v2. |
mbozzi wrote: |
---|
What are those other solutions? - I don't understand how @jlb's suggestion about std::unique can solve the original problem. - I basically implemented a variation on @poteto's "efficient" suggestion in my second post. - After that, the problem changed. |
mbozzi wrote: | |
---|---|
IMO, program 1 is a pretty clear description of intent behind some inscrutable syntax. The intent is: Step 1: Compute the elements in both (std::set_intersection) v1 and v2. Step 2: Compute the elements in v1 that are not in (set_difference) both v1 and v2. Step 3: Compute the elements in v2 that are not in (set_difference) both v1 and v2. Program 2 is an efficient approach: it will never allocate memory, and it only runs through the input data once. Contrast this to the program above, which does the same work more than once, and needs extra memory to store the set intersection (an intermediate result).
Roughly like this: <explanation> |
mbozzi wrote: | |
---|---|
It would be a good idea to study std::remove and std::set_intersection before trying to make sense of that. The idea is to run through both input ranges in a manner similar to std::set_intersection. Elements that belong to the intersection take the else clause and are "removed" as-if by the loop inside std::remove. Finally, when the end of any input range is reached, trailing elements are shifted zero or more spaces left with std::copy to finish-up. The result is a pair of iterators corresponding to the new ends of the sequences, just like std::remove. |
you mentioned it's not usually required to const reference PODs (Plain Old Date). The reference part makes sense and was something I had forgotten. However, the const part I'm wondering about because I read I should use const wherever possible on CPlusPlus.com (but I can't seem to find the link now). |
|
|
MikeyBoy wrote: |
---|
If you're not passing by reference, it's less important whether or not a function parameter is defined as const or not. Any changes the function makes to the value of that parameter are to a local copy within the function; they can't affect the value in the calling code. My opinion is that using const is still helpful to document that the function isn't supposed to change the value of that local copy - just as it would be useful to declare a local variable as const if it wasn't intended to be modified. IIRC, it's legal to define a variable as const in the definition of a function, but to leave out the const in the declaration. This fits with what I've said above - making the parameter const is only important in the internal workings of the function, but of no relevance to the calling code that needs the declaration, if the variable is passed by value. |
|
|
lastchance wrote: |
---|
Well you asked it to output the number of duplicates ... so it did! That's the 3. |