I have a hand full of objects each containing several strings each. Right now its set up as structures each containing a map with keys 1...n, one for each string (map<int,string> strs), this can be changed if a better way exists. I need to randomly access all of these str ings without overlapping and know that i'm done. How can I do this, either with the maps or another data structure? Thanks.
Here's some code for a Fisher-Yates shuffle:
template <class T>
std::vector<T> shuffle(std::vector<T> &vect)
{
std::vector<T> shuffled = vect;
for(int i = shuffled.size()-1; i >= 1; i--) {
int idx = rand() % (i+1);
T tmp = shuffled[idx];
shuffled[idx] = shuffled[i];
shuffled[i] = tmp;
}
return shuffled;
}
This will take in a vector, and return a copy of it in a random order. If you have a vector of strings, you can use it like this (I'm using c++11 here):
int main()
{
srand(time(NULL));
std::vector<std::string> strs = {"foo", "bar", "baz", "stack", "overflow"};
for(auto &str : shuffle(strs)) {
std::cout << str << std::endl;
}
return 0;
}
Of course, if you're lazy, like me, there's always the random_shuffle() function in <algorithm>:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
int main()
{
std::vector<std::string> strs = {"foo", "bar", "baz", "stack", "overflow"};
std::random_device rd;
std::mt19937 g(rd()); // Use a good random number generaor
std::random_shuffle(strs.begin(), strs.end(), g); // this does the shuffle
for(auto &str : strs) {
std::cout << str << std::endl;
}
return 0;
}
Hope this helps!
A horrible solution, don't do this. Very slow for large candidate vectors, this has n-squared complexity. Shuffling is better, it has linear complexity.
std::vector<int> RandomThing(int number, int min, int max)
{
assert(!"RandomThing" && min < max);
std::vector<int> candidates;
for(int i=min; i<max; i++)
candidates.push_back(i);
std::vector<int> result;
for(int i=0; i<number;)
{
int candidate_index = rand() % candidates.size();
result.push_back(candidates[candidate_index]);
std::vector<int>::iterator it = candidates.begin();
std::advance(it, candidate_index);
candidates.erase(it);
}
return result;
}
Related
Assume I have a vector with the following elements {1, 1, 2, 3, 3, 4}
I want to write a program with c++ code to remove the unique values and keep only the duplicated once. So the end result will be something like this {1,3}.
So far this is what I've done, but it takes a lot of time,
Is there any way this can be more efficient,
vector <int> g1 = {1,1,2,3,3,4}
vector <int> g2;
for(int i = 0; i < g1.size(); i++)
{
if(count(g1.begin(), g1.end(), g1[i]) > 1)
g2.push_back(g1[i]);
}
v.erase(std::unique(g2.begin(), g2.end()), g2.end());
for(int i = 0; i < g2.size(); i++)
{
cout << g2[i];
}
My approach is to create an <algorithm>-style template, and use an unordered_map to do the counting. This means you only iterate over the input list once, and the time complexity is O(n). It does use O(n) extra memory though, and isn't particularly cache-friendly. Also this does assume that the type in the input is hashable.
#include <algorithm>
#include <iostream>
#include <iterator>
#include <unordered_map>
template <typename InputIt, typename OutputIt>
OutputIt copy_duplicates(
InputIt first,
InputIt last,
OutputIt d_first)
{
std::unordered_map<typename std::iterator_traits<InputIt>::value_type,
std::size_t> seen;
for ( ; first != last; ++first) {
if ( 2 == ++seen[*first] ) {
// only output on the second time of seeing a value
*d_first = *first;
++d_first;
}
}
return d_first;
}
int main()
{
int i[] = {1, 2, 3, 1, 1, 3, 5}; // print 1, 3,
// ^ ^
copy_duplicates(std::begin(i), std::end(i),
std::ostream_iterator<int>(std::cout, ", "));
}
This can output to any kind of iterator. There are special iterators you can use that when written to will insert the value into a container.
Here's a way that's a little more cache friendly than unordered_map answer, but is O(n log n) instead of O(n), though it does not use any extra memory and does no allocations. Additionally, the overall multiplier is probably higher, in spite of it's cache friendliness.
#include <vector>
#include <algorithm>
void only_distinct_duplicates(::std::vector<int> &v)
{
::std::sort(v.begin(), v.end());
auto output = v.begin();
auto test = v.begin();
auto run_start = v.begin();
auto const end = v.end();
for (auto test = v.begin(); test != end; ++test) {
if (*test == *run_start) {
if ((test - run_start) == 1) {
*output = *run_start;
++output;
}
} else {
run_start = test;
}
}
v.erase(output, end);
}
I've tested this, and it works. If you want a generic version that should work on any type that vector can store:
template <typename T>
void only_distinct_duplicates(::std::vector<T> &v)
{
::std::sort(v.begin(), v.end());
auto output = v.begin();
auto test = v.begin();
auto run_start = v.begin();
auto const end = v.end();
for (auto test = v.begin(); test != end; ++test) {
if (*test != *run_start) {
if ((test - run_start) > 1) {
::std::swap(*output, *run_start);
++output;
}
run_start = test;
}
}
if ((end - run_start) > 1) {
::std::swap(*output, *run_start);
++output;
}
v.erase(output, end);
}
Assuming the input vector is not sorted, the following will work and is generalized to support any vector with element type T. It will be more efficient than the other solutions proposed so far.
#include <algorithm>
#include <iostream>
#include <vector>
template<typename T>
void erase_unique_and_duplicates(std::vector<T>& v)
{
auto first{v.begin()};
std::sort(first, v.end());
while (first != v.end()) {
auto last{std::find_if(first, v.end(), [&](int i) { return i != *first; })};
if (last - first > 1) {
first = v.erase(first + 1, last);
}
else {
first = v.erase(first);
}
}
}
int main(int argc, char** argv)
{
std::vector<int> v{1, 2, 3, 4, 5, 2, 3, 4};
erase_unique_and_duplicates(v);
// The following will print '2 3 4'.
for (int i : v) {
std::cout << i << ' ';
}
std::cout << '\n';
return 0;
}
I have 2 improvements for you:
You can change your count to start at g1.begin() + i, everything before was handled by the previous iterations of the loop.
You can change the if to == 2 instead of > 1, so it will add numbers only once, independent of the occurences. If a number is 5 times in the vector, the first 3 will be ignored, the 4th will make it into the new vector and the 5th will be ignored again. So you can remove the erase of the duplicates
Example:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector <int> g1 = {1,1,2,3,3,1,4};
vector <int> g2;
for(int i = 0; i < g1.size(); i++)
{
if(count(g1.begin() + i, g1.end(), g1[i]) == 2)
g2.push_back(g1[i]);
}
for(int i = 0; i < g2.size(); i++)
{
cout << g2[i] << " ";
}
cout << endl;
return 0;
}
I'll borrow a principal from Python which is excellent for such operations -
You can use a dictionary where the dictionary-key is the item in the vector and the dictionary-value is the count (start with 1 and increase by one every time you encounter a value that is already in the dictionary).
afterward, create a new vector (or clear the original) with only the dictionary keys that are larger than 1.
Look up in google - std::map
Hope this helps.
In general, that task got complexity about O(n*n), that's why it appears slow. Does it have to be a vector? Is that a restriction? Must it be ordered? If not, it better to actually store values as std::map, which eliminates doubles when populated, or as a std::multimap if presence of doubles matters.
The intended nature of the program is to randomly generate numbers into a vector container, then sort them in ascending order and print the numbers out. The program compiles correctly but also sorts and prints the value 0 for each number that is generated.
#include "stdafx.h"
//contains all header files (ctime, algorithm, iostream, vector), also
defines const vector size as 250
using namespace std;
void genRndNums(vector <int> &v);
void printVec(vector <int> &v);
int main()
{
vector <int> myVector(VEC_SIZE);
genRndNums(myVector);
printVec(myVector);
return 0;
}
void genRndNums(vector <int> &v)
{
int v1;
srand(time(nullptr));
for (int i = 0; i < VEC_SIZE; i++)
{
v1 = rand() % 1000 + 1;
v.push_back(v1);
//v.push_back(rand() % 1000 + 1);
}
}
void printVec(vector <int> &v)
{
vector<int>::iterator it;
sort(v.begin(), v.end());
for (it = v.begin(); it != v.end(); it++)
{
cout << *it << " ";
}
}
In the case that 250 numbers were printed out, it would display the integer 0 250 times and then display the rest of the numbers in ascending sequence.
This is due to the for-loop in the print function having something misplaced, but I am not sure how to get the vector to display only the randomized integers.
Since you are using push_back to add elements to the vector, you need to start with an empty vector. I.e. you need to replace vector <int> myVector(VEC_SIZE); with vector <int> myVector;.
This is a common mistake. push_back adds to the end of the vector whose size is already VEC_SIZE. You can start with an empty vector like this:
vector <int> myVector;
or you can assign values to existing vector (whose size is VEC_SIZE) elements like this:
for (int i = 0; i < VEC_SIZE; i++)
{
v1 = rand() % 1000 + 1;
v[i] = v1;
}
Your vector constructor creates vector with 250 numbers (each with 0 value). To that numbers you appends another 250 generated numbers.
You shall not create that 250 numbers at the beginning
#include <vector>
#include <algorithm>
#include <random>
#include <iostream>
int main()
{
std::vector<int> v;
{
std::random_device r;
std::default_random_engine e(r());
std::uniform_int_distribution<int> d(1, 6);
std::generate_n(std::back_inserter(v), 250, [&](){ return d(r); });
}
std::sort(v.begin(), v.end());
for (auto x : v) {
std::cout << x << "\n";
}
return 0;
}
or override them
#include <vector>
#include <algorithm>
#include <random>
#include <iostream>
int main()
{
std::vector<int> v(250);
{
std::random_device r;
std::default_random_engine e(r());
std::uniform_int_distribution<int> d(1, 6);
std::generate(v.begin(), v.end(), [&](){ return d(r); });
}
std::sort(v.begin(), v.end());
for (auto x : v) {
std::cout << x << "\n";
}
return 0;
}
I am receiving some integers from an external API (std::vector).
The API usually needs to be called multiple times, so I need to accumulate all the integers from the consecutive API calls to a local vector. At the end every element of the array must be unique (does not need to be sorted).
My code is below (uses the getNextVector to "mock" data and simulate the API call).
The code works, however I want maximum performance for this operation. Is my approach the right one?
#include <vector>
#include <iostream>
#include <iterator>
#include <algorithm>
std::vector<int> getNextVector(int i) {
if ( i == 0 ) {
std::vector<int> v = { 1,2,3 };
return v;
} else if ( i == 1 ) {
std::vector<int> v = { 3,4,5 };
return v;
} else if ( i == 2 ) {
std::vector<int> v = { 5,6,7 };
return v;
} else if ( i == 3 ) {
std::vector<int> v = { 7,8,9 };
return v;
}
}
int count() { return 4; } //we have four vectors
int main(int argc, char** argv) {
std::vector<int> dest;
dest.reserve(20); // we can find this, for simplicity hardcode...
for( int i = 0; i < count(); i++ ) {
std::vector<int> src = getNextVector(i);
dest.insert(
dest.end(),
std::make_move_iterator(src.begin()),
std::make_move_iterator(src.end())
);
}
std::sort(dest.begin(), dest.end());
dest.erase(unique(dest.begin(), dest.end()), dest.end());
/*
std::copy(
dest.begin(),
dest.end(),
std::ostream_iterator<int>(std::cout, "\n")
);
*/
return 0;
}
I think you can store the elements of the vector in a set. If ordering is not needed you can use unordered_set. Simply do the following -
std::unordered_set<int> integers;
for (int i = 0; i < count; i++) {
std::vector<int> src = getNextVector(i);
for (int j = 0; j < src.size(); j++) {
integers.insert(src[i]);
}
}
Or as suggested by #StoryTeller, you can use an appropriate function instead of the loop. For example -
std::unordered_set<int> integers;
for (int i = 0; i < count; i++) {
std::vector<int> src = getNextVector(i);
integers.insert(src.begin(), src.end());
}
My first thought was about "It can be done fast and easly with unordered_set", later I realised that it will not help too much with ints (hash of int is still int, so I don't see here performance increase). So, lastly I decided to benchmark it and my results are:
N = 4 Set implementation 304703 miliseconds
N = 4 Unordered set implementation 404469 miliseconds
N = 4 Vect implementation 91769 miliseconds
N = 20 Set implementation 563320 miliseconds
N = 20 Unordered set implementation 398049 miliseconds
N = 20 Vect implementation 176558 miliseconds
N = 40 Set implementation 569628 miliseconds
N = 40 Unordered set implementation 420496 miliseconds
N = 40 Vect implementation 207368 miliseconds
N = 200 Set implementation 639829 miliseconds
N = 200 Unordered set implementation 456763 miliseconds
N = 200 Vect implementation 245343 miliseconds
N = 2000 Set implementation 728753 miliseconds
N = 2000 Unordered set implementation 499716 miliseconds
N = 2000 Vect implementation 303813 miliseconds
N = 20000 Set implementation 760176 miliseconds
N = 20000 Unordered set implementation 480219 miliseconds
N = 20000 Vect implementation 331941 miliseconds
So, apperently, for samples you gave us here you implementation is the fastest one. This is case when your API returns only few possible vector combinations and number of iterations is small. I've decided to verify what happends when you have more different values via rand() for N > 4 (*). And it keeps it that way. Unordered set is the slowest one (hash calculation cost).
So, to answer your question: benchmark you case on your own - this is the best way to determine which is the fastest one.
(*) Bad randomness of rand() is not bug, but a feature here.
EDIT:
My answer does not provide not says there are no faster algorithms - I've benchmarked STL ones, which at first glance seems to be behave differently than results provide. But for sure there is a way of doing unique concatetion faster, maybe some combination of set of vectors or different container and I hope someone will provide one.
#include <vector>
#include <iostream>
#include <iterator>
#include <algorithm>
#include <set>
#include <unordered_set>
#include <chrono>
std::vector<int> getNextVector(int i) {
if (i == 0) {
std::vector<int> v = { 1,2,3 };
return v;
}
else if (i == 1) {
std::vector<int> v = { 3,4,5 };
return v;
}
else if (i == 2) {
std::vector<int> v = { 5,6,7 };
return v;
}
else if (i == 3) {
std::vector<int> v = { 7,8,9 };
return v;
}
return {rand() % 10000,rand() % 10000,rand() % 10000 };
}
void set_impl(std::set<int>& dest, int N)
{
// dest.reserve(20); // we can find this, for simplicity hardcode...
for (int i = 0; i < N; i++) {
std::vector<int> src = getNextVector(i);
dest.insert(
std::make_move_iterator(src.begin()),
std::make_move_iterator(src.end())
);
}
}
void uset_impl(std::unordered_set<int>& dest, int N)
{
// dest.reserve(20); // we can find this, for simplicity hardcode...
for (int i = 0; i < N; i++) {
std::vector<int> src = getNextVector(i);
dest.insert(
std::make_move_iterator(src.begin()),
std::make_move_iterator(src.end())
);
}
}
void vect_impl(std::vector<int>& dest, int N)
{
for (int i = 0; i < N; i++) {
std::vector<int> src = getNextVector(i);
dest.insert(
dest.end(),
std::make_move_iterator(src.begin()),
std::make_move_iterator(src.end())
);
}
std::sort(dest.begin(), dest.end());
dest.erase(unique(dest.begin(), dest.end()), dest.end());
}
int main(int argc, char** argv) {
for (int N : { 4, 20, 40, 200, 2000, 20000 })
{
const int K = 1000000 / N;
using clock = std::chrono::high_resolution_clock;
std::set<int> sdest;
auto start = clock::now();
for (int i = 0; i < K; i++)
{
sdest.clear();
set_impl(sdest, N);
}
auto set_ms = std::chrono::duration_cast<std::chrono::microseconds>(clock::now() - start).count();
std::unordered_set<int> usdest;
start = clock::now();
for (int i = 0; i < K; i++)
{
usdest.clear();
uset_impl(usdest, N);
}
auto uset_ms = std::chrono::duration_cast<std::chrono::microseconds>(clock::now() - start).count();
std::vector<int> dest;
dest.reserve(N); // we can find this, for simplicity hardcode...
start = clock::now();
for (int i = 0; i < K; i++)
{
dest.clear();
vect_impl(dest, N);
}
auto vect_ms = std::chrono::duration_cast<std::chrono::microseconds>(clock::now() - start).count();
std::cout << "N = " << N << " Set implementation " << set_ms << " miliseconds\n";
std::cout << "N = " << N << " Unordered set implementation " << uset_ms << " miliseconds\n";
std::cout << "N = " << N << " Vect implementation " << vect_ms << " miliseconds\n";
}
return 0;
}
If you want to preserve the order of elements recieved from the external API and they are not sorted then I recommend you create a second vector which you keep sorted. Then do a lower_bound on the sorted vector and if the returned iterator is not the value insert in both the target and sorted vectors (using the returned iterator as the insert position in the sorted vector). Using set or unordered set for integers is likely to be very much slower (probably orders of magnitude slower). If you don't care about the order then use a single sorted vector.
vector<int> sorted;
....
vector<int> src = getNextVector(i);
for( int i : src ) {
auto itr = std::lower_bound( sorted.begin(), sorted.end(), i );
if( *itr != i ) {
sorted.insert(itr, i);
integers.push_back(i);
}
}
If you know the values from each call to getNextVector are unique then you could do something like the following (which might be faster.)
vector<int> sorted;
....
vector<int> src = getNextVector(i);
vector<int> usrc;
for( int i : src ) {
auto itr = std::lower_bound( sorted.begin(), sorted.end(), i );
if( *itr != i ) {
usrc.push_back(i);
integers.push_back(i);
}
}
sorted.insert(sorted.end(), usrc.begin(), usrc.end());
std::sort( sorted.begin(), sorted.end() );
[C++20 solution]
In order to merge multiples containers into a vector,
while removing duplicates, I'd use something simplier like that :
namespace mp {
template <typename T>
concept Container = requires (T value) { // very naive container requirements
typename T::value_type;
std::begin(value), std::end(value);
std::cbegin(value), std::cend(value);
};
}
template <mp::Container ... Ts>
requires
requires { typename std::common_type_t<typename Ts::value_type...>; }
auto merge_uniques(const Ts & ... names) {
using value_type = typename std::common_type_t<typename Ts::value_type...>;
auto value = std::unordered_set<value_type>{};
(value.insert(std::cbegin(names), std::cend(names)), ...);
return std::vector<value_type> {
std::move_iterator{std::begin(value)},
std::move_iterator{std::end(value)}
};
}
I'm trying to use a map in order to make the algorithm for this answer https://leetcode.com/problems/two-sum/#/description O(n), but for some reason i'm getting the improper indices for a lot of test cases i'm trying
From what I can tell, I'm doing the checks properly for the iterators, however these are kind of new to me, and i'm not entirely sure if i'm returning the correct indices that I want.
//My Code:
#include <iostream>
#include <cstdio>
#include <array>
#include <vector>
#include <map>
std::vector<int> twoSum(int nums[], int size, int target)
{
std::vector<int> answer;
std::map<int, int> myMap;
std::map<int, int>::iterator it;
std::cout << size << std::endl;
for (int i = 0; i < size; i++)
{
myMap.insert(std::pair<int, int>(nums[i], i));
int indexItOne = distance(myMap.begin(), myMap.find(nums[i]));
int indexItTwo = distance(myMap.begin(), myMap.find(target-nums[i]));
it = myMap.find(target - nums[i]);
if (it != myMap.begin() || indexItOne != indexItTwo)
{
answer.push_back(i);
answer.push_back(distance(myMap.begin(), myMap.find(target - nums[i])));
return answer;
}
}//for
}//twoSum
You are correct in that the map should be a mapping from num to the index of that num, but it should not be inserted into the map right away. This is due to the constraint of the problem that
you may not use the same element twice.
Therefore, the algorithm would go something more like this:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
// Create a mapping from num -> index of num
unordered_map<int, int> m;
for(int i = 0; i < nums.size(); i++) {
// Check if we have seen our buddy
int buddy = target - nums[i];
auto buddyIt = m.find(buddy);
if(buddyIt != m.end()) {
// Buddy found, return answer
return vector<int>{ buddyIt->second, i };
}
// Buddy not found, insert current num into buddy map
m[nums[i]] = i;
}
}
};
I would like to generate list of strings with no repeats as follows
A1, A2 , A3 , A4 , B1 , B2 , B3 , B4 , C1, C2, C3, C4
this is the way I generate out my list of strings
std::string columns[] ={"A","B","C"};
std::string rows[]={"1","2","3","4"};
std::string columnsAndRows;
for(int i=0; i<10; i++) {
for(int j=0; j<10; j++) {
columnsAndRows=columns[i]+row[j];
//possible to do something like this?
columnAndRows.rand();
}
}
but the problem is, I read about rand() and it returns a pseudo-random integral number in the range between 0 and RAND_MAX. what should I do to generate a random string base on my desired requirements?
Using std::rand with the modulus might not be a good idea. Instead you can easily construct a std::vector of possible elements and do a std::random_shuffle on that container:
std::vector<std::string> cols = {"A", "B", "C"};
std::vector<std::string> rows = {"1", "2", "3", "4"};
std::vector<std::string> vec;
for (auto i : cols)
for (auto j : rows)
vec.emplace_back(i + j);
std::random_shuffle(vec.begin(), vec.end());
And here's the running code results.
As hinted by DyP, std::random_shuffle might use rand inside its implementation (the truth is that it's implementation defined) therefore you might incur in the problem of keep getting the same results over and over again because you did not seed the random function.
Thankfully C++11 introduces std::shuffle that allow us to pass a third argument and define our own random generator functor. The great thing about this is that we can easily use <random> to feed that argument:
std::mt19937 rand_func(std::random_device{}());
std::shuffle(vec.begin(), vec.end(), rand_func);
And here's the running code results.
So why can't you use rand()? Because it may return a too-large value? Then pick a random value and if it's too large, (a) don't use it but pick another or (b) clip off the too large part using the % (modulus) operator:
my1stOwnRandomValue = rand() % 4;
my2ndOwnRandomValue = rand() % 4;
columnsAndRows=columns[my1stOwnRandomValue]+rows[my2ndOwnRandomValue];
This does not address "with no repeats", to do so you need more code. You may keep a list of 'used' values, or create a list of all possible combinations (after all there are only 16) and pick one at random from this list, then remove the picked combination from the list.
you can use time as the seed of random function this can aviod pseudo-random
srand((unsigned) time(NULL)); /*set seed must #include <time.h>*/
for(int i=0; i<10; i++) {
for(int j=0; j<10; j++) {
columnValue=rand() % 4;
rowValue=rand() % 4;
columnsAndRows=columns[columnValue]+row[rowValue];
}
}
Here's a C++11 version:
#include <random>
#include <algorithm>
#include <iostream>
#include <cstddef>
#include <vector>
// helper to get the size (extent) of a raw array
template<class T, std::size_t N>
constexpr std::size_t get_extent(T&)
{ return std::extent<T>::value; }
int main()
{
std::string const chars[] = {"A","B","C"};
std::string const digits[] = {"1","2","3","4"};
// vector containing the resulting strings
std::vector<std::string> result;
// create the "ordered" sequence A1, A2, A3, A4, B1, ..
for(auto const& eChar : chars)
for(auto const& eDigit : digits)
result.push_back( eChar+eDigit );
// shuffle the sequence
{
// random device to seed the PRNG
std::random_device rd;
// create a MT19937 PRNG, seeded
std::mt19937 g(rd());
std::shuffle(begin(result), end(result), g);
}
// output result
for(auto const& e : result) std::cout << e << ", ";
std::cout << "\n";
}
A C++03 version:
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <iterator>
#include <iostream>
#include <cstddef>
#include <vector>
// helper to get the size (extent) of a raw array
template<class T, std::size_t N>
std::size_t get_extent(T (&)[N])
{ return N; }
int main()
{
std::string const chars[] = {"A","B","C"};
std::string const digits[] = {"1","2","3","4"};
// vector containing the resulting strings
typedef std::vector<std::string> result_t;
result_t result;
// create the "ordered" sequence A1, A2, A3, A4, B1, ..
for(std::string const* pChar = chars;
pChar != chars + get_extent(chars);
++pChar)
for(std::string const* pDigit = digits;
pDigit != digits + get_extent(digits);
++pDigit)
result.push_back( *pChar+*pDigit );
// shuffle the sequence
{
std::srand( std::time(NULL) );
std::random_shuffle(result.begin(), result.end());
}
// output result
std::copy(result.begin(), result.end(),
std::ostream_iterator<std::string>(std::cout, ", "));
std::cout << "\n";
}
string strcat1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string strcat2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int stringl1 = strcat1.size() - 1;
int stringl2 = strcat1.size() - 1;
auto strfn1 = [&]() {return strcat2[rand() % stringl2];}; //will return a single char
auto strfn2 = [&]() {return strcat2[rand() % stringl2];};
while (true)
{
this_thread::sleep_for(500ms);
std::string str1(1, strfn1()); //fill 1 string/char space with arg2 here strfn1
std::string str2(1, strfn2());
std::string str3(1, strfn2());
str1 += str2;
str1 = str3 + str2 + str1 + str3; //as many adjacent string as you want
cout << str1<<" ";
}
#Jongware
You can avoid generating a number larger than the provided range by using the minimum and the difference between the maximum and minimum range instead.
So rather than:
int x = rand() % max + min;
Use:
int diff = max - min;
int x = rand() % diff + min;