我想生成没有重复的字符串列表,如下所示
A1,A2,A3,A4,B1,B2,B3,B4,C1,C2,C3,C4
这是我生成字符串列表的方式
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();
}
}
但问题是,我读了一下rand()并返回0到RAND_MAX范围内的伪随机整数。我该怎么做才能根据我想要的要求生成随机字符串?
答案 0 :(得分:4)
将std::rand
与模数might not be a good idea一起使用。相反,您可以轻松构建std::vector
个可能的元素,并在该容器上执行std::random_shuffle
:
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());
这是running代码结果。
正如DyP暗示的那样,std::random_shuffle
可能会在其实现中使用rand
(事实是它的实现已定义),因此您可能会遇到持续获得相同结果的问题并且因为你没有播种随机函数。
值得庆幸的是,C ++ 11引入了std::shuffle
,它允许我们传递第三个参数并定义我们自己的随机生成器函子。关于这一点的好处是我们可以轻松地使用<random>
来提供该论点:
std::mt19937 rand_func(std::random_device{}());
std::shuffle(vec.begin(), vec.end(), rand_func);
这是running代码结果。
答案 1 :(得分:1)
那你为什么不能使用rand()
?因为可能会返回太大的值?然后选择一个随机值,如果它太大,(a)不要使用它,而是使用%
(模数)运算符选择另一个或(b)剪掉太大的部分:
my1stOwnRandomValue = rand() % 4;
my2ndOwnRandomValue = rand() % 4;
columnsAndRows=columns[my1stOwnRandomValue]+rows[my2ndOwnRandomValue];
这不解决“没有重复”,为此您需要更多代码。您可以保留“已使用”值的列表,或创建所有可能组合的列表(毕竟只有16个)并从此列表中随机选择一个,然后从中删除所选的组合列表。
答案 2 :(得分:1)
你可以使用时间作为随机函数的种子,这可以避免伪随机
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];
}
}
答案 3 :(得分:1)
这是一个C ++ 11版本:
#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";
}
C ++ 03版本:
#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";
}
答案 4 :(得分:0)
@Jongware
您可以通过使用最小值和最小值范围之间的差异来避免生成大于提供范围的数字。
所以而不是:
int x = rand() % max + min;
使用:
int diff = max - min;
int x = rand() % diff + min;
答案 5 :(得分:0)
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<<" ";
}