Intersection of two sorted vectors in C++A pointer vector sorted by its member functionShould I call a method (i.e. size()) multiple times or store it (if I know the value will not change)Is this implementation of Quicksort good?Computing intersection of 2D infinite linesMerge two already sorted linked listPlace integers into a vector, sum each adjacent pair, refill vector with only the sums of each pair i.e remove all the original data from the vectorMerge two sorted lists of numbersFinding the lowest missing integer in a vector containing negative and positive valuesDemonstration of Scale BalancingType-safe Euclidean vectors in C++
Is it possible to run Internet Explorer on OS X El Capitan?
Malcev's paper "On a class of homogeneous spaces" in English
How can I prevent hyper evolved versions of regular creatures from wiping out their cousins?
Replacing matching entries in one column of a file by another column from a different file
Important Resources for Dark Age Civilizations?
Meaning of に in 本当に
How do I deal with an unproductive colleague in a small company?
Why can't I see bouncing of a switch on an oscilloscope?
Why is consensus so controversial in Britain?
Codimension of non-flat locus
Modeling an IP Address
Perform and show arithmetic with LuaLaTeX
Why doesn't H₄O²⁺ exist?
How much RAM could one put in a typical 80386 setup?
Languages that we cannot (dis)prove to be Context-Free
How old can references or sources in a thesis be?
Alternative to sending password over mail?
RSA: Danger of using p to create q
Watching something be written to a file live with tail
How is it possible to have an ability score that is less than 3?
Can I ask the recruiters in my resume to put the reason why I am rejected?
"You are your self first supporter", a more proper way to say it
Why are electrically insulating heatsinks so rare? Is it just cost?
What is the word for reserving something for yourself before others do?
Intersection of two sorted vectors in C++
A pointer vector sorted by its member functionShould I call a method (i.e. size()) multiple times or store it (if I know the value will not change)Is this implementation of Quicksort good?Computing intersection of 2D infinite linesMerge two already sorted linked listPlace integers into a vector, sum each adjacent pair, refill vector with only the sums of each pair i.e remove all the original data from the vectorMerge two sorted lists of numbersFinding the lowest missing integer in a vector containing negative and positive valuesDemonstration of Scale BalancingType-safe Euclidean vectors in C++
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
$begingroup$
Intersection of two sorted vectors in C++ - can this be written any better?
vector<int> intersection(vector<int>& nums1, vector<int>& nums2)
vector<int> result;
int l = 0, r = 0;
while(l < nums1.size() && r < nums2.size())
int left = nums1[l], right = nums2[r];
if(left == right)
result.push_back(right);
while(l < nums1.size() && nums1[l] == left )l++;
while(r < nums2.size() && nums2[r] == right )r++;
continue;
if(left < right)
while(l < nums1.size() && nums1[l] == left )l++;
else while( r < nums2.size() && nums2[r] == right )r++;
return result;
c++ reinventing-the-wheel
$endgroup$
add a comment |
$begingroup$
Intersection of two sorted vectors in C++ - can this be written any better?
vector<int> intersection(vector<int>& nums1, vector<int>& nums2)
vector<int> result;
int l = 0, r = 0;
while(l < nums1.size() && r < nums2.size())
int left = nums1[l], right = nums2[r];
if(left == right)
result.push_back(right);
while(l < nums1.size() && nums1[l] == left )l++;
while(r < nums2.size() && nums2[r] == right )r++;
continue;
if(left < right)
while(l < nums1.size() && nums1[l] == left )l++;
else while( r < nums2.size() && nums2[r] == right )r++;
return result;
c++ reinventing-the-wheel
$endgroup$
5
$begingroup$
Do you know aboutstd::set_intersection()
? Reference and example implementations: en.cppreference.com/w/cpp/algorithm/set_intersection
$endgroup$
– user673679
yesterday
3
$begingroup$
@user673679 yes I did, and didn't want to use it;
$endgroup$
– Rick
yesterday
add a comment |
$begingroup$
Intersection of two sorted vectors in C++ - can this be written any better?
vector<int> intersection(vector<int>& nums1, vector<int>& nums2)
vector<int> result;
int l = 0, r = 0;
while(l < nums1.size() && r < nums2.size())
int left = nums1[l], right = nums2[r];
if(left == right)
result.push_back(right);
while(l < nums1.size() && nums1[l] == left )l++;
while(r < nums2.size() && nums2[r] == right )r++;
continue;
if(left < right)
while(l < nums1.size() && nums1[l] == left )l++;
else while( r < nums2.size() && nums2[r] == right )r++;
return result;
c++ reinventing-the-wheel
$endgroup$
Intersection of two sorted vectors in C++ - can this be written any better?
vector<int> intersection(vector<int>& nums1, vector<int>& nums2)
vector<int> result;
int l = 0, r = 0;
while(l < nums1.size() && r < nums2.size())
int left = nums1[l], right = nums2[r];
if(left == right)
result.push_back(right);
while(l < nums1.size() && nums1[l] == left )l++;
while(r < nums2.size() && nums2[r] == right )r++;
continue;
if(left < right)
while(l < nums1.size() && nums1[l] == left )l++;
else while( r < nums2.size() && nums2[r] == right )r++;
return result;
c++ reinventing-the-wheel
c++ reinventing-the-wheel
edited yesterday
Peter Mortensen
25417
25417
asked yesterday
RickRick
316112
316112
5
$begingroup$
Do you know aboutstd::set_intersection()
? Reference and example implementations: en.cppreference.com/w/cpp/algorithm/set_intersection
$endgroup$
– user673679
yesterday
3
$begingroup$
@user673679 yes I did, and didn't want to use it;
$endgroup$
– Rick
yesterday
add a comment |
5
$begingroup$
Do you know aboutstd::set_intersection()
? Reference and example implementations: en.cppreference.com/w/cpp/algorithm/set_intersection
$endgroup$
– user673679
yesterday
3
$begingroup$
@user673679 yes I did, and didn't want to use it;
$endgroup$
– Rick
yesterday
5
5
$begingroup$
Do you know about
std::set_intersection()
? Reference and example implementations: en.cppreference.com/w/cpp/algorithm/set_intersection$endgroup$
– user673679
yesterday
$begingroup$
Do you know about
std::set_intersection()
? Reference and example implementations: en.cppreference.com/w/cpp/algorithm/set_intersection$endgroup$
– user673679
yesterday
3
3
$begingroup$
@user673679 yes I did, and didn't want to use it;
$endgroup$
– Rick
yesterday
$begingroup$
@user673679 yes I did, and didn't want to use it;
$endgroup$
– Rick
yesterday
add a comment |
2 Answers
2
active
oldest
votes
$begingroup$
Indentation
Your indentation is not consistent. This makes the code hard to read and maintain. It should be fixed so you don't give other people headaches.
if(left < right)
while(l < nums1.size() && nums1[l] == left )l++;
else while( r < nums2.size() && nums2[r] == right )r++;That is basically unreadable giberish (opinion of Martin).
Using namespace
std;
is super badThis is mention in nearly every C++ review. There is a large article on the subject here: Why is “using namespace std” considered bad practice?. The second answer is the best in my opinion (Martin) see
Multiple declarations in one is bad (thanks to terrible syntax binding rules)
The one declaration per line has been written about adnausium in best practice guides. Please for the sake of your reader declare one variable per line with its own exact type.
The syntax binding rules alluded to above is:
int* x, y; // Here x is int* and y in int
// confusing to a reader. Did you really mean to make y an int?
// Avoid this problem be declaring one variable per lineTypically, functions like this would be based on iterators to work on any container
Here your code is limited to only using vectors. But the algorithm you are using could be used by any container type with only small modifications. As a result your function could provide much more utility being written to use iterators.
The standard library was written such that iterators are the glue between algorithms and container.
It would be a lot simpler, if not necessarily more efficient at runtime, to just use some hash sets.
- This function could be generic in T rather than assuming
int
. - The repeated conditions make me feel like there's simplification waiting here, although exactly what that is eludes me in the two minutes I'm spending on this.
- Should take by
const
ref, not ref, so that you can operate on temporaries.
$endgroup$
1
$begingroup$
You caught the problems and I voted you up, but you could improve your answer by explaining what the issue for the first 4 bullet items.
$endgroup$
– pacmaninbw
yesterday
2
$begingroup$
@pacmaninbw: Added some context.
$endgroup$
– Martin York
yesterday
$begingroup$
@MartinYork wow! whose answer is it, anyway? :) :) /intended in a positive way/
$endgroup$
– Will Ness
21 hours ago
add a comment |
$begingroup$
I invite you to review @DeadMG's answer.
Rewriting following (most of) his advice, you'd get something like:
#include <cassert>
#include <algorithm>
#include <vector>
std::vector<T> intersection(std::vector<T> const& left_vector, std::vector<T> const& right_vector)
auto left = left_vector.begin();
auto left_end = left_vector.end();
auto right = right_vector.begin();
auto right_end = right_vector.end();
assert(std::is_sorted(left, left_end));
assert(std::is_sorted(right, right_end));
std::vector<T> result;
while (left != left_end && right != right_end)
if (*left == *right)
result.push_back(*left);
++left;
++right;
continue;
if (*left < *right)
++left;
continue;
assert(*left > *right);
++right;
return result;
I've always found taking pairs of iterators awkward, so I would not recommend such an interface. Instead, you could take simply take any "iterable", they need not even have the same value type, so long as they are comparable:
template <typename Left, typename Right>
std::vector<typename Left::value_type> intersection(Left const& left_c, Right const& right_c);
Also, note that I've included some assert
to validate the pre-conditions of the methods (the collections must be sorted) as well as internal invariants (if *left
is neither equal nor strictly less than *right
then it must be strictly greater).
I encourage you to use assert
liberally:
- They document intentions: pre-conditions, invariants, etc...
- They check that those intentions hold.
Documentation & Bug detection rolled in one, with no run-time (Release) cost.
$endgroup$
1
$begingroup$
Why don't you post that as its own questions. There are some improvements even if we don't move to iterators like using template template types.
$endgroup$
– Martin York
yesterday
1
$begingroup$
@MartinYork: I generally don't find "template template" to be an improvement, they're quite awkward to use, and tend to constrain the inputs more than intended.
$endgroup$
– Matthieu M.
yesterday
$begingroup$
@MatthieuM. You should reconsider the solution you posted.
$endgroup$
– Rick
yesterday
1
$begingroup$
@Rick: Please elaborate?
$endgroup$
– Matthieu M.
22 hours ago
$begingroup$
Accepting iterable types is a good idea, and certainly the direction of modern C++ (Ranges, etc). If I were writing it, I'd probably provide the iterator-pair interface for the rare occasions that the caller needs more control, and provide the range interface as a thin adapter. Also, consider the Standard Library pattern of passing an output iterator - that can similarly be wrapped with an adaptor if a vector result is needed.
$endgroup$
– Toby Speight
21 hours ago
|
show 2 more comments
Your Answer
StackExchange.ifUsing("editor", function ()
return StackExchange.using("mathjaxEditing", function ()
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
);
);
, "mathjax-editing");
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f216861%2fintersection-of-two-sorted-vectors-in-c%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
$begingroup$
Indentation
Your indentation is not consistent. This makes the code hard to read and maintain. It should be fixed so you don't give other people headaches.
if(left < right)
while(l < nums1.size() && nums1[l] == left )l++;
else while( r < nums2.size() && nums2[r] == right )r++;That is basically unreadable giberish (opinion of Martin).
Using namespace
std;
is super badThis is mention in nearly every C++ review. There is a large article on the subject here: Why is “using namespace std” considered bad practice?. The second answer is the best in my opinion (Martin) see
Multiple declarations in one is bad (thanks to terrible syntax binding rules)
The one declaration per line has been written about adnausium in best practice guides. Please for the sake of your reader declare one variable per line with its own exact type.
The syntax binding rules alluded to above is:
int* x, y; // Here x is int* and y in int
// confusing to a reader. Did you really mean to make y an int?
// Avoid this problem be declaring one variable per lineTypically, functions like this would be based on iterators to work on any container
Here your code is limited to only using vectors. But the algorithm you are using could be used by any container type with only small modifications. As a result your function could provide much more utility being written to use iterators.
The standard library was written such that iterators are the glue between algorithms and container.
It would be a lot simpler, if not necessarily more efficient at runtime, to just use some hash sets.
- This function could be generic in T rather than assuming
int
. - The repeated conditions make me feel like there's simplification waiting here, although exactly what that is eludes me in the two minutes I'm spending on this.
- Should take by
const
ref, not ref, so that you can operate on temporaries.
$endgroup$
1
$begingroup$
You caught the problems and I voted you up, but you could improve your answer by explaining what the issue for the first 4 bullet items.
$endgroup$
– pacmaninbw
yesterday
2
$begingroup$
@pacmaninbw: Added some context.
$endgroup$
– Martin York
yesterday
$begingroup$
@MartinYork wow! whose answer is it, anyway? :) :) /intended in a positive way/
$endgroup$
– Will Ness
21 hours ago
add a comment |
$begingroup$
Indentation
Your indentation is not consistent. This makes the code hard to read and maintain. It should be fixed so you don't give other people headaches.
if(left < right)
while(l < nums1.size() && nums1[l] == left )l++;
else while( r < nums2.size() && nums2[r] == right )r++;That is basically unreadable giberish (opinion of Martin).
Using namespace
std;
is super badThis is mention in nearly every C++ review. There is a large article on the subject here: Why is “using namespace std” considered bad practice?. The second answer is the best in my opinion (Martin) see
Multiple declarations in one is bad (thanks to terrible syntax binding rules)
The one declaration per line has been written about adnausium in best practice guides. Please for the sake of your reader declare one variable per line with its own exact type.
The syntax binding rules alluded to above is:
int* x, y; // Here x is int* and y in int
// confusing to a reader. Did you really mean to make y an int?
// Avoid this problem be declaring one variable per lineTypically, functions like this would be based on iterators to work on any container
Here your code is limited to only using vectors. But the algorithm you are using could be used by any container type with only small modifications. As a result your function could provide much more utility being written to use iterators.
The standard library was written such that iterators are the glue between algorithms and container.
It would be a lot simpler, if not necessarily more efficient at runtime, to just use some hash sets.
- This function could be generic in T rather than assuming
int
. - The repeated conditions make me feel like there's simplification waiting here, although exactly what that is eludes me in the two minutes I'm spending on this.
- Should take by
const
ref, not ref, so that you can operate on temporaries.
$endgroup$
1
$begingroup$
You caught the problems and I voted you up, but you could improve your answer by explaining what the issue for the first 4 bullet items.
$endgroup$
– pacmaninbw
yesterday
2
$begingroup$
@pacmaninbw: Added some context.
$endgroup$
– Martin York
yesterday
$begingroup$
@MartinYork wow! whose answer is it, anyway? :) :) /intended in a positive way/
$endgroup$
– Will Ness
21 hours ago
add a comment |
$begingroup$
Indentation
Your indentation is not consistent. This makes the code hard to read and maintain. It should be fixed so you don't give other people headaches.
if(left < right)
while(l < nums1.size() && nums1[l] == left )l++;
else while( r < nums2.size() && nums2[r] == right )r++;That is basically unreadable giberish (opinion of Martin).
Using namespace
std;
is super badThis is mention in nearly every C++ review. There is a large article on the subject here: Why is “using namespace std” considered bad practice?. The second answer is the best in my opinion (Martin) see
Multiple declarations in one is bad (thanks to terrible syntax binding rules)
The one declaration per line has been written about adnausium in best practice guides. Please for the sake of your reader declare one variable per line with its own exact type.
The syntax binding rules alluded to above is:
int* x, y; // Here x is int* and y in int
// confusing to a reader. Did you really mean to make y an int?
// Avoid this problem be declaring one variable per lineTypically, functions like this would be based on iterators to work on any container
Here your code is limited to only using vectors. But the algorithm you are using could be used by any container type with only small modifications. As a result your function could provide much more utility being written to use iterators.
The standard library was written such that iterators are the glue between algorithms and container.
It would be a lot simpler, if not necessarily more efficient at runtime, to just use some hash sets.
- This function could be generic in T rather than assuming
int
. - The repeated conditions make me feel like there's simplification waiting here, although exactly what that is eludes me in the two minutes I'm spending on this.
- Should take by
const
ref, not ref, so that you can operate on temporaries.
$endgroup$
Indentation
Your indentation is not consistent. This makes the code hard to read and maintain. It should be fixed so you don't give other people headaches.
if(left < right)
while(l < nums1.size() && nums1[l] == left )l++;
else while( r < nums2.size() && nums2[r] == right )r++;That is basically unreadable giberish (opinion of Martin).
Using namespace
std;
is super badThis is mention in nearly every C++ review. There is a large article on the subject here: Why is “using namespace std” considered bad practice?. The second answer is the best in my opinion (Martin) see
Multiple declarations in one is bad (thanks to terrible syntax binding rules)
The one declaration per line has been written about adnausium in best practice guides. Please for the sake of your reader declare one variable per line with its own exact type.
The syntax binding rules alluded to above is:
int* x, y; // Here x is int* and y in int
// confusing to a reader. Did you really mean to make y an int?
// Avoid this problem be declaring one variable per lineTypically, functions like this would be based on iterators to work on any container
Here your code is limited to only using vectors. But the algorithm you are using could be used by any container type with only small modifications. As a result your function could provide much more utility being written to use iterators.
The standard library was written such that iterators are the glue between algorithms and container.
It would be a lot simpler, if not necessarily more efficient at runtime, to just use some hash sets.
- This function could be generic in T rather than assuming
int
. - The repeated conditions make me feel like there's simplification waiting here, although exactly what that is eludes me in the two minutes I'm spending on this.
- Should take by
const
ref, not ref, so that you can operate on temporaries.
edited yesterday
Peter Mortensen
25417
25417
answered yesterday
DeadMGDeadMG
769612
769612
1
$begingroup$
You caught the problems and I voted you up, but you could improve your answer by explaining what the issue for the first 4 bullet items.
$endgroup$
– pacmaninbw
yesterday
2
$begingroup$
@pacmaninbw: Added some context.
$endgroup$
– Martin York
yesterday
$begingroup$
@MartinYork wow! whose answer is it, anyway? :) :) /intended in a positive way/
$endgroup$
– Will Ness
21 hours ago
add a comment |
1
$begingroup$
You caught the problems and I voted you up, but you could improve your answer by explaining what the issue for the first 4 bullet items.
$endgroup$
– pacmaninbw
yesterday
2
$begingroup$
@pacmaninbw: Added some context.
$endgroup$
– Martin York
yesterday
$begingroup$
@MartinYork wow! whose answer is it, anyway? :) :) /intended in a positive way/
$endgroup$
– Will Ness
21 hours ago
1
1
$begingroup$
You caught the problems and I voted you up, but you could improve your answer by explaining what the issue for the first 4 bullet items.
$endgroup$
– pacmaninbw
yesterday
$begingroup$
You caught the problems and I voted you up, but you could improve your answer by explaining what the issue for the first 4 bullet items.
$endgroup$
– pacmaninbw
yesterday
2
2
$begingroup$
@pacmaninbw: Added some context.
$endgroup$
– Martin York
yesterday
$begingroup$
@pacmaninbw: Added some context.
$endgroup$
– Martin York
yesterday
$begingroup$
@MartinYork wow! whose answer is it, anyway? :) :) /intended in a positive way/
$endgroup$
– Will Ness
21 hours ago
$begingroup$
@MartinYork wow! whose answer is it, anyway? :) :) /intended in a positive way/
$endgroup$
– Will Ness
21 hours ago
add a comment |
$begingroup$
I invite you to review @DeadMG's answer.
Rewriting following (most of) his advice, you'd get something like:
#include <cassert>
#include <algorithm>
#include <vector>
std::vector<T> intersection(std::vector<T> const& left_vector, std::vector<T> const& right_vector)
auto left = left_vector.begin();
auto left_end = left_vector.end();
auto right = right_vector.begin();
auto right_end = right_vector.end();
assert(std::is_sorted(left, left_end));
assert(std::is_sorted(right, right_end));
std::vector<T> result;
while (left != left_end && right != right_end)
if (*left == *right)
result.push_back(*left);
++left;
++right;
continue;
if (*left < *right)
++left;
continue;
assert(*left > *right);
++right;
return result;
I've always found taking pairs of iterators awkward, so I would not recommend such an interface. Instead, you could take simply take any "iterable", they need not even have the same value type, so long as they are comparable:
template <typename Left, typename Right>
std::vector<typename Left::value_type> intersection(Left const& left_c, Right const& right_c);
Also, note that I've included some assert
to validate the pre-conditions of the methods (the collections must be sorted) as well as internal invariants (if *left
is neither equal nor strictly less than *right
then it must be strictly greater).
I encourage you to use assert
liberally:
- They document intentions: pre-conditions, invariants, etc...
- They check that those intentions hold.
Documentation & Bug detection rolled in one, with no run-time (Release) cost.
$endgroup$
1
$begingroup$
Why don't you post that as its own questions. There are some improvements even if we don't move to iterators like using template template types.
$endgroup$
– Martin York
yesterday
1
$begingroup$
@MartinYork: I generally don't find "template template" to be an improvement, they're quite awkward to use, and tend to constrain the inputs more than intended.
$endgroup$
– Matthieu M.
yesterday
$begingroup$
@MatthieuM. You should reconsider the solution you posted.
$endgroup$
– Rick
yesterday
1
$begingroup$
@Rick: Please elaborate?
$endgroup$
– Matthieu M.
22 hours ago
$begingroup$
Accepting iterable types is a good idea, and certainly the direction of modern C++ (Ranges, etc). If I were writing it, I'd probably provide the iterator-pair interface for the rare occasions that the caller needs more control, and provide the range interface as a thin adapter. Also, consider the Standard Library pattern of passing an output iterator - that can similarly be wrapped with an adaptor if a vector result is needed.
$endgroup$
– Toby Speight
21 hours ago
|
show 2 more comments
$begingroup$
I invite you to review @DeadMG's answer.
Rewriting following (most of) his advice, you'd get something like:
#include <cassert>
#include <algorithm>
#include <vector>
std::vector<T> intersection(std::vector<T> const& left_vector, std::vector<T> const& right_vector)
auto left = left_vector.begin();
auto left_end = left_vector.end();
auto right = right_vector.begin();
auto right_end = right_vector.end();
assert(std::is_sorted(left, left_end));
assert(std::is_sorted(right, right_end));
std::vector<T> result;
while (left != left_end && right != right_end)
if (*left == *right)
result.push_back(*left);
++left;
++right;
continue;
if (*left < *right)
++left;
continue;
assert(*left > *right);
++right;
return result;
I've always found taking pairs of iterators awkward, so I would not recommend such an interface. Instead, you could take simply take any "iterable", they need not even have the same value type, so long as they are comparable:
template <typename Left, typename Right>
std::vector<typename Left::value_type> intersection(Left const& left_c, Right const& right_c);
Also, note that I've included some assert
to validate the pre-conditions of the methods (the collections must be sorted) as well as internal invariants (if *left
is neither equal nor strictly less than *right
then it must be strictly greater).
I encourage you to use assert
liberally:
- They document intentions: pre-conditions, invariants, etc...
- They check that those intentions hold.
Documentation & Bug detection rolled in one, with no run-time (Release) cost.
$endgroup$
1
$begingroup$
Why don't you post that as its own questions. There are some improvements even if we don't move to iterators like using template template types.
$endgroup$
– Martin York
yesterday
1
$begingroup$
@MartinYork: I generally don't find "template template" to be an improvement, they're quite awkward to use, and tend to constrain the inputs more than intended.
$endgroup$
– Matthieu M.
yesterday
$begingroup$
@MatthieuM. You should reconsider the solution you posted.
$endgroup$
– Rick
yesterday
1
$begingroup$
@Rick: Please elaborate?
$endgroup$
– Matthieu M.
22 hours ago
$begingroup$
Accepting iterable types is a good idea, and certainly the direction of modern C++ (Ranges, etc). If I were writing it, I'd probably provide the iterator-pair interface for the rare occasions that the caller needs more control, and provide the range interface as a thin adapter. Also, consider the Standard Library pattern of passing an output iterator - that can similarly be wrapped with an adaptor if a vector result is needed.
$endgroup$
– Toby Speight
21 hours ago
|
show 2 more comments
$begingroup$
I invite you to review @DeadMG's answer.
Rewriting following (most of) his advice, you'd get something like:
#include <cassert>
#include <algorithm>
#include <vector>
std::vector<T> intersection(std::vector<T> const& left_vector, std::vector<T> const& right_vector)
auto left = left_vector.begin();
auto left_end = left_vector.end();
auto right = right_vector.begin();
auto right_end = right_vector.end();
assert(std::is_sorted(left, left_end));
assert(std::is_sorted(right, right_end));
std::vector<T> result;
while (left != left_end && right != right_end)
if (*left == *right)
result.push_back(*left);
++left;
++right;
continue;
if (*left < *right)
++left;
continue;
assert(*left > *right);
++right;
return result;
I've always found taking pairs of iterators awkward, so I would not recommend such an interface. Instead, you could take simply take any "iterable", they need not even have the same value type, so long as they are comparable:
template <typename Left, typename Right>
std::vector<typename Left::value_type> intersection(Left const& left_c, Right const& right_c);
Also, note that I've included some assert
to validate the pre-conditions of the methods (the collections must be sorted) as well as internal invariants (if *left
is neither equal nor strictly less than *right
then it must be strictly greater).
I encourage you to use assert
liberally:
- They document intentions: pre-conditions, invariants, etc...
- They check that those intentions hold.
Documentation & Bug detection rolled in one, with no run-time (Release) cost.
$endgroup$
I invite you to review @DeadMG's answer.
Rewriting following (most of) his advice, you'd get something like:
#include <cassert>
#include <algorithm>
#include <vector>
std::vector<T> intersection(std::vector<T> const& left_vector, std::vector<T> const& right_vector)
auto left = left_vector.begin();
auto left_end = left_vector.end();
auto right = right_vector.begin();
auto right_end = right_vector.end();
assert(std::is_sorted(left, left_end));
assert(std::is_sorted(right, right_end));
std::vector<T> result;
while (left != left_end && right != right_end)
if (*left == *right)
result.push_back(*left);
++left;
++right;
continue;
if (*left < *right)
++left;
continue;
assert(*left > *right);
++right;
return result;
I've always found taking pairs of iterators awkward, so I would not recommend such an interface. Instead, you could take simply take any "iterable", they need not even have the same value type, so long as they are comparable:
template <typename Left, typename Right>
std::vector<typename Left::value_type> intersection(Left const& left_c, Right const& right_c);
Also, note that I've included some assert
to validate the pre-conditions of the methods (the collections must be sorted) as well as internal invariants (if *left
is neither equal nor strictly less than *right
then it must be strictly greater).
I encourage you to use assert
liberally:
- They document intentions: pre-conditions, invariants, etc...
- They check that those intentions hold.
Documentation & Bug detection rolled in one, with no run-time (Release) cost.
answered yesterday
Matthieu M.Matthieu M.
2,1871810
2,1871810
1
$begingroup$
Why don't you post that as its own questions. There are some improvements even if we don't move to iterators like using template template types.
$endgroup$
– Martin York
yesterday
1
$begingroup$
@MartinYork: I generally don't find "template template" to be an improvement, they're quite awkward to use, and tend to constrain the inputs more than intended.
$endgroup$
– Matthieu M.
yesterday
$begingroup$
@MatthieuM. You should reconsider the solution you posted.
$endgroup$
– Rick
yesterday
1
$begingroup$
@Rick: Please elaborate?
$endgroup$
– Matthieu M.
22 hours ago
$begingroup$
Accepting iterable types is a good idea, and certainly the direction of modern C++ (Ranges, etc). If I were writing it, I'd probably provide the iterator-pair interface for the rare occasions that the caller needs more control, and provide the range interface as a thin adapter. Also, consider the Standard Library pattern of passing an output iterator - that can similarly be wrapped with an adaptor if a vector result is needed.
$endgroup$
– Toby Speight
21 hours ago
|
show 2 more comments
1
$begingroup$
Why don't you post that as its own questions. There are some improvements even if we don't move to iterators like using template template types.
$endgroup$
– Martin York
yesterday
1
$begingroup$
@MartinYork: I generally don't find "template template" to be an improvement, they're quite awkward to use, and tend to constrain the inputs more than intended.
$endgroup$
– Matthieu M.
yesterday
$begingroup$
@MatthieuM. You should reconsider the solution you posted.
$endgroup$
– Rick
yesterday
1
$begingroup$
@Rick: Please elaborate?
$endgroup$
– Matthieu M.
22 hours ago
$begingroup$
Accepting iterable types is a good idea, and certainly the direction of modern C++ (Ranges, etc). If I were writing it, I'd probably provide the iterator-pair interface for the rare occasions that the caller needs more control, and provide the range interface as a thin adapter. Also, consider the Standard Library pattern of passing an output iterator - that can similarly be wrapped with an adaptor if a vector result is needed.
$endgroup$
– Toby Speight
21 hours ago
1
1
$begingroup$
Why don't you post that as its own questions. There are some improvements even if we don't move to iterators like using template template types.
$endgroup$
– Martin York
yesterday
$begingroup$
Why don't you post that as its own questions. There are some improvements even if we don't move to iterators like using template template types.
$endgroup$
– Martin York
yesterday
1
1
$begingroup$
@MartinYork: I generally don't find "template template" to be an improvement, they're quite awkward to use, and tend to constrain the inputs more than intended.
$endgroup$
– Matthieu M.
yesterday
$begingroup$
@MartinYork: I generally don't find "template template" to be an improvement, they're quite awkward to use, and tend to constrain the inputs more than intended.
$endgroup$
– Matthieu M.
yesterday
$begingroup$
@MatthieuM. You should reconsider the solution you posted.
$endgroup$
– Rick
yesterday
$begingroup$
@MatthieuM. You should reconsider the solution you posted.
$endgroup$
– Rick
yesterday
1
1
$begingroup$
@Rick: Please elaborate?
$endgroup$
– Matthieu M.
22 hours ago
$begingroup$
@Rick: Please elaborate?
$endgroup$
– Matthieu M.
22 hours ago
$begingroup$
Accepting iterable types is a good idea, and certainly the direction of modern C++ (Ranges, etc). If I were writing it, I'd probably provide the iterator-pair interface for the rare occasions that the caller needs more control, and provide the range interface as a thin adapter. Also, consider the Standard Library pattern of passing an output iterator - that can similarly be wrapped with an adaptor if a vector result is needed.
$endgroup$
– Toby Speight
21 hours ago
$begingroup$
Accepting iterable types is a good idea, and certainly the direction of modern C++ (Ranges, etc). If I were writing it, I'd probably provide the iterator-pair interface for the rare occasions that the caller needs more control, and provide the range interface as a thin adapter. Also, consider the Standard Library pattern of passing an output iterator - that can similarly be wrapped with an adaptor if a vector result is needed.
$endgroup$
– Toby Speight
21 hours ago
|
show 2 more comments
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f216861%2fintersection-of-two-sorted-vectors-in-c%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
5
$begingroup$
Do you know about
std::set_intersection()
? Reference and example implementations: en.cppreference.com/w/cpp/algorithm/set_intersection$endgroup$
– user673679
yesterday
3
$begingroup$
@user673679 yes I did, and didn't want to use it;
$endgroup$
– Rick
yesterday