The vector is taking points to a rectangle. I want to be able to take the lowest and highest complex number and assigne it to 2 different complex numbers. I've only tried for the lowest with the below but it doesnt seem to find the lowest and just return the 1st element.
vector < complex<double>* > xs;
typedef typename vector < complex<double>* >::iterator Iter;
xs.push_back(&pointa);
xs.push_back(&pointb);
xs.push_back(&pointc);
xs.push_back(&pointd);
for (Iter p = xs.begin(); p != xs.end(); ++p)
{
if((*p)->real()<(*p+1)->real() && (*p)->imag()<(*p+1)->imag())
{
double a = (*p)->real();
double b = (*p)->imag();
complex <double> botleft_1(a,b);
}
else
{
}
}
Any suggestions?
The immediate bug in your code is that *p+1 means (*p)+1.
The next bug after you fix that to *(p+1) will be that you go one element off the end of the vector. You should be comparing each value with the lowest/highest so far, not with the next value in the vector.
There is in any case no such thing as the "lowest" or "highest" complex number - the complex numbers are not an ordered field (theorem). You can define any comparison operator you like on complex numbers, but it will be pretty arbitrary, for example it won't necessarily have ordered field properties such as a < b && c < d => a+c < b+d. The comparison you have defined does have that property, but is not a strict weak order, so it might not behave the way you expect once you start doing comparisons among 3 or more values.
For example, consider the values complex<double> a(1,1), b(0,3), c(2,2);, and the comparison function lt(complex<double> lhs, complex<double> rhs) { return lhs.real() < rhs.real() && lhs.imag() < rhs.imag(); }.
Then lt(a,b) and lt(b,a) are both false. This means a and b are equivalent as far as the ordering is concerned.
Likewise, lt(b,c) and lt(c,b) are both false. This means b and c are equivalent as far as the ordering is concerned.
However, lt(a,c) is true. This means a and c are not equivalent as far as the ordering is concerned.
In the loop you do not compare with the lowest number, only with next number. Try something like this:
complex<double> *lowest = *xs.begin();
for (Iter p = xs.begin() + 1; p != xs.end(); ++p){
if ((*p)->real() < lowest->real() && (*p)->imag() < lowest->imag())
lowest = *p;
}
After the loop, the variable lowest will have be the one you want.
Also, in your version of the loop, you compare to p + 1 which will be xs.end() on the last item, and that will not be a valid pointer.
Use boost::minmax_element
std::pair< Iter > pairit = boost::minmax_element( xs.begin(), xs.end(),
[&]( complex<double>* pcomplexA, complex<double>* pcomplexB ) {
// Suitable comparison predicate (see Steve Jessop's answer)
return pcomplexA->abs() < pcomplexB->abs(); // |a| < |b|
});
Related
Is there a way to change the precision of the predefined <= and < in the comparison between std::vector<double> vectors lexicographically ?
I am comparing between std::vector<double> vectors lexicographically in many places in my code, the scale of the first component (close to 0) is different from the scale of the other components (between -700 and 700). I want the precision to be 1e-6, i.e for two components a and b if abs(a-b)<=1e-6 then we consider a=b, where a, b are double.
Since I used <= and < in many places in the code, defining a new function that replaces <= and < to compare between vectors is risky (I make skip some vectors), so I am wondering if it is possible to change the precision of <= and < so this change will apply to all the comparisons directly.
An example of vectors I have: A=(-2.6666666666666936, 33497.435897435964, -300.51282051282101), B=(-2.6666666666666914, 17403.589743589808, -251.28205128205173), the result by using <=, is that A<=B because of the first component, but in my case, the first components are equal with (with epsilon=1e-6) so A>B.
There is no good way to change the precision of the operators.
I'd suggest you write your own function that iterates over the two vectors and does the comparisons directly. Something like:
bool approxLessThan(
const std::vector<double>& a,
const std::vector<double>& b,
double tolerance) {
// feel free to handle this differently
assert(a.size() == b.size());
for (size_t i =0; i < a.size(); i++) {
double dif = a[i] - b[i];
if (std::abs(dif) > tolerance)
return dif < 0.0; // change this to <= as needed
}
return false; // The vectors are "equal"
}
You can expand this to handle vectors of different sizes if needed.
I have a vector that holds a vector of points is a class that has an x and a y coordinate. I basically have to remove all the permutations and subsets from my vector. And to do that I making use of the algorithm includes and is_permutation
I have overloaded the '==' operator and it makes sense why we would need that. but those two algorithms do not work unless I overload '<' operator.
This is my point class:
class Point{
private:
int x;
int y;
public:
Point(){
x=0;
y=0;
}
Point(int xx, int yy){
x=xx;
y=yy;
}
double getSlope(Point p){
if(this->x!=p.x && this->y!=p.y){
return (double)(double(this->y-p.y)/double(this->x-p.x));
}else if(this->x==p.x){
return INT_MAX;
}else{
return INT_MIN;
}
}
void print(){
cout<<"(" <<x<<","<<y<<")";
}
bool operator == (Point &p){
if(this->x==p.x && this->y==p.y )
return true;
else
return false;
}
bool operator < (Point &p){
cout<<"\nin the < operator\n";
if(this->x < p.x && this->y < p.y )
return true;
else
return false;
}
};
and this is the function that takes in a temporary vector of points
and compares it with vector> to remove permutations.
The points are obtained from the file so as we're getting the points we only add it in vector> if they pass the check
bool check(PointVector temp, vector<PointVector> pointArrays ){
for(int i =0 ; i < pointArrays.size(); i++){
if(is_permutation(pointArrays[i].begin(),pointArrays[i].end(),temp.begin())){
return false;
}else if(includes(pointArrays[i].begin(),pointArrays[i].end(),temp.begin(),temp.end())){
return false;
}else if(includes(temp.begin(),temp.end(),pointArrays[i].begin(),pointArrays[i].end())){
pointArrays[i].swap(temp);
return false;
}
}
return true;
}
Point Vector is a typedef for vector<points>;
This is about std::includes, which imposes a requirement upon the input sequences to be sorted (according to the comparator - operator<).
Under this precondition, the algorithm could be implemented with operator== (with the semantics of not < and not >) and the same, linear asymptotic complexity.1 For the first range of length n and the second range of length m, we iterate the first range, each time comparing the element to the current element of the second range. On match, we increment the iterators to both ranges as usual. So, this is O(n+m) = O(n), because n < m => false. The problem is that if n > m and the result should be false, we must iterate the whole first range to see that (we cannot decide before checking n - m + 1 elements of the first range against the first element of the second range). The larger n - m is, the worse.
But with operator<, we can decide much sooner (more exactly never later), if we should return false from the algorithm, because we have read an element from the 2nd sequence that comes before the next one from the 1st sequence.
Example:
Is {1} a subrange of {2, ..., 106}?
operator==: 106 - 1 comparisons operator<: 1 comparison
Even the operator< version, however, still suffers in this example:
Is {106} a subrange of {1, ..., 106 - 1}?
operator==: 106 - 1 comparisons operator<: 106 - 1 comparisons
Then it is upon the programmer to choose the direction of iteration that is expected to yield shorter decision times.
Overall, algorithms that deal with ordered sequences work in terms of order comparisons, because they provide more insight into the input sequences.
1.
Without the sorted requirement (and with random-access iterators) for either range, the complexity would be higher (depending on the use of additional structures/presorting).
Recently I came across this code fragment:
// look for element which is the smallest max element from
// a given iterator
int diff = std::numeric_limits<int>::max();
auto it = nums.rbegin();
auto the_one = nums.rbegin();
for (; it != given; ++it) // this terminates
{
int local_diff = *it - *given;
// if the element is less than/equal to given we are not interested
if (local_diff <= 0)
continue;
if (local_diff < diff)
{
// this update the global diff
diff = local_diff;
the_one = it;
}
}
I was wondering if anyone can think of an elegant stl algorithm to replace the above. Essentially we have to go through all the elements, and also keep track of the one which we need. This is not similar to std::max_element (atleast I can't model it that way).
auto the_one = std::min_element(nums.rbegin(), given,
[given](int a, int b) {
bool good_a = a > *given;
bool good_b = b > *given;
return (good_a && good_b) ? a < b : good_a;
});
The trick is to write a comparison function that declares any "good" element (one that's greater than *given) to compare smaller than any "not good" element. Two "good" elements are compared normally; two "bad" elements are always declared equivalent.
I'm trying to iterate a vector from the nth element onwards. Not sure how should i go about doing this.
I have a vector A and B. My vector A has 10 elements of PC1-PC10 and my vector B has 20 elements of User1-User20.
So what I want to do is that when both my vector A and B reaches the 10th element, meaning to say the last element for vector A, I want to repeat iterating vector A but start iterating vector B from the 11th element so that I can do some stuff with it.
Below is the simplified code that I came up with but technically its about the same thing:
vector<string>::iterator b = vecB.begin();
for (int i = 1; i < 2; i++) {
for (vector<string>::iterator a = vecA.begin(); a != vecA.end() ; a++) {
if (a == vecA.end()) {
b = vecB.begin() + 10; //here the iterator for verB should start from the 11th element
}
++b
}
}
Should I mess with the iterator for vector B? Or is there another alternative?
EDIT
It seems that I have been asking the wrong question after all. I have marked the answer to this question and will be posting another shortly. Thanks for the quick response to my question!
The if condition inside the nested loop will never be true, because it conflicts with the loop condition:
for (vector<string>::iterator a = vecA.begin(); a != vecA.end() ; a++) {
// This check ----------------------------------^^^^^^^^^^^^^^^
// guarantees that this will never succeed:
// vvvvvvvvvvvvvvv
if (a == vecA.end()) {
...
}
}
You should rewrite the code like this:
vector<string>::iterator b = vecB.begin();
// Check that vecB has sufficient number of elements before entering the loop.
for (int i = 1 ; i < 2 ; i++) {
for (vector<string>::iterator a = vecA.begin(); a != vecA.end() ; ++a, ++b) {
...
}
// At this point we know for sure that a == vecA.end(),
// because it is a post-condition of the for loop above.
b = std::next(vecB.begin(), 11);
}
The call of ++b can be moved into the loop header.
Note the use of std::next: although
b = vecB.begin() + 10;
compiles for vectors, it is not guaranteed for all kinds of containers. Use std::next instead:
b = std::next(vecB.begin(), 11);
Note: This code makes an assumption that vecB has at least 11 elements more than vecA does. This may be OK if you check that assumption before entering the loop. If this assumption is broken, the code would have undefined behavior.
Others have already answered how to reset or advance an iterator, so I'll just answer, how to solve your problem in a simpler way. It's much simpler to iterate two vectors in parallel using the index rather than two iterators:
// assumes vecB is bigger than vecA as described in the question
for (std::size_t i = 0; i < vecB.size(); i++) {
auto user = vecB[i];
auto pc = vecA[i % vecA.size()];
}
Pay attention to how the smaller vector is iterated using the remainder operator.
In addition to using std::next, as shown in the answer by #dasblinkenlight, you can also use std::advance.
b = vecB.begin();
std::advance(b, 10);
You don't need to change the iterator for B, it will automatically continue with 11th element. But you need to restart iteration on A at the beginning of the for loop (or you would work with a.end() which is not a valid element):
if (a == vecA.end()) {
a = vecA.begin();
}
Also you should iterate over both but check for end on b only; if you check on a, the for would end before the if would turn true:
for (auto a = vecA.begin(), b = vecB.begin(); b != vecB.end(); ++a, ++b)
You can see the whole code here.
I actually prefer to manually iterate over vectors pre-C++11 because it looks way cleaner and more readable than iterators:
for (unsigned int i = 0; i < my_vector.size(); i++) {
my_vector[i]; //Do Something
}
You can specify the range you want to iterate over simply by modifying the for loop conditional (i.e. unsigned int i = n)
Edit: Before downvoting actually read my entire answer. Using iterators on vectors is overly verbose and makes your code virtually unreadable. If there is a legitimate reason this method should not be used in favor of iterators, then please leave a comment.
Most people aren't looking for an ultra-generic, drop-in-any-container solution. Most people know they need a dynamic list, vector fits the bill, so why not make your code easy to read for the next guy?
While getting ready for interviews, I decided to code the classic "Find if there are two elements in an array that sum up to a given number" question using iterator logic, so that it can be generalized to other containers than vector.
Here's my function so far
// Search given container for two elements with given sum.
// If two such elements exist, return true and the iterators
// pointing to the elements.
bool hasElementSum( int sum, const vector<int>& v, vector<int>::iterator& el1, vector<int>::iterator& el2 )
{
bool ret = false;
el1 = v.begin();
el2 = v.end()-1;
while ( el1 != el2 ) {
if ( *el1 + *el2 == sum ) return true;
++el1;--el2;
}
return false;
}
This, of course, doesn't work, but I couldn't figure out a way to do it without using the condition while ( el1 >= el2 ). Various sources I looked advise against using omnly equality checking for iterators, to be able to generalize to all types of containers that support iterators.
Thanks!
First of all, your algorithm is wrong unless you've somehow determined ahead of time that you only need to look at sums where one item is in the first half of the collection, and the other is in the second half of the collection.
If the input's not sorted, then #sbi's answer is about as good as it gets.
With a sorted, random-access input, you can start with the first element, and do a binary search (or interpolation search, etc.) to see if you can find the value that would have to go with that to produce the desired sum. Then you can try the second element, but when you do the binary search (or whatever) use the result from the previous search as the upper limit. Since your first element is larger than the previous one, the matching value to produce the correct sum must be less than or equal to what you found the last time around.
foreach element1 in array
foreach element2 in array + &element1
if( element1 + element2 == sum )
return true
return false
This is O(N^2), since you have to add each element to each of the other elements.
Isn't this question usually asked with a sorted array ?
If not it has to work in O(n^2) complexity, and you will have to check all possible pairs.
I propose the following method though did not analyze the order
Construct a binary search tree with all the elements of the vector, Then for each element
foreach(element = vec.begin to vec.end)
{
if element == node.data, skip
if the element + node.data == sum, return true
if the element + node.data > sum, goto left child
if the element + node.data < sum, goto right child
}
Not a perfect solution/algorithm, but something of this kind.
Sorry, I screwed this one up. What I meant to write was a sort followed by a linear passed, which is the typical answer given to this question, as ltsik pointed out in his comment to Jerry, i.e. something like
bool hasElementSum( int sum, const vector<int>& v, int* ind1, int* ind2 )
{
*ind1 = 0; *ind2 = v.size()-1;
std::sort( v.begin(), v.end() );
while ( *ind1 <= *ind2 ) {
int s = v[*ind1] + v[*ind2];
if ( s > sum ) (*ind1)++;
else if ( s < sum ) (*ind2)++;
else return true
}
return false;
}
My question was how to write this using iterators without saying while (iter1 <= iter2 ) in order to be general, but I now see that doesn't make sense because this algorithm needs random access iterators anyway. Also, returning the indexes is meaningless since they refer to the sorted array and not the original one.