Eu gostaria de criar uma sequência aleatória, composta por caracteres alfanuméricos. Eu quero poder especificar o comprimento da string.
Como faço isso em C ++?
A resposta de Mehrdad Afshari seria suficiente, mas eu achei isso um pouco detalhado demais para essa tarefa simples. Às vezes, as tabelas de consulta podem fazer maravilhas:
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
está incorreta. Ses
for uma string C (terminada em NULL), a assinatura do método não precisaria conter olen
parâmetro. Imo, se você está passando o comprimento como argumento, está assumindo que a matriz não é uma string C. Portanto, se você não estiver passando uma string C para a função, a linhas[len] = 0
poderá quebrar as coisas, pois a matriz passaria de 0 a len-1. E mesmo se você estiver passando uma string C para a função, a linhas[len] = 0
seria redundante.Aqui está minha adaptação da resposta de Ates Goral usando C ++ 11. Eu adicionei o lambda aqui, mas o princípio é que você pode passá-lo e, assim, controlar quais caracteres sua string contém:
Aqui está um exemplo de passagem de um lambda para a função de sequência aleatória: http://ideone.com/Ya8EKf
Por que você usaria C ++ 11 ?
Por exemplo:
Saída de amostra.
fonte
rand()
no seu primeiro snippet de código?rand()
mais. Não é nem uniforme para sair chorando ...Minha solução 2p:
fonte
default_random_engine
vez demt19937
? O código pareceria mais genérico.std::default_random_engine
não é algo que eu me recomendo em recomendar, pois o padrão não garante sua qualidade, eficiência ou repetibilidade entre implementações.sizeof
, mudar oauto&
questd::string
, o que lhe dástd::string::length
std::string
provavelmente era mais lento porque contém um ponteiro interno para seus dados. Isso significaria um indireção extra que uma matriz estática não requer. Tambémsizeof
nunca pode ser mais lento do questd::string::size
porque é uma constante de tempo de compilação.std::size
, não apareceu atéC++17
e ainda há muitas pessoas apenas codificando,C++11/14
então vou deixar como está por enquanto.fonte
Acabei de testar isso, funciona bem e não requer uma tabela de pesquisa. O rand_alnum () meio que expulsa os alfanuméricos, mas como seleciona 62 dos 256 caracteres possíveis, não é grande coisa.
fonte
Em vez de fazer um loop manual, prefira usar o algoritmo C ++ apropriado , neste caso
std::generate_n
, com um gerador de números aleatórios apropriado :Isso é próximo de algo que eu chamaria de solução "canônica" para esse problema.
Infelizmente, semear corretamente um gerador de números aleatórios C ++ genérico (por exemplo, MT19937) é realmente difícil . O código acima, portanto, usa um modelo de função auxiliar
random_generator
:Isso é complexo e relativamente ineficiente. Felizmente, é usado para inicializar uma
thread_local
variável e, portanto, é invocado apenas uma vez por thread.Finalmente, as inclusões necessárias para o acima são:
O código acima usa dedução de argumento de modelo de classe e, portanto, requer C ++ 17. Ele pode ser adaptado trivialmente para versões anteriores adicionando os argumentos de modelo necessários.
fonte
std::size_t
parastd::uniform_int_distribution
? Não consigo ver nenhum outro CTADrng
como parâmetro padrão, com algo comotemplate <typename T = std::mt19937> inline thread_local T default_rng = get_random_generator<T>();
std::uniform_int_distribution<>
, o que seria seguro, mas poderia avisar sobre conversão assinada -> não assinada.Espero que isso ajude alguém.
Testado em https://www.codechef.com/ide com C ++ 4.9.2
Output: random_str : DNAT1LAmbJYO0GvVo4LGqYpNcyK3eZ6t0IN3dYpHtRfwheSYipoZOf04gK7OwFIwXg2BHsSBMB84rceaTTCtBC0uZ8JWPdVxKXBd
fonte
RandomString(100)
! ;-)std::srand()
, só deve ser chamado uma vez no início do programa (de preferência a primeira coisa a entrarmain()
). O código, como está, gerará muitas seqüências "aleatórias" idênticas se chamadas em um loop restrito.Aqui está uma frase engraçada. Precisa de ASCII.
fonte
fonte
std::string
em vez destd::string::value_type[]
Algo ainda mais simples e mais básico, caso você esteja feliz por sua string conter caracteres imprimíveis:
fonte
Sequência aleatória, cada arquivo executado = sequência diferente
fonte
std::generate_n
assumirá ocustom_string
comprimentoLENGTH_NAME
, mas não o é.Exemplo para uso do Qt :)
fonte
Vamos tornar o acaso conveniente novamente!
Eu criei uma boa solução apenas para cabeçalho C ++ 11. Você pode facilmente adicionar um arquivo de cabeçalho ao seu projeto e, em seguida, adicionar seus testes ou usar seqüências aleatórias para outros fins.
Essa é uma descrição rápida, mas você pode seguir o link para verificar o código completo. A principal parte da solução está na classe Randomer:
Randomer
incorpora todas as coisas aleatórias e você pode adicionar suas próprias funcionalidades facilmente. Depois que tivermosRandomer
, é muito fácil gerar strings:Escreva suas sugestões para melhoria abaixo. https://gist.github.com/VjGusev/e6da2cb4d4b0b531c1d009cd1f8904ad
fonte
Mais uma adaptação, porque a falta de respostas bastaria para minhas necessidades. Antes de tudo, se rand () for usado para gerar números aleatórios, você obterá a mesma saída a cada execução. A semente do gerador de números aleatórios deve ser algum tipo de aleatória. Com o C ++ 11, você pode incluir a biblioteca "random" e inicializar a semente com random_device e mt19937. Essa semente será fornecida pelo sistema operacional e será aleatória o suficiente para nós (por exemplo, relógio). Você pode dar uma gama limites estão incluídos [0,25] no meu caso. E por último, mas não menos importante, eu só precisava de uma sequência aleatória de letras minúsculas, então utilizei a adição de caracteres. Com um conjunto de caracteres, a abordagem não funcionou para mim.
fonte
fonte
Cuidado ao chamar a função
(adaptado de @Ates Goral ), sempre resultará na mesma sequência de caracteres. Usar
antes de chamar a função, embora a função rand () seja sempre propagada com 1 @kjfletch .
Por exemplo:
fonte
fonte
fonte