जवाबों:
मेहरदाद अफशरी का जवाब है कि यह चाल चली जाएगी, लेकिन मुझे यह आसान काम के लिए थोड़ा सा भी मिला। लुक-अप टेबल कभी-कभी चमत्कार कर सकती हैं:
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;
}
s[len] = 0
गलत है। यदि s
C स्ट्रिंग (NULL समाप्त) है, तो विधि के हस्ताक्षर में len
पैरामीटर नहीं होना चाहिए । Imo, यदि आप एक तर्क के रूप में लंबाई से गुजर रहे हैं, तो आप मान रहे हैं कि सरणी C स्ट्रिंग नहीं है। इस प्रकार, यदि आप फ़ंक्शन के लिए सी स्ट्रिंग पास नहीं कर रहे हैं, तो लाइन s[len] = 0
चीजों को तोड़ सकती है, क्योंकि सरणी 0 से लेन -1 तक जाएगी। और यहां तक कि अगर आप फ़ंक्शन के लिए एक सी स्ट्रिंग पास कर रहे हैं तो लाइन s[len] = 0
बेमानी होगी।
यहाँ C ++ 11 का उपयोग करके Ates गोरल के उत्तर का मेरा अनुकूलन है। मैंने यहां लंबोदर को जोड़ा है, लेकिन सिद्धांत यह है कि आप इसे पास कर सकते हैं और इस बात को नियंत्रित कर सकते हैं कि आपके स्ट्रिंग में कौन से अक्षर हैं
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;
}
यहाँ एक लंबो में यादृच्छिक स्ट्रिंग फ़ंक्शन में पास होने का एक उदाहरण है: 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;
}
rand()
आपके पहले कोड स्निपेट का उपयोग नहीं करना बेहतर है ?
rand()
नहीं होगा। ज़ोर से रोने के लिए भी यह एक समान नहीं है ...
मेरा 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;
}
default_random_engine
इसके बजाय का उपयोग करें mt19937
? कोड अधिक सामान्य लगेगा।
std::default_random_engine
कुछ ऐसा नहीं है जिसे मैं सिफारिश करने में अच्छा महसूस करता हूं क्योंकि मानक कार्यान्वयन के बीच इसकी गुणवत्ता, दक्षता या दोहराव के बारे में कोई गारंटी नहीं देता है।
sizeof
auto&
std::string
std::string::length
std::string
करना धीमा होने की संभावना थी क्योंकि इसमें इसके डेटा के लिए एक आंतरिक सूचक होता है। इसका मतलब यह होगा कि एक अतिरिक्त अप्रत्यक्ष रूप से एक स्थिर सरणी की आवश्यकता नहीं है। इसके अलावा sizeof
कभी धीमा नहीं हो सकता std::string::size
क्योंकि यह एक संकलन समय स्थिर है।
std::size
तब तक दिखाई नहीं दिया C++17
और अभी भी बहुत सारे लोग केवल कोडिंग कर रहे हैं C++11/14
इसलिए मैं इसे छोड़ दूंगा क्योंकि यह अभी के लिए है।
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;
}
मैंने अभी इसका परीक्षण किया है, यह मीठा काम करता है और लुकअप टेबल की आवश्यकता नहीं है। 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;
}
मैन्युअल रूप से लूप करने के बजाय , इस मामले में उचित यादृच्छिक संख्या जनरेटर के साथ , उपयुक्त C ++ एल्गोरिथ्म का उपयोग करना पसंद करें :std::generate_n
auto generate_random_alphanumeric_string(std::size_t len) -> std::string {
static constexpr auto chars =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
thread_local auto rng = random_generator<>();
auto dist = std::uniform_int_distribution{{}, std::strlen(chars) - 1};
auto result = std::string(len, '\0');
std::generate_n(begin(result), len, [&]() { return chars[dist(rng)]; });
return result;
}
यह कुछ ऐसा है जो मैं इस समस्या के लिए "विहित" समाधान कहूंगा।
दुर्भाग्य से, जेनेरिक C ++ यादृच्छिक संख्या जनरेटर (जैसे MT19937) को सही ढंग से बोना वास्तव में कठिन है । इसलिए उपरोक्त कोड एक सहायक फ़ंक्शन टेम्पलेट का उपयोग करता है random_generator
:
template <typename T = std::mt19937>
auto random_generator() -> T {
auto constexpr seed_bits = sizeof(typename T::result_type) * T::state_size;
auto constexpr seed_len = seed_bits / std::numeric_limits<std::seed_seq::result_type>::digits;
auto seed = std::array<std::seed_seq::result_type, seed_len>{};
auto dev = std::random_device{};
std::generate_n(begin(seed), seed_len, std::ref(dev));
auto seed_seq = std::seed_seq(begin(seed), end(seed));
return T{seed_seq};
}
यह जटिल और अपेक्षाकृत अक्षम है। सौभाग्य से इसे इनिशियलाइज़ करने के लिए उपयोग किया जाता हैthread_local
चर और इसलिए केवल एक बार प्रति थ्रेड के रूप में लागू किया जाता है।
अंत में, उपरोक्त के लिए आवश्यक शामिल हैं:
#include <algorithm>
#include <array>
#include <cstring>
#include <functional>
#include <limits>
#include <random>
#include <string>
उपरोक्त कोड वर्ग टेम्पलेट तर्क कटौती का उपयोग करता है और इस प्रकार C ++ 17 की आवश्यकता होती है। यह आवश्यक टेम्पलेट तर्कों को जोड़कर पूर्व संस्करणों के लिए तुच्छ रूप से अनुकूलित किया जा सकता है।
std::size_t
है std::uniform_int_distribution
? मैं किसी भी अन्य CTAD
rng
एक डिफ़ॉल्ट पैरामीटर के रूप में सुझाव देने का प्रलोभन दिया जा रहा है , जैसे किtemplate <typename T = std::mt19937> inline thread_local T default_rng = get_random_generator<T>();
std::uniform_int_distribution<>
, जो सुरक्षित होगा, लेकिन हस्ताक्षरित -> अहस्ताक्षरित रूपांतरण के बारे में चेतावनी दे सकता है।
मुझे उम्मीद है इससे किसी को सहायता मिलेगी।
Https://www.codechef.com/ide पर C ++ 4.9.2 के साथ परीक्षण किया गया
#include <iostream>
#include <string>
#include <stdlib.h> /* srand, rand */
using namespace std;
string RandomString(int len)
{
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()
{
srand(time(0));
string random_str = RandomString(100);
cout << "random_str : " << random_str << endl;
}
Output:
random_str : DNAT1LAmbJYO0GvVo4LGqYpNcyK3eZ6t0IN3dYpHtRfwheSYipoZOf04gK7OwFIwXg2BHsSBMB84rceaTTCtBC0uZ8JWPdVxKXBd
RandomString(100)
:! ;-)
std::srand()
वास्तव में केवल कार्यक्रम की शुरुआत में एक बार बुलाया जाना चाहिए (अधिमानतः पहली बात main()
)। कोड, जैसा कि है, एक समान "यादृच्छिक" तार का एक बहुत उत्पन्न करेगा यदि एक तंग लूप में कहा जाता है।
#include <iostream>
#include <string>
#include <random>
std::string generateRandomId(size_t length = 0)
{
static const std::string allowed_chars {"123456789BCDFGHJKLMNPQRSTVWXZbcdfghjklmnpqrstvwxz"};
static thread_local std::default_random_engine randomEngine(std::random_device{}());
static thread_local std::uniform_int_distribution<int> randomDistribution(0, allowed_chars.size() - 1);
std::string id(length ? length : 32, '\0');
for (std::string::value_type& c : id) {
c = allowed_chars[randomDistribution(randomEngine)];
}
return id;
}
int main()
{
std::cout << generateRandomId() << std::endl;
}
std::string
std::string::value_type[]
कुछ भी सरल और अधिक बुनियादी मामले में आप अपनी स्ट्रिंग के लिए किसी भी मुद्रण योग्य वर्ण शामिल करने के लिए खुश हैं:
#include <time.h> // we'll use time for the seed
#include <string.h> // this is for strcpy
void randomString(int size, char* output) // pass the destination size and the destination itself
{
srand(time(NULL)); // seed with time
char src[size];
size = rand() % size; // this randomises the size (optional)
src[size] = '\0'; // start with the end of the string...
// ...and work your way backwards
while(--size > -1)
src[size] = (rand() % 94) + 32; // generate a string ranging from the space character to ~ (tilde)
strcpy(output, src); // store the random string
}
रैंडम स्ट्रिंग, हर रन फ़ाइल = अलग स्ट्रिंग
auto randchar = []() -> char
{
const char charset[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
const size_t max_index = (sizeof(charset) - 1);
return charset[randomGenerator(0, max_index)];
};
std::string custom_string;
size_t LENGTH_NAME = 6 // length of name
generate_n(custom_string.begin(), LENGTH_NAME, randchar);
std::generate_n
मान लिया जाएगा कि custom_string
लंबाई है LENGTH_NAME
, लेकिन ऐसा नहीं है।
Qt उपयोग के लिए उदाहरण :)
QString random_string(int length=32, QString allow_symbols=QString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")) {
QString result;
qsrand(QTime::currentTime().msec());
for (int i = 0; i < length; ++i) {
result.append(allow_symbols.at(qrand() % (allow_symbols.length())));
}
return result;
}
चलो फिर से यादृच्छिक सुविधाजनक बनाओ!
मैंने एक अच्छा सी ++ 11 हेडर केवल समाधान बनाया। आप आसानी से अपनी परियोजना में एक हेडर फ़ाइल जोड़ सकते हैं और फिर अपने परीक्षण जोड़ सकते हैं या अन्य उद्देश्यों के लिए यादृच्छिक तार का उपयोग कर सकते हैं।
यह एक त्वरित विवरण है, लेकिन आप पूर्ण कोड की जांच करने के लिए लिंक का अनुसरण कर सकते हैं। समाधान का मुख्य भाग रैंडम श्रेणी में है:
class Randomer {
// random seed by default
std::mt19937 gen_;
std::uniform_int_distribution<size_t> dist_;
public:
/* ... some convenience ctors ... */
Randomer(size_t min, size_t max, unsigned int seed = std::random_device{}())
: gen_{seed}, dist_{min, max} {
}
// if you want predictable numbers
void SetSeed(unsigned int seed) {
gen_.seed(seed);
}
size_t operator()() {
return dist_(gen_);
}
};
Randomer
सभी बेतरतीब सामान को समाप्त कर देता है और आप आसानी से इसमें अपनी कार्यक्षमता जोड़ सकते हैं। हमारे पास होने के बाद Randomer
, तार उत्पन्न करना बहुत आसान है:
std::string GenerateString(size_t len) {
std::string str;
auto rand_char = [](){ return alphabet[randomer()]; };
std::generate_n(std::back_inserter(str), len, rand_char);
return str;
}
नीचे दिए गए सुधार के लिए अपने सुझाव लिखें। https://gist.github.com/VjGusev/e6da2cb4d4b0b531c1d009cd1f8904ad
फिर भी एक और अनुकूलन क्योंकि गैर जवाब मेरी जरूरतों को पूरा करेगा। सबसे पहले यदि रैंड () का उपयोग यादृच्छिक संख्या उत्पन्न करने के लिए किया जाता है तो आपको प्रत्येक रन पर समान आउटपुट मिलेगा। यादृच्छिक संख्या जनरेटर के लिए बीज को किसी प्रकार का यादृच्छिक होना चाहिए। C ++ 11 के साथ आप "यादृच्छिक" लाइब्रेरी शामिल कर सकते हैं और आप random_device और mt19937 के साथ बीज को इनिशियलाइज़ कर सकते हैं। इस बीज की आपूर्ति ओएस द्वारा की जाएगी और यह हमारे लिए पर्याप्त होगा (उदाहरण के लिए: घड़ी)। आप दे सकते हैं एक सीमा मेरे मामले में [0,25] शामिल हैं। और अंतिम लेकिन कम से कम मुझे केवल लोअरकेस अक्षरों के यादृच्छिक स्ट्रिंग की आवश्यकता थी इसलिए मैंने चार जोड़ का उपयोग किया। वर्णों के एक पूल के साथ दृष्टिकोण मेरे लिए काम नहीं करता था।
#include <random>
void gen_random(char *s, const int len){
static std::random_device rd;
static std::mt19937 mt(rd());
static std::uniform_int_distribution<int> dist(0, 25);
for (int i = 0; i < len; ++i) {
s[i] = 'a' + dist(mt);
}
s[len] = 0;
}
//C++ Simple Code
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<char> alphanum =
{'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'
};
string s="";
int len=5;
srand(time(0));
for (int i = 0; i <len; i++) {
int t=alphanum.size()-1;
int idx=rand()%t;
s+= alphanum[idx];
}
cout<<s<<" ";
return 0;
}
फ़ंक्शन को कॉल करते समय वेयर करें
string gen_random(const int len) {
static const char alphanum[] = "0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
stringstream ss;
for (int i = 0; i < len; ++i) {
ss << alphanum[rand() % (sizeof(alphanum) - 1)];
}
return ss.str();
}
( @Ates गोरल के अनुकूलित ) यह हर बार एक ही चरित्र अनुक्रम में परिणाम होगा। उपयोग
srand(time(NULL));
फ़ंक्शन को कॉल करने से पहले, हालांकि रैंड () फ़ंक्शन को हमेशा 1 @kjfletch के साथ वरीयता दी जाती है ।
उदाहरण के लिए:
void SerialNumberGenerator() {
srand(time(NULL));
for (int i = 0; i < 5; i++) {
cout << gen_random(10) << endl;
}
}
#include <iostream>
#include <string>
#include <stdlib.h>
int main()
{
int size;
std::cout << "Enter size : ";
std::cin >> size;
std::string str;
for (int i = 0; i < size; i++)
{
auto d = rand() % 26 + 'a';
str.push_back(d);
}
for (int i = 0; i < size; i++)
{
std::cout << str[i] << '\t';
}
return 0;
}
void strGetRandomAlphaNum(char *sStr, unsigned int iLen)
{
char Syms[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
unsigned int Ind = 0;
srand(time(NULL) + rand());
while(Ind < iLen)
{
sStr[Ind++] = Syms[rand()%62];
}
sStr[iLen] = '\0';
}