উত্তর:
মেহরদাদ আফশারীর উত্তরটি কৌশলটি করবে, তবে আমি এই সাধারণ কাজের জন্য এটি কিছুটা ভার্ভোজ পেয়েছি। সন্ধানের টেবিলগুলি মাঝে মাঝে বিস্ময়কর করতে পারে:
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
কোনও সি স্ট্রিং (NULL সমাপ্ত) হয় তবে পদ্ধতির স্বাক্ষরটির মধ্যে len
প্যারামিটার থাকতে হবে না । তবে, আপনি যদি আর্গুমেন্ট হিসাবে দৈর্ঘ্যটি অতিক্রম করছেন, আপনি ধরে নিচ্ছেন অ্যারেটি কোনও স্ট্রিং নয়। সুতরাং, আপনি যদি ফাংশনে সি স্ট্রিংটি না দিয়ে s[len] = 0
যাচ্ছেন তবে লাইনটি জিনিসগুলি ভেঙে ফেলতে পারে, যেহেতু অ্যারে 0 থেকে লেন -1 এ যায়। এমনকি আপনি যদি ফাংশনটিতে একটি সি স্ট্রিং দিয়ে যাচ্ছেন তবে লাইনটি s[len] = 0
অনর্থক হবে।
সি ++ 11 ব্যবহার করে আমার অ্যাটেস গোরালের উত্তরটির আমার অভিযোজন এটি এখানে। আমি এখানে ল্যাম্বডা যুক্ত করেছি, তবে নীতিটি হ'ল আপনি এটিকে পাস করতে পারেন এবং এর মাধ্যমে আপনার স্ট্রিংয়ে কী অক্ষর রয়েছে তা নিয়ন্ত্রণ করতে পারেন:
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
আপনি কেন সি ++ 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;
}
বরং নিজে লুপিং চেয়ে উপযুক্ত ব্যবহার পছন্দ সি ++ অ্যালগরিদম এই ক্ষেত্রে 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;
}
এটি এই সমস্যার কাছাকাছি যা আমি এই সমস্যার জন্য "আধ্যাত্মিক" সমাধান বলব।
দুর্ভাগ্যক্রমে, জেনেরিক সি ++ র্যান্ডম সংখ্যার জেনারেটর যথাযথভাবে বপন করা (উদাহরণস্বরূপ 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
? আমি অন্য কোনও সিটিএডি দেখতে পাচ্ছি না
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 এ পরীক্ষিত
#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
সমস্ত এলোমেলো জিনিস incapsulates এবং আপনি সহজেই এটি আপনার নিজস্ব কার্যকারিতা যুক্ত করতে পারেন। আমাদের থাকার পরে 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
তবুও অন্য অভিযোজন কারণ উত্তর না আমার প্রয়োজনীয়তা যথেষ্ট হবে। সবার আগে যদি র্যান্ড () ব্যবহার করা হয় এলোমেলো সংখ্যা তৈরি করতে আপনি প্রতিটি রানে একই আউটপুট পাবেন। এলোমেলো সংখ্যা জেনারেটরের জন্য বীজটি কিছুটা এলোমেলো হতে হবে। সি ++ 11 এর মাধ্যমে আপনি "এলোমেলো" লাইব্রেরি অন্তর্ভুক্ত করতে পারেন এবং আপনি এলোমেলো_দেবতা এবং 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();
}
( @ অ্যাটেস গোলালের সাথে অভিযোজিত ) এর ফলে প্রতিবার একই চরিত্রের ক্রম হবে। ব্যবহার
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';
}