Sorting an array, from high to low - c++

I have an array containing multiple integers, is there a common way for sorting it from high to low?

#include <algorithm>
#include <functional>
int arr[ 5 ] = { 4, 1, 3, 2, 5 };
std::sort( arr, arr + 5, std::greater< int >() );

Pass a comparator to the sort routine that reverses the normal comparison.

Related

get length of multidimensional array with different length in c++?

I have a multidimensional array and i'm trying to get the length of each column. But it's returning 20 for all of them.
int buttons[16][5] = {{0, 4, 1},{1, 0, 2, 5},{2, 1, 3, 6},{3, 2, 7},{4,0,5,8},{5,1,4,6,9},{6,2,5,7,10},{7,3,6,11},{8,4,9,12},{9,5,8,10,13},{10,6,9,11,14},{11,7,10,15},{12,8,13},{13,9,12,14},{14,10,13,15},{15,11,14}};
sizeof(buttons[0]);
You are declaring an C-style array where each element is an array of 5 int. Therefore, with sizeof(buttons[0]), you are getting the size of 5 ints. Usually, ints have a size of 4 bytes, hence you get 20. Only apparently has buttons[0] 3 elements: in fact, in your code, you initialize only the first 3 elements of buttons[0].
If you want a multidimensional array, where each "column" has different size, you should better use std::vector which can hold array of variable size. Then size() gives you the actual number of element.
Example code:
#include <iostream>
#include <vector>
int main()
{
std::vector<int> buttons[16] = {{0, 4, 1},{1, 0, 2, 5},{2, 1, 3, 6},{3, 2, 7},{4,0,5,8},{5,1,4,6,9},{6,2,5,7,10},{7,3,6,11},{8,4,9,12},{9,5,8,10,13},{10,6,9,11,14},{11,7,10,15},{12,8,13},{13,9,12,14},{14,10,13,15},{15,11,14}};
std::cout << buttons[0].size();
}
Even better, you could use a vector of vector:
#include <iostream>
#include <vector>
int main()
{
std::vector<std::vector<int>> buttons = {{0, 4, 1},{1, 0, 2, 5},{2, 1, 3, 6},{3, 2, 7},{4,0,5,8},{5,1,4,6,9},{6,2,5,7,10},{7,3,6,11},{8,4,9,12},{9,5,8,10,13},{10,6,9,11,14},{11,7,10,15},{12,8,13},{13,9,12,14},{14,10,13,15},{15,11,14}};
std::cout << buttons[0].size();
}
You can't do that with arrays. You can do that with vectors:
vector<vector<int> > buttons = ...;
for (auto const& button : buttons) cout << button.size() << '\n';

Find the index of the n-least values in a array without sorting

I have the following array:
{7, 1, 3, 9, 5, 4, 7, 8, 2}
and a empty n-size array. Now I want to find the index of the n-least values in that given array without sorting and write them to the empty array. For example n = 3:
{1, 8, 2}
Is there an easy way to do that?
If you are not restricted in sorting other arrays, then create an array of indices and sort the array of indices in accordance with the original array.
#include <vector>
#include <iostream>
#include <algorithm>
#include <numeric>
int main()
{
int n = 3;
// test data
std::vector<int> test = { 7, 1, 3, 9, 5, 4, 7, 8, 2 };
// index array
std::vector<int> index(test.size());
// set the index array to 0, 1, 2, … n-1
std::iota(index.begin(), index.end(), 0);
// sort the index array
std::sort(index.begin(), index.end(), [&](int n1, int n2) { return test[n1] < test[n2]; });
// output results -- note we are printing the index array
for (int i = 0; i < n; ++i)
std::cout << index[i] << "\n";
}
Output:
1
8
2
Start with first value in array.
Compare the values from the array and the value of the index in the n-least array. (If empty then just add it).
If the value is less, then shift the array from that position and add the index to that position in the n-least array.
If it's not less then compare the next value from the n-least array and so forth.
This is probably not optimal but atleast it's not of O(n^2) complexity that a naive solution would yield.
I'll write this in pseudo code:
n = 3
arr = [7, 1, 3, 9, 5, 4, 7, 8, 2]
narr = []
for i as 0 to sizeof(arr) - 1
for j as 0 to n - 1
if narr[j] is undefined or arr[i] < arr[narr[j]]
narr.shiftRight(j, 1)
narr[j] = i;
break
endif
endfor
endfor

Randomly pick from a vector in C++?

I have a vector that allows for duplicates, I want to randomly chose an element with the probability that represents how many times an element was repeated.
For example - for the vector below, 6 should have the highest probability of being chosen. I thought about using rand(), but I am not quiet sure how to incorporate the probability.
vector A = [ 0, 0, 2, 2, 4, 5, 1, 6, 6, 6]
thanks
I think you are on the right way for getting a custom distribution of values. See the following code which demonstrates the access to the vector. Hope it helps.
#include <cstdlib>
#include <iostream>
#include <ctime>
#include <vector>
int main()
{
std::vector<int> A { 0, 0, 2, 2, 4, 5, 1, 6, 6, 6 };
std::srand(std::time(0)); // use current time as seed for random generator
int random_pos = std::rand() % A.size(); // Modulo to restrict the number of random values to be at most A.size()-1
int random_val = A[random_pos];
}
Maybe something like this (untested!):
#include <vector>
#include <random>
#include <iostream>
int main()
{
std::vector<size_t> A{0, 0, 2, 2, 4, 5, 1, 6, 6, 6};
static thread_local std::mt19937 g{std::random_device{}()};
static thread_local std::uniform_int_distribution<size_t> d{0,A.size()};
std::cout << A[d(g)] << std::endl;
}

Are duplicates of the nth element always contiguous when using std::nth_element?

vector<int> data = {3, 1, 5, 3, 3, 8, 7, 3, 2};
std::nth_element(data.begin(), data.begin() + median, data.end());
Will this always result in:
data = {less, less, 3, 3, 3, 3, larger, larger, larger} ?
Or would a other possible outcome be:
data = {3, less, less, 3, 3, 3, larger, larger, larger} ?
I've tried it multiple times on my machine wich resulted in the nth values always being contiguous. But that's not proof ;).
What it's for:
I want to building a unique Kdtree but I have duplicates in my vector. Currently I'm using nth_element to find the median value. The issue is to select a unique/reconstructible median, without having to traverse the vector again. If the median values were contiguous I could choose a unique median, without much traversing.
No. The documentation does not specify such behavior, and with a few minutes of experimentation, it was pretty easy to find a test case where the dupes weren't contiguous on ideone:
#include <iostream>
#include <algorithm>
int main() {
int a[] = {2, 1, 2, 3, 4};
std::nth_element(a, a+2, a+5);
std::cout << a[1];
return 0;
}
Output:
1
If the dupes were contiguous, that output would have been 2.
I have just tried several not-so-simple examples, and on the third got non-contiguous output.
Program
#include <vector>
#include <iostream>
#include <algorithm>
int main() {
std::vector<int> a = {1, 3, 3, 2, 1, 3, 5, 5, 5, 5};
std::nth_element(a.begin(), a.begin() + 5, a.end());
for(auto v: a) std::cout << v << " ";
std::cout << std::endl;
}
with gcc 4.8.1 under Linux, with std=c++11, gives me output
3 1 1 2 3 3 5 5 5 5
while the n-th element is 3.
So no, the elements are not always contiguous.
I also think that even a simpler way, with no thinking of a good test case, was just generating long random arrays with many duplicate elements and checking whether it holds. I think it will break on the first or second attempt.

STL Container move selected elements

How to select elements with certain value from STL container and move them at the end of that container?
Considering you made a comment about wanting to use std::vector, I'd suggest using std::partition or std::stable_partition, i.e.:
#include <algorithm>
#include <functional>
#include <iostream>
#include <iterator>
#include <vector>
int main()
{
int init_values[] = {1, 1, 7, 3, 19, 5, 5, 4, 5, 2, 5, 8, 9, 10, 5, 1};
std::vector<int> values(
init_values,
init_values + sizeof(init_values) / sizeof(int)
);
std::stable_partition(
values.begin(), values.end(),
std::bind1st(std::not_equal_to<int>(), 5)
);
std::copy(values.begin(), values.end(), std::ostream_iterator<int>(std::cout, ", "));
std::cout << "\n";
return 0;
}
This code will move all elements of the vector that are equal to 5 to the end of the vector, keeping the relative order of the remaining elements in tact.
You could try using std::partition with a predicate that returns true for elements not equal to the target value. If you need to to preserve the relative order of the elements there is also std::stable_partition.