Check Arrays for same entries - c++

I have two Arrays of doubles. One Array will be sorted and after this I want to check if every Element of the original Array is still in the sorted Array. I used the find() function of C++ but this pointer only points to the first Element if found, e.g. if you have as original Array {1, 1 ,1 ,1}, the sorted one is {1, 1, 1, 1} but find() only points to the first Element.
Do I really need to loop through the original Array and count the number of times the Elements occure and then loop through the sorted Array and do the same?

Since you just want to check if your array was sorted correctly, you can just sort the other array with std::sort which works correctly for sure and then compare the results:
your_sort(first_array);
std::sort(second_array.begin(),second_array.end());
bool sort_worked = std::equal(first_array.begin(),first_array.end(),
second_array.begin());
Just in case you did not know:
Every standard library-container has the begin() and end() member functions.
You should always use them, use std::vector as your default data structure and another standard container iff you have a good reason to do so. Do not use C-style arrays.

The find() function returns a pointer to the first occurence of the
desired element within a range.
std::find(first, last, value_to_be_searched)
if the element was not found it returns 'last'. You can loop through your
first array and just check that for each element the find function
returns something different from 'last' when called on your second array.

Related

lower_bound function not working properly?

I am using lower_bound to search for element greater than or equal to key in the range [back,end) of a vector which may contain decreasing elements in the given range. So ,I also have to use the greater() functor. The value returned should be the last element itself(for the given range), but the function returns 0. Why?
vector<int>v={1,2,3,4,5};
int i=3;
cout<<*lower_bound(next(v.begin(),i+1),v.end(),v[i],greater<int>());
expected output : 5
if i remove the greater() code, it works fine.
I am using lower_bound to search for element greater than or equal to key in the range [back,end) of a vector which may contain decreasing elements in the given range. So ,I also have to use the greater() functor.
vector<int>v={1,2,3,4,5};
std::lower_bound requires that the input range is sorted according to the comparison object argument. Your vector is not sorted with the std::greater. If it was, then the greatest value would be first.
If your vector is sorted such that least value is first, then you must use std::less (which is the default, so does not need to be specified explicitly).
That said, next(v.begin(),3+1) is an iterator to the last element of the array, so the range [next(v.begin(),3+1), v.end()[ contains exactly one element, whose value is 5. So this range of a single element is in fact sorted according to all possible comparison functions, so using std::greater is technically not a problem.
So, std::lower_bound returns the iterator to the first value that does not satisfy the comparison (i.e. is not less than when using std::less or is not greater than when using std::greater). Otherwise it returns iterator to the end of the range, which in your case is one past the last element of the array.
You've given v[3] i.e the value 4 as the compared value. The range that contains the value 5 does not contain any elements that are not greater than 4, and therefore std::lower_bound returns the iterator to the end of the range. You indirect through this iterator, and the behaviour of the program is undefined.
If you don't use std::greater i.e. you implicitly use std::less, then the range that contains value 5 does contain an element that is not less than 4. Namely the one element whose value is 5. Thus std::lower_bound returns iterator to that element, and indirection through that iterator produces the value 5.
You're not supposed to use the reference to std::greater.
The std::lower_bound function uses a comparison operator to work out whether the element you're searching for is greater than or lower than the elements in the collection. The function presumes that the comparison operator is for less-than, i.e. std::less, and if you provide std::greater instead, the algorithm will get confused and evaluate items in reverse order.

How to find the index of an element in a sorted vector given a pointer to that element

I have a vector std::vector<MyClass> vec. I'm trying to sort the vector and then find the index of an element given a pointer to it
sort(vec.begin(), vec.end(), ...);
auto index = myPointer - &vec[0];
I noticed that the value of index doesn't change when the vector is sorted and therefore is incorrect. Is there a way to directly get the correct index?
Standard requires that RandomIt of sort meet the requirement of ValueSwappable, which means it use std::iter_swap to swap elements during sorting. Your pointer address won't be changed, if it points to the 2nd element before sort, it will still point to the 2nd element after sort, but the 2nd element got changed after sort most of the time. You need to use equal_range to get a new pointer address after sorting.

Do vector indices not wrap around in C++? What is the workaround?

When I initialize a vector:
std::vector <int> someVec;
and I call:
std::cout << someVec[-1];
with an arbitrary number of elements, 0 is always returned.
Is there some way to get around this? The inability to do this in C++ is messing up my "sort" function. Is there any way to initialize said vector differently in order to return the last element in the vector, rather than 0 which seems to be the default. It seems that any index called outside the range of the vector will result in 0. It isn't wrapped which is baffling me.
The behaviour of accessing the vector outside the bounds (such as at the index [-1]) is undefined.
Is there anyway to [...] return the last element in the vector
Like this: someVec.back()
If you need a container that returns the last element when using the index [-1], then vector is not the container for your purpose. The standard library has no such container.
The inability to do this in C++ is messing up my "sort" function.
The ideal approach may be to fix the "sort" function to not require access to [-1]. The standard library comes with a sort function though, so you might not even need to implement one yourself.
Is there some way to get around this?
To access the last element in a std::vector use std::back:
std::vector<int> vec(10,1);
std::cout << vec.back(); // prints 1
Note that after default initializing a vector
std::vector<int> vec2;
accessing any index via operator[] is undefined behaviour, because the size of the vector is 0, there aren't any elements to access.

What is the behavior of std::greater in std::priority_queue?

When I used std::greater<int> as a comparison function object in std::sort as the following:
std::sort(array_name, array_name + length, std::greater<int>());
The array sorted in non-increasing order (i.e. the largest number first)
But, when I used the same comparison function in std::priority_queue as the following:
std::priority_queue <int, std::vector<int>, std::greater<int> > pq_name;
Why the std::priority_queue::top member function returns the smallest number first?
(I need a clear comparison between the two cases).
In order to understand why this happens, you have to understand the data structures that you're working with.
Q: What is an array?
A: An array is a contiguous region of memory containing a type. As far as we are concerned it can contain any type of object. But since you're working with int, in C++ an integer is tipicaly formed by 32 bits, but it depends. Therefore, your representation in memory would be something like,
| 4 bytes | 4 bytes | 4 bytes | (...)
When you're sorting an array, the std::greater<int>operator will "sort" your array by keeping the greater integer in the first position, the second largest value in the second position, and so on.
Q: What is a std::priority_queue?
A: A priority queue is a heap, more specifically, a binary tree. A heap is a data structure that is optimized to return the largest value by default. This type of heaps are called max heaps. But when you overload the comparison within the priority_queue using the std::greater operator, you are transforming the heap into a min heap. This kind of heaps, similarly to what happens when you overload the std::sort method operator, is implemented to retrieve the minimum value first.
Keep in mind that the representation of a heap in memory is completely different from the one found in an array.
CPPRef says on it:
A user-provided Compare can be supplied to change the ordering, e.g. using std::greater would cause the smallest element to appear as the top().
Note that the Compare parameter is defined such that it returns true if its first argument comes before its second argument in a weak ordering. But because the priority queue outputs largest elements first, the elements that "come before" are actually output last. That is, the front of the queue contains the "last" element according to the weak ordering imposed by Compare.
So, for a default std::less-based ordering, top of the queue is the largest element, the one that comes the last when sorted. OTOH with std::greater the last element is the smallest one.

How to get the begin and end of an array that was created by new

int[] a = {1,2,3};
int* b = new int[3]{4,5,6};
I want to get the begin and end of b. std::begin()works in abut not in b. Is there an suitable way to get the two positions of b?
If you see a reference to std::begin and std::end you will see that beginning and end iterators are in way pointers to the first and one-beyond-last elements of the container. For arrays this is doubly-true because then you can use actual pointers for the iterators.
For an array like a the std::begin function returns a pointer to the first element, and the std::end function returns a pointer to one beyond the last element.
Now when you know that information it's easy to figure out what "begin" and "end" iterators for a pointer is, because it's exactly the same as for an array. I.e. pointers to the first and one-beyond-last elements.
In the case of your example, the "begin iterator" is simply b (because it points to the first element), and the "end iterator" is b + 3 which is a pointer to one beyond the last element.