Vector of random integers where each integer occurs 10 times C++ - c++

#include <random>
#include <algorithm>
#include <iterator>
#include <iostream>
#include <vector>
using namespace std;
int main()
{
// First create an instance of an engine.
random_device rnd_device;
// Specify the engine and distribution.
mt19937 mersenne_engine {rnd_device()}; // Generates random integers
uniform_int_distribution<int> dist {0, 2};
auto gen = [&dist, &mersenne_engine](){
return dist(mersenne_engine);
};
vector<int> vec(30);
generate(begin(vec), end(vec), gen);
// Optional
for (auto i : vec) {
cout << i << " ";
}
}
I am trying to create a vector of 30 numbers consisting of values 0-2 and each integer occurs 10 times. What is the most efficient way to do this in C++.

Basically it should be done as written in the comments.
First we define a std::vector with the given size
Then, we fill it with an ultra simple Lambda
And finally we shuffle it
The resulting code is simple and efficient. Please see:
#include <random>
#include <algorithm>
#include <iterator>
#include <iostream>
#include <vector>
int main() {
// Engine to shuffle the vector
std::random_device rnd_device;
std::mt19937 me{ rnd_device() };
// Simple filler lambda
auto filler = [n = 0]() mutable->int { return n++ / 10; };
// Define vector with given size
std::vector<int> vec(30);
// Fill and shuffle
std::generate(vec.begin(), vec.end(), filler);
std::shuffle(vec.begin(), vec.end(), me);
// Debug output
std::copy(vec.begin(), vec.end(), std::ostream_iterator<int>(std::cout, " "));
}

Related

Why can't I use a set as the output collection of transform operation on a vector? [duplicate]

This question already has answers here:
std::back_inserter for a std::set?
(2 answers)
Closed 12 months ago.
When I use transform on a set and use a vector to store the output, it works fine. But it doesn't seem to work the other way around.
This is the code that doesn't work:
#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;
int multiply(int a) {
return a * 2;
}
void print(int i) {
cout << i << " ";
}
int main() {
int mynumbers[] = { 3,9,2,4,1 };
vector<int> v1(mynumbers, mynumbers + 5);
set<int> s1(mynumbers, mynumbers + 5);
transform(v1.begin(), v1.end(), s1.begin(), multiply);
for_each(v1.begin(), v1.end(), print);
cout << endl;
for_each(s1.begin(), s1.end(), print);
}
As #molbdnilo pointed out:
The elements of a set are immutable.
Thus, existing elements cannot be overwritten.
However, it can be done with e.g. a std::insert_iterator:
#include <algorithm>
#include <iostream>
#include <set>
#include <vector>
int main()
{
std::vector<int> v = { 1, 2, 3, 4, 5 };
std::set<int> s;
std::transform(v.begin(), v.end(),
std::insert_iterator<std::set<int>>(s, s.begin()),
[](int x) { return x * 2; });
for (int x : s) std::cout << ' ' << x;
}
Output:
2 4 6 8 10
Live demo on coliru
As #JeJo already mentioned, std::inserter can be used.
Just pasting here the code with it.
set<int> s1;
transform(v1.begin(), v1.end(), inserter(s1, s1.begin()), multiply);
For the testing purpose, it does not matter, although it is not good to initialize the set s1 with vector v1 values, because transform adds/overwrites entries in the target container, and in your code the new values are getting mixed with old values (e.g. 4,9)

How to shuffle element key in a std::map?

I am looking for a way to shuffle a std::map in C++.
I have a std::map with key as integers and value as struct and i want to shuffle the keys.
I tried to use std::random_shuffle, but it doesn't compile. So i created a temp vector, i populated this vector, shuffle it and use it to swap in the map.
This is how i currently do:
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <ctime>
#include <cstdlib>
std::vector<int> temp_vec_registration;
int myrandom(int i) { return std::rand()%i; }
struct CRegInfo
{
bool success;
int num_order;
int type;
CRegInfo(bool succ, int num, int type)
: success(succ), num_order(num), type(type)
{}
};
typedef std::map<int, CRegInfo> RegInfo;
RegInfo register_chars;
int main()
{
std::srand(unsigned(std::time(0)));
temp_vec_registration.clear();
register_chars.clear();
for (int i = 0; i <= 10; i++)
temp_vec_registration.push_back(i);
std::random_shuffle(temp_vec_registration.begin(), temp_vec_registration.end(), myrandom);
for (std::vector<int>::iterator it1=temp_vec_registration.begin(); it1!=temp_vec_registration.end(); ++it1)
register_chars.insert(RegInfo::value_type(*it1, CRegInfo(false, 0, 0)));
for (auto it2 = register_chars.begin(); it2 != register_chars.end(); ++it2)
std::cout << it2->first << "\t";
}
But it doesn't work, the vector has random number, but the map always has the same numbers in key. (0, 1, 2, 3.. 10).
Hmm, while this is technically possible with some additional hacking, but with naive approach—std::map is an ordered storage, i.e. it maintains ordering among its keys, which is its primary feature, for the price of logarithmic complexities of simple operations.
std::unordered::map, as its name suggests, does not give such guarantees so you might try luck doing the same with unordered_map... If you simply want to iterate over map items in an indeterminate order, well, use your shuffled vector for it.

How to manipulate vectors in C++

I'm trying to manipulate a set of elements in vectors in c++.
vector <int> vectorOfValue;
vectorOfValue.push_back(1);
vectorOfValue.push_back(2);
vectorOfValue.push_back(3);
vectorOfValue.push_back(4);
vectorOfValue.push_back(5);
vectorOfValue.push_back(6);
vectorOfValue.push_back(7);
vectorOfValue.push_back(8);
vectorOfValue.push_back(9);
vectorOfValue.push_back(10);
I would like to know how the program can print out the vectors of values bigger 3 and smaller than 9.
It is a set of the data to exclude the outliers for example.
If you want to use the standard library algorithms and iterators, you could use std::copy_if:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
auto main(int argc, char* argv[]) -> int
{
std::vector<int> vectorOfValue;
// code for initialization of vector ..
std::copy_if(vectorOfValue.begin(),
vectorOfValue.end(),
std::ostream_iterator<int>(std::cout, "\n"),
[](const int value) { return value > 3 && value < 9; });
}
Short approach of mine using auto syntax instead of using iterator :
for(auto &i : vectorOfValue) {
if (i > 3 && i < 9) {
std::cout << i << std::endl;
}
}

Range v3. Difference between two ranges

I am trying to get the difference between two ranges but have little luck.
Something like
vector<int> l{ 1,5,6 };
auto diff = views::ints(1,10) - view::all( l );
==> Range<int> { 2,3,4,7,8,9 }
By the way. Are there any good writings on range-v3? Something to make me wiser?
Thanks.
You are looking for the set_difference algorithm, or its lazy view version:
#include <range/v3/view/iota.hpp>
#include <range/v3/view/set_algorithm.hpp>
#include <iostream>
#include <vector>
int main() {
std::vector<int> l{ 1,5,6 };
auto diff = ranges::view::set_difference(ranges::view::ints(1,10), l);
std::cout << diff << '\n'; // [2,3,4,7,8,9]
}

How to multiply a vector and scalar in C++?

I would like to multiply a vector with a scalar. This vector was created using the accepted answer to this question of mine namely:
std::vector<int> n(N + 1);
std::iota(begin(n), end(n), 0);
and I would like to multiply this vector, n, with a scalar (specifically of type double, if it is relevant here) called npi.
I have seen this answer to a previous question here, but it wasn't all that helpful. The way I attempted to implement it was by adding:
std::transform(n.begin(), n.end(), n.begin(),
std::bind1st(std::multiplies<T>(),pin));
to my C++ program. This returned the compile error:
error: ‘T’ was not declared in this scope
std::bind1st(std::multiplies<T>(),pin));
I would like to call the vector created by multiplying this vector with a scalar npi, so please do not give me code that will call this new vector n (i.e., overwriting my existing n vector).
EDIT:
If it will placate whomever voted to close this question, here is my full program:
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <cmath>
#include <utility>
#include <unistd.h>
#include <algorithm>
#include <numeric>
/*#include <armadillo>*/
using namespace std;
/*using namespace arma;*/
double N = 1000.0;
double x0 = 0;
double x1 = 100;
double pin = M_PI / double(N);
int main() {
std::vector<int> n(N + 1);
std::iota(begin(n), end(n), 0);
std::transform(n.begin(), n.end(), n.begin(),
std::bind1st(std::multiplies<T>(),pin));
for(double i: n)
{
std::cout << i << '\n' << std::scientific;
}
}
For vector<int> output, one way is:
auto npi = n;
for( auto& i: npi )
i *= pin;
If npi should be vector<double> (not clear from the question) then replace the first line with:
std::vector<double> npi( n.begin(), n.end() );
You need to replace T by the type contained in the vector, in this case int. However you can probably simplify your code by using a lambda function here instead:
#include <algorithm> // for std::transform
#include <cmath> // for M_PI
#include <iostream> // for std::cout etc
#include <numeric> // for std::iota
#include <vector> // for awesome
int main() {
std::vector<int> vec1(10);
std::iota(vec1.begin(), vec1.end(), 0);
int N = 42;
std::vector<double> vec2(vec1.size()); // vec2 needs to be as big or bigger than vec1
std::transform(vec1.begin(), vec1.end(), vec2.begin(),
[N](int i) { return i * M_PI / N; });
for (auto a : vec1)
std::cout << a << " ";
std::cout << std::endl;
for (auto a : vec2)
std::cout << a << " ";
std::cout << std::endl;
}
Here's an online example: http://melpon.org/wandbox/permlink/XrNxDND0steJmym8
If I have understood you correctly you need the following
std::vector<double> v;
v.reserve(n.size());
std::transform(n.begin(), n.end(), std::back_inserter( v ),
std::bind1st(std::multiplies<double>(), pin));
You can pass the scalar in the capture clause of the Lambda function and do the multiplication inside the lambda function itself
#include <algorithm>
#include <vector>
std::vector<int> foo;
std::vector<int> bar;
auto npi=4.0;
std::transform (foo.begin(), foo.end(), bar.begin(), foo.begin(), [&npi](auto& c){return c * npi;}