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';
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;
}
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.
I have a std::vector of constant size 2n, and its contents - more vectors - are added in this order (cannot be changed):
1, 1+n, 2, 2+n, 3, 3+n, 4, 4+n etc.
For instance, where n=6 the order of adding would be: 1,7,2,8 etc.
Once populated, I would like to reorder the contents of my vector to 1, 2, 3 etc.
Can anyone suggest how I might go about that? I can't help thinking there's some lovely elegant approach that's just beyond my reach.
With a little help from my friends #Boost:
typedef std::vector<int> V;
V const v { 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15, 8, 16 };
auto rearranged = copy_range<V>(join(
v | strided(2),
v | sliced(1, v.size()) | strided(2)));
See it Live At Coliru
#include <boost/range/adaptors.hpp>
#include <boost/range/join.hpp>
#include <boost/range/algorithm.hpp>
using namespace boost::adaptors;
using boost::copy_range;
#include <iostream>
int main() {
typedef std::vector<int> V;
V const v { 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15, 8, 16 };
auto rearranged = copy_range<V>(join(
v | strided(2),
v | sliced(1, v.size()) | strided(2)));
// print the result
boost::copy(rearranged, std::ostream_iterator<int>(std::cout,";"));
}
Prints
1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;
Since the vector is of a constant size 2n, while populating you can change the index accordingly.
index = (i%2) ? i/2+n+1 : i/2+1;
Where i = 0 to 2n-1
When you get the value of n, declare your vector as
std::vector<myType> vec( 2*n );
the function to map from current place to proper place is easy enough.
fn(int x,int n) { (i%2) ? i/2+n+1 : i/2+1; }
Declare a new vector, with default contents. The loop over them doing swaps.
for(i=0,i<size;i++) {swap(v1[i],v2[fn(i,n)]);}
Of course this likely has serious off by one issues, since your description is 1 based, not zero based like vectors.