#include <iostream>
#include <vector>
usingnamespace std;
//Pre: v1 and v2 are sorted vectors
//Post: returns the elements of v1 that are not in v2
vector<double> difference(const vector<double>& v1, const vector<double>& v2) {
vector<double> v3(v1.size());
int i, j, k;
i = j = k = 0;
while (i < v1.size() and j < v2.size()) {
if (v1[i] == v2[j]) ++i;
elseif (v1[i] > v2[j]) ++j;
else {
v3[k] = v1[i]; ++i; ++k;
}
}
while (i < v1.size()) {
v3[k] = v1[i]; ++i; ++k;
}
vector <double> Res(k);
for (i = 0; i < k; ++i) Res[i] = v3[i];
return Res;
}
Do you mean by "not allowed" that you cannot call the std::set_difference, or also that you cannot study at all the logic of the code examples that could implement std::set_difference?
However, if you would not be allowed to use these library algorithms directly, you would look at the example implementations of both std::set_difference and std::unique, and rewrite them fused, with your original index style, rather than the interator/pointer style that the examples use.
#include <iostream>
#include <vector>
usingnamespace std;
//Pre: v1 and v2 are sorted vectors
//Post: returns the elements of v1 that are not in v2
vector<double> difference(const vector<double>& v1, const vector<double>& v2) {
//eliminate all duplicates of v1
vector<double> va;
va.push_back(v1[0]);
for (int i = 1; i < v1.size(); ++i) {
if (v1[i-1] != v1[i]) va.push_back(v1[i]);
}
//eliminate all duplicates of v1
vector<double> vb;
vb.push_back(v2[0]);
for (int i = 1; i < v2.size(); ++i) {
if (v2[i-1] != v2[i]) vb.push_back(v2[i]);
}
//in the worst case va and vb have no elements in common
vector<double> v3(va.size());
//i for va, j for vb, k for v3
int i, j, k;
i = j = k = 0;
//check which elements of va are not in vb and put them in v3
while (i < va.size() and j < vb.size()) {
if (va[i] == vb[j]) {
++i; ++j;
}
elseif (va[i] > vb[j]) ++j;
else {
v3[k] = va[i]; ++i; ++k;
}
}
//copy the remaining part of va which wasnt treated if there is any
while (i < va.size()) {
v3[k] = va[i];
++k;
++i;
}
//copying the result in the resultant vector Res
vector <double> Res;
for (i = 0; i < k; ++i) Res[i] = v3[i];
return Res;
}
Working with integers instead of floating point values would put the entire focus on the algorithm (avoid taling care of floating point comparisons and treatment of possible NaNs).
#include <vector>
usingnamespace std;
void push_back_if_unique( vector<int>& seq, int value )
{ if( seq.empty() || seq.back() < value ) seq.push_back(value) ; }
//Pre: first and second are sorted vectors
//Post: returns unique elements of first that are not in second
vector<int> difference( const vector<int>& first, const vector<int>& second )
{
vector<int> result ;
std::size_t i = 0 ; // position in first
std::size_t j = 0 ; // position in second
while( i < first.size() )
{
if( j == second.size() ) // nothing more in second
{
for( ; i < first.size() ; ++i ) push_back_if_unique( result, first[i] ) ;
return result ;
}
if( first[i] > second[j] ) ++j ;
else
{
if( first[i] < second[j] ) push_back_if_unique( result, first[i] ) ;
++i ;
}
}
return result ;
}