Lab 02
Here is a pdf version of the ppt I covered during the lab. And the codes that I (skimmed through) / (demonstrated live).
content.pdf (The pdf version of the ppt shown)
binary_search.cpp (Implementing binary search ourselver)
stl_binary_search.cpp (Using STL algorithms default implementation of binary search)
set_intersection.cpp (Implementing set intersection using our own binary search method)
throwns.cpp (Solution to this problem)
Apart from all this I would like you all to go through these function below for many different use cases -
binary_search (This function assumes the vector/array to be already sorted)
lower_bound (Assumes vector to be sorted. Also see upper_bound)
unique (Returns a iterator/pointer to the end of the resulting vector, see example for clarity)
set_intersection (In the example given, this function uses back_inserter())
set_union (Similar to above one)
tuple (See the example here, highlights are - can use auto to make_tuple() and can also do get<data_type> if ensured that there is only entry in the tuple having data_type)
Challenge Questions -
Q) Given an already sorted vector V and a target variable Z in input, check if there exists 2 elements in v, such that x + y = z, where x and y both belong to V. This should be done in O(n) (Do note - The vector in this case is sorted already in input)
Solution
// Let the vector be V and the target be Z. Assuming V to be sorted.
int l = 0;
for(int r = (int)V.size() - 1; r >= 0; r--) {
while(V[l] + V[r] < z and l + 1 < r) l++;
if(V[l] + V[r] == z) {
cout<<"Found --> "<<V[l]<<" "<<V[r]<<endl;
break;
}
}
// The broad idea is to have 2 pointers, one on the left most
// side of the vector and the other on the right most side.
// Now slowly move the right pointer leftwards, i.e decrement
// its postion by -1. While you are moving it to the left you
// will realise that the net sum of A[l] + A[r] would decrease,
// because A[r] < A[r + 1], so to again up this value close
// to Z, you move l pointer forward, i.e increment it.
Q) Try to do set_union for 2 already sorted vectors A and B in O(n) using a 2-pointer style approach. (Will resemble to the merge operation in a merge sort) Update - 2 pointer approach basically means avoid using set_union and set_intersection
Solution
// Assuming I have vector A<> and vector B<> sorted.
int l1 = 0, l2 = 0, top = -1;
// top denotes the current top value in the res vector.
// I am assuming that both the vectors will NOT contain any -1.
// -1 is a sentinel value used to make the code shorter.
vector&l;int&rt; res; //The vector which will have the union result.
while(l1 < (int)A.size() or l2 < (int)B.size()) {
if(l1 == (int)A.size()) {
if(B[l2] != top) res.push_back(B[l2]), top = B[l2];
l2++;
}
else if(l2 == (int)B.size()) {
if(A[l1] != top) res.push_back(A[l1]), top = A[l1];
l1++;
}
else {
if(A[l1] <= B[l2]) {
if(A[l1] != top) res.push_back(A[l1]), top = A[l1];
l1++;
}
else {
if(B[l2] != top) res.push_back(B[l2]), top = B[l2];
l2++;
}
}
}
for(auto v : res) cout<<v<<" ";
cout<<endl;
// Here the broad idea is that you keep 2 pointers
// where you move the one which points to the smaller element
// and push it in the res vector if and only if the current
// element at the top of the res vector is different from the element
// being pushed. This ensured that an element is only pushed once.
// Therefore it is equivalent to a set_union.
// If you did NOT keep the top condition and just pushed it regardless of
// the current top, then this would be the code for the merge step in
// a merge-sort algorithm implementation.
Q) Sort a collection of names (represented as strings using only ‘a’ - ‘z’ without any spaces) first based on ascending length of the names, incase of ties, break the ties by descending order of the names themselves (Ex. {“abc”, “ab”, “xyz”} in sorted order will be {“ab”, “xyz”, “abc”})