随机字符串生成器 c++

Random string generator c++

本文关键字:c++ 字符串 随机      更新时间:2023-10-16

我想生成没有重复的字符串列表,如下所示

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 之间的伪随机整数。 我应该怎么做才能根据我想要的要求生成随机字符串?

std::rand与模一起使用可能不是一个好主意。相反,您可以轻松构造可能元素的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());

下面是运行代码的结果。


正如 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);

下面是运行代码的结果。

那为什么不能用rand()呢?因为它可能会返回太大的值?然后选择一个随机值,如果它太大,(a) 不要使用它,而是选择另一个或 (b) 使用 %(模)运算符剪掉太大的部分:

my1stOwnRandomValue = rand() % 4;
my2ndOwnRandomValue = rand() % 4;
columnsAndRows=columns[my1stOwnRandomValue]+rows[my2ndOwnRandomValue];

这不会解决"没有重复"的问题,为此,您需要更多代码。您可以保留"已使用"值的列表,或创建所有可能组合的列表(毕竟只有 16 个)并从此列表中随机选择一个,然后从列表中删除选择的组合。

你可以用时间作为随机函数的种子,这可以 aviod 伪随机

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];
    }
}

这是一个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";
}
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

您可以通过改用最小值以及最大值和最小范围之间的差值来避免生成大于提供范围的数字。

所以而不是:

int x = rand() % max + min;

用:

int diff = max - min;
int x = rand() % diff + min;