C ++에서 임의의 영숫자 문자열을 어떻게 만듭니 까? 문자열을 만들고

영숫자 문자로 구성된 임의의 문자열을 만들고 싶습니다. 문자열의 길이를 지정할 수 있기를 원합니다.

C ++에서 어떻게해야합니까?



답변

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

답변

다음은 C ++ 11을 사용한 Ates Goral의 답변에 대한 적응입니다. 여기에 람다를 추가했지만 원칙은 전달하여 문자열에 포함 된 문자를 제어 할 수 있다는 것입니다.

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을 왜 사용 하시겠습니까?

  1. 관심있는 문자 집합에 대해 특정 확률 분포 (또는 분포 조합)를 따르는 문자열을 생성 할 수 있기 때문 입니다.
  2. 비 결정적 난수 를 기본적으로 지원하기 때문에
  3. 유니 코드를 지원하므로 국제화 된 버전으로 변경할 수 있습니다.

예를 들면 다음과 같습니다.

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

샘플 출력.


답변

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

답변

 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이 필요합니다. 필요한 템플릿 인수를 추가하여 이전 버전에 맞게 간단하게 조정할 수 있습니다.


답변

나는 이것이 누군가를 돕기를 바랍니다.

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)
{
   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