如何防止c++中随机生成选项的重复
How to prevent repetition of randomly generated options in C++?
这是我到目前为止所做的,我尽了最大的努力标记代码的每个位。值得注意的是,这是用XCode编写的,所以它是在Mac上运行的。
/*
Ayush Sharma
4 November 2016
*/
#include <iostream>
#include <ctime>
using namespace std;
int main (){
//clearing the screen
system("clear");
//seeding the random
srand((unsigned int)time(NULL));
//variables & arrays
char answer;
int r, m, correct = 0;
string capitals[50] =
{"Montgomery", "Juneau", "Phoenix", "Little Rock", "Sacramento", "Denver", "Hartford", "Dover", "Tallahassee", "Atlanta", "Honolulu", "Boise", "Springfield", "Indianapolis", "Des Moines", "Topeka", "Frankfort", "Baton Rouge", "Augusta", "Annapolis", "Boston", "Lansing", "St. Paul", "Jackson", "Jefferson City", "Helena", "Lincoln", "Carson City", "Concord", "Trenton", "Santa Fe", "Albany", "Raleigh", "Bismarck", "Columbus", "Oklahoma City", "Salem", "Harrisburg", "Providence", "Columbia", "Pierre", "Nashville", "Austin", "Salt Lake City", "Montpelier", "Richmond", "Olympia", "Charleston", "Madison", "Cheyenne"};
string states[50] = {"Alabama","Alaska","Arizona","Arkansas","California","Colorado","Connecticut","Delaware","Florida","Georgia","Hawaii","Idaho","Illinois","Indiana","Iowa","Kansas","Kentucky","Louisiana","Maine","Maryland","Massachusetts","Michigan","Minnesota","Mississippi","Missouri","Montana","Nebraska","Nevada","New Hampshire","New Jersey","New Mexico","New York","North Carolina","North Dakota","Ohio","Oklahoma","Oregon","Pennsylvania","Rhode Island","South Carolina","South Dakota","Tennessee","Texas","Utah","Vermont","Virginia","Washington","West Virginia","Wisconsin","Wyoming"};
//title
cout << "***************************************************************n";
cout << "* *n";
cout << "* United States Capitals Quiz *n";
cout << "* *n";
cout << "***************************************************************nn";
for (int i = 0; i < 15; i++){
//Picking A Random State
r = rand() % 50;
//Checking if State is a Repeat
if (states[r] != "-1") {
cout << "What is the capital of " << states[r] << "? ";
//Picking Correct Answer Choice and Respective Layout
m = rand() % 4;
if (m == 0) {
cout << "nA: " << capitals[r] << endl;
cout << "B: " << capitals[rand()%50] << endl;
cout << "C: " << capitals[rand()%50] << endl;
cout << "D: " << capitals[rand()%50] << endl;
}
if (m == 1) {
cout << "nA: " << capitals[rand()%50] << endl;
cout << "B: " << capitals[r] << endl;
cout << "C: " << capitals[rand()%50] << endl;
cout << "D: " << capitals[rand()%50] << endl;
}
if (m == 2) {
cout << "nA: " << capitals[rand()%50] << endl;
cout << "B: " << capitals[rand()%50] << endl;
cout << "C: " << capitals[r] << endl;
cout << "D: " << capitals[rand()%50] << endl;
}
if (m == 3) {
cout << "nA: " << capitals[rand()%50] << endl;
cout << "B: " << capitals[rand()%50] << endl;
cout << "C: " << capitals[rand()%50] << endl;
cout << "D: " << capitals[r] << endl;
}
//Recieving Answer
cout << "Answer: ";
cin >> answer;
//Converting Letter to Number
if (answer == 'A' || answer == 'a') answer = 0; if (answer == 'B' || answer == 'b') answer = 1;
if (answer == 'C' || answer == 'c') answer = 2; if (answer == 'D' || answer == 'd') answer = 3;
//Comparing Answer to Correct Answer
if (m == answer) {
cout << "Correct!" << endl << endl;
correct++;
}else{
cout << "Incorrect! The correct answer was " << capitals[r] << "! nn";
}
//Removing State from Array
states[r] = "-1";
}else{
//If State was a Repeat, generate another State
i--;
}
}
//Printing Results
cout << "Number Correct: " << correct << "/15 or " << ((correct/15.00)*100) << "%!n";
return 0;
}
代码几乎可以工作。问题是答案有时会被重复,比如下面这个场景:威斯康辛州的首府是哪里?答:麦迪逊b .法兰克福c·杰克逊d·麦迪逊只有A或D是"正确"的答案,尽管它们有相同的文本(尽管我宁愿让答案不可能重复)。我也想知道是否有一种更有效的方法来创建选择题的布局。提前感谢!
-Ayush
假设您希望随机绘制50
值,而不需要重复,只需创建包含这些值的数组或向量,对其进行洗牌,然后按顺序访问洗牌数组中的元素。
在c++ 11中,这很容易使用<algorithm>
中的std::iota()
和std::random_shuffle()
算法。
int value[50];
std::iota(std::begin(value), std::end(value), 0); // populate array with values 0 to 49
std::random_shuffle(std::begin(value), std::end(value));
然后在你的外循环中,用r=value[i]
代替r = rand()%50
。
std::begin()
和std::end()
在标准标头<iterator>
中。
同样的想法可以在c++ 11之前使用,但方法有点不同(c++ 11不支持std::begin()
, std::end()
或std::iota()
,但等效的很容易实现)。
而不是value
是一个数组,我将它创建为std::vector<int>
,也有50个元素。我在上面使用数组来说明,因为您似乎默认使用数组。
这是很明显会发生的事情。一个简单的解决方案是创建一个数组来保存已经显示的选项。使用while循环向数组中添加唯一选项。您可以使用另一个函数检查数组中是否有任何重复。然后,显示capitals[r]
以及数组中的其他三个选项。
bool noRepeat(int arr[], int o){
for(int i=0; i<3; i++){
if(arr[i] == o)
return false;
}
return true;
}
int main(){
...
//picking correct answer and determining layout
int m = rand()%4, n=0, y, options[3];
if (m == 0) {
while(n<3){
y = rand()%50;
if(noRepeat(options, y) && capitals[y]!=capitals[r])
options[n++] = y;
}
//display according to layout
cout << "nA: " << capitals[r] << endl;
cout << "B: " << capitals[options[0]] << endl;
cout << "C: " << capitals[options[1]] << endl;
cout << "D: " << capitals[options[2]] << endl;
}
//do the same for the rest
...
}
就像@Isaiah说的,你可以使用while循环来测试生成的索引是否与你的正确答案不相同。
例如:
int index = rand() % 50;
while(index == r)
{
index = rand() % 50;
}
cout << "B: " << capitals[index] << endl;
注意:这仍然可以产生重复的"不正确的答案",但我猜你得到的点,以避免由rand
产生的重复。很明显,这个代码只是为了纠正正确答案的重复,你应该使用rand
,正如其他人在评论中提到的。
你的问题是随机选择三个没有重复的大写字母。下面是一些伪代码
- 将除正确答案外的所有答案都大写成矢量
- 生成一个随机索引到这个向量
- 在该索引处使用大写字母,并从矢量 中删除大写字母。
- 对第二个和第三个随机大写字母重复步骤2和3。注意随机索引应该允许在每次迭代中减少向量大小。
- 防止主数据类型C++的隐式转换
- 如何在选项卡视图Qt中设置一个新项目,并保存以前的项目
- Win32编译器选项和内存分配
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- 函数何时会在c++中包含stack_Unwind_Resume调用
- 将指针设置为"nullptr"并不能防止双重删除?
- C/C++预处理器是否可以检测一些编译器选项
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 如何防止C++遗留代码中的挂起指针
- 将--whole archive链接器选项与CMake和具有其他库依赖项的库一起使用
- Python中的for循环与C++有何不同
- 如何防止clang格式在流运算符调用之间添加换行符<<
- 通过选项卡的文本设置QTabWidget顺序
- 通过ccmake在cmake中缓存依赖选项
- 当我移动跟踪栏时,如何防止控件(选项卡)闪烁和消失与Windows通用控件6.0?
- 如何防止在 switch 语句中多次选择同一选项/值
- 如何防止用户多次选择一个选项
- 如何禁用控制+QTableView的快捷方式并防止全选选项
- 选项卡控件:如何防止所选内容发生更改
- 如何防止c++中随机生成选项的重复