jm.*_*jm. 164 c++ string random
我想创建一个随机字符串,由字母数字字符组成.我希望能够指定字符串的长度.
我如何在C++中执行此操作?
Ate*_*ral 269
Mehrdad Afshari的回答可以解决问题,但我发现这个简单的任务有点过于冗长.查找表有时可以创造奇迹:
void gen_random(char *s, const int len) {
static const char alphanum[] =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
for (int i = 0; i < len; ++i) {
s[i] = alphanum[rand() % (sizeof(alphanum) - 1)];
}
s[len] = 0;
}
Run Code Online (Sandbox Code Playgroud)
Car*_*arl 100
这是我使用C++ 11改编Ates Goral的答案.我在这里添加了lambda,但原则是你可以传入它,从而控制你的字符串包含的字符:
std::string random_string( size_t length )
{
auto randchar = []() -> char
{
const char charset[] =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
const size_t max_index = (sizeof(charset) - 1);
return charset[ rand() % max_index ];
};
std::string str(length,0);
std::generate_n( str.begin(), length, randchar );
return str;
}
Run Code Online (Sandbox Code Playgroud)
下面是将lambda传递给随机字符串函数的示例:http://ideone.com/Ya8EKf
为什么要使用C++ 11?
例如:
#include <iostream>
#include <vector>
#include <random>
#include <functional> //for std::function
#include <algorithm> //for std::generate_n
typedef std::vector<char> char_array;
char_array charset()
{
//Change this to suit
return char_array(
{'0','1','2','3','4',
'5','6','7','8','9',
'A','B','C','D','E','F',
'G','H','I','J','K',
'L','M','N','O','P',
'Q','R','S','T','U',
'V','W','X','Y','Z',
'a','b','c','d','e','f',
'g','h','i','j','k',
'l','m','n','o','p',
'q','r','s','t','u',
'v','w','x','y','z'
});
};
// given a function that generates a random character,
// return a string of the requested length
std::string random_string( size_t length, std::function<char(void)> rand_char )
{
std::string str(length,0);
std::generate_n( str.begin(), length, rand_char );
return str;
}
int main()
{
//0) create the character set.
// yes, you can use an array here,
// but a function is cleaner and more flexible
const auto ch_set = charset();
//1) create a non-deterministic random number generator
std::default_random_engine rng(std::random_device{}());
//2) create a random number "shaper" that will give
// us uniformly distributed indices into the character set
std::uniform_int_distribution<> dist(0, ch_set.size()-1);
//3) create a function that ties them together, to get:
// a non-deterministic uniform distribution from the
// character set of your choice.
auto randchar = [ ch_set,&dist,&rng ](){return ch_set[ dist(rng) ];};
//4) set the length of the string you want and profit!
auto length = 5;
std::cout<<random_string(length,randchar)<<std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Gal*_*lik 30
我的2p解决方案:
#include <random>
#include <string>
std::string random_string(std::string::size_type length)
{
static auto& chrs = "0123456789"
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
thread_local static std::mt19937 rg{std::random_device{}()};
thread_local static std::uniform_int_distribution<std::string::size_type> pick(0, sizeof(chrs) - 2);
std::string s;
s.reserve(length);
while(length--)
s += chrs[pick(rg)];
return s;
}
Run Code Online (Sandbox Code Playgroud)
Meh*_*ari 15
void gen_random(char *s, size_t len) {
for (size_t i = 0; i < len; ++i) {
int randomChar = rand()%(26+26+10);
if (randomChar < 26)
s[i] = 'a' + randomChar;
else if (randomChar < 26+26)
s[i] = 'A' + randomChar - 26;
else
s[i] = '0' + randomChar - 26 - 26;
}
s[len] = 0;
}
Run Code Online (Sandbox Code Playgroud)
我刚试过这个,它很好用,不需要查找表.rand_alnum()有点强制使用字母数字,但因为它从可能的256个字符中选择了62个,这不是什么大问题.
#include <cstdlib> // for rand()
#include <cctype> // for isalnum()
#include <algorithm> // for back_inserter
#include <string>
char
rand_alnum()
{
char c;
while (!std::isalnum(c = static_cast<char>(std::rand())))
;
return c;
}
std::string
rand_alnum_str (std::string::size_type sz)
{
std::string s;
s.reserve (sz);
generate_n (std::back_inserter(s), sz, rand_alnum);
return s;
}
Run Code Online (Sandbox Code Playgroud)
我倾向于总是使用结构化的C++方法进行这种初始化.请注意,从根本上说,它与Altan的解决方案没有什么不同.对于C++程序员来说,它只是表达了更好的意图,并且可以更容易地移植到其他数据类型.在这个例子中,C++函数generate_n完全表达了你想要的:
struct rnd_gen {
rnd_gen(char const* range = "abcdefghijklmnopqrstuvwxyz0123456789")
: range(range), len(std::strlen(range)) { }
char operator ()() const {
return range[static_cast<std::size_t>(std::rand() * (1.0 / (RAND_MAX + 1.0 )) * len)];
}
private:
char const* range;
std::size_t len;
};
std::generate_n(s, len, rnd_gen());
s[len] = '\0';
Run Code Online (Sandbox Code Playgroud)
顺便说一下,请阅读Julienne的文章,了解为什么这个指数的计算比简单的方法(如取模数)更受欢迎.
我希望这可以帮助别人.
使用C++ 4.9.2 在https://www.codechef.com/ide上测试
#include <iostream>
#include <string>
#include <stdlib.h> /* srand, rand */
using namespace std;
string RandomString(int len)
{
srand(time(0));
string str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
string newstr;
int pos;
while(newstr.size() != len) {
pos = ((rand() % (str.size() - 1)));
newstr += str.substr(pos,1);
}
return newstr;
}
int main()
{
string random_str = RandomString(100);
cout << "random_str : " << random_str << endl;
}
Run Code Online (Sandbox Code Playgroud)
Output:
random_str : DNAT1LAmbJYO0GvVo4LGqYpNcyK3eZ6t0IN3dYpHtRfwheSYipoZOf04gK7OwFIwXg2BHsSBMB84rceaTTCtBC0uZ8JWPdVxKXBd
标准库中最合适的函数是std::sample:
#include <algorithm>
#include <iterator>
#include <random>
#include <string>
#include <iostream>
static const char charset[] =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
template<typename URBG>
std::string gen_string(std::size_t length, URBG&& g) {
std::string result;
result.resize(length);
std::sample(std::cbegin(charset),
std::cend(charset),
std::begin(result),
std::intptr_t(length),
std::forward<URBG>(g));
return result;
}
int main() {
std::mt19937 g;
std::cout << gen_string(10, g) << std::endl;
std::cout << gen_string(10, g) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
随机数生成器的状态应在调用之间保持在函数之外。
这是一个有趣的单线。需要 ASCII。
void gen_random(char *s, int l) {
for (int c; c=rand()%62, *s++ = (c+"07="[(c+16)/26])*(l-->0););
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
181900 次 |
| 最近记录: |