我需要选择m个随机字符(字母)而不重复并且我完全卡住,我一直只收到1个随机字母。我该如何修复我的代码?有没有办法解决这个问题,或者我应该废弃这个想法,并从一些kinf od教程中寻找解决方案?
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <string>
using namespace std;
int main()
{
cout << "number below 27" << endl;
int m;
cin >> m;
srand(time(NULL));
bool repeat = false;
char letters[m];
char letter;
for(int i = 0; i < m; i++){
letter = rand()%26 +97;
repeat = true;
for(int j = 0; j < m; j++){
if(letters[m] == letters[j]){
repeat = false;
break;
}
}
if(repeat){
letters[m] = letter;
}
}
for (int i = 0; i < m; i++){
cout << letters[m];
}
}
答案 0 :(得分:3)
您可以使用后缀 -
#include <random>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main ()
{
char charSet[]={'a','b','c'};//You can add all the charecters
std::random_device rd;
std::mt19937 g(rd());
std::shuffle(charSet,charSet+3,g);
for(auto c : charSet)
{
std::cout<<c;
}
std::cout<<endl;
return 0;
}
答案 1 :(得分:0)
您的代码逻辑中存在明显错误:当您测试重复时,您只与结束字母之外的内容进行比较,而不是与目前为止所有采样的内容进行比较。正确的测试将是
for(int i = 0; i < m; i++) {
bool repeating;
char tryletter;
do {
tryletter = rand()%26 +97;
repeating = false;
for(auto j=0; j!=i && !repeating; ++j)
repeating = tryletter == letters[j];
} while(repeating);
letters[i] = tryletter;
}
虽然不是最有效的方式来执行您要求的操作。一种更有效的方法是从所有26个字母开始,随机选择一个并从集合中删除它,然后继续挑选和删除随机字母。例如
std::string random_letters_without_repetition(std::size_t m)
{
std::string letters;
std::string all = "abcdefghijklmnopqrstuvwxyz";
assert(m <= all.size());
std::random_device r;
std::default_random_engine rng(r());
while(m--) {
std::uniform_int_distribution<std::size_t> uni{0,all.size()-1};
auto index = uni(rng);
letters += all[index];
all.erase(index);
}
return letters;
}
答案 2 :(得分:0)
for (int i = 0; i < m; i++){
cout << letters[i];
}
您重复随机数生成器,直到您有一个唯一的随机数。 并输出您的值使用i,因为m是常量且超出界限:
{{1}}
答案 3 :(得分:0)
我认为直接方法是在C ++中使用set
。刚刚使用set
完成以下解决方案以确保唯一。希望它可能会有所帮助。
#include <iostream>
#include <ctime>
#include <set>
#include <random>
using namespace std;
int main()
{
cout << "number below 27" << endl;
int m;
cin >> m;
srand(time(NULL));
set<char> letters_set;
while(letters_set.size() < m){
char c = rand()%26+'a';
letters_set.insert(c);
}
for(auto c: letters_set)
cout<<c<<endl;
}
更有效的解决方案,也确保每个字母的可能性相同。
#include <iostream>
#include <ctime>
#include <set>
#include <random>
using namespace std;
int main()
{
cout << "number below 27" << endl;
int m;
cin >> m;
srand(time(NULL));
vector<int> all_letters(26, 'a');
for(int i = 0; i < 26; ++i) all_letters[i] += i;
vector<char> letters_set;
for(int i = 0; i < m; ++i){
int select = rand()%all_letters.size();
letters_set.push_back(all_letters[select]);
all_letters.erase(all_letters.begin()+select);
}
for(auto c: letters_set)
cout<<c<<endl;
}