我会尽力描述我的问题,因为这是我第一次来这里:)
所以,我必须在C ++中编写一个程序,因为你可能或者可能没有从标题中猜到,打印出一系列随机数字,这些随机数字不会在数字本身和系列中重复。
我有4个“插槽”来填充数字系列。数字可以从0到4随机化(不能重复)。
我的意思是:
SLOT 1:1 3 2 4
SLOT 2:3 1 4 2< -----如您所见,它们不会水平重复,也不会垂直重复
SLOT 3:2 4 3 1
SLOT 4:4 2 1 3
这是我提出的代码,直到我被卡住(这是一个可怕的丑陋代码,我知道)
void MC_Slot_Rand()
{
text.setDefaultColor("white");//don't mind this
srand((unsigned)time(NULL));
int n1;
int n2;
int n3;
int n4;
int number;
int slotN = 0;
int slotN_2 = 1;
while (slotN < dim)
{
color.red();//don't mind this
cout << "SLOT " << slotN_2 << ": ";
color.white();//don't mind this either
n1 = 1;//RESET
//for some reason, if i don't put 1
// the program repeats the numbers
n2, n3, n4 = 10;//RESET
do
{
number = rand() % 4;
} while (number == n1);
n1 = number;
do
{
number = rand() % 4;
} while (number == n1);
n2 = number;
do
{
number = rand() % 4;
} while (number == n1 || number == n2);
n3 = number;
do
{
number = rand() % 4;
} while (number == n1 || number == n2 || number == n3);
n4 = number;
//cout << n1 << n2 << n3 << n4;//debug
MC_ENUM(n1);
MC_ENUM(n2);//this function simply takes the number and
//transforms it into a letter using a switch statement
// example: 0 = A, 1 = B, etcetera...
MC_ENUM(n3);
MC_ENUM(n4);
ut.spacer(3);//this function does cout<<endl; as many times
//as the number specifies
slotN++;
slotN_2++;
}
}//END OF FUNCTION
这段代码的作用是简单地打印4系列非重复数字,但数字是垂直重复的!当然,我不希望这种情况发生。
我希望那里比我更有经验的人可以帮助我:)。
非常重要:如果您想尝试使用此代码,请取消使用don't mind this
,MC_ENUM();
函数以及ut.spacer();
评论的行,因为它们是我的库的一部分并赢得了'与你合作:P
感谢您的时间。
答案 0 :(得分:0)
在这里你能做什么: 当您需要数字是唯一的,而不是生成随机数时,您所做的是生成所需的所有唯一数字的数组。在这种情况下,它是一个长度为4的数组,其值为[1,2,3,4]。 现在,使用已知良好的混洗算法随机地对阵列进行随机排列,该算法保证所有排列的机会几乎相等。如果您想阻止某个数字出现在同一个索引中,您可以轻松地在随机数中添加一个规则,该规则需要为每个随机数字添加唯一的位置。
这是另一种方法:这种方法特别适合小长度。生成所有可能的排列,然后随机选择一个排列。为了维护您的额外要求,您只需忽略不合适的排列。这种方法的一个明显优势是它完全是确定性的。
答案 1 :(得分:0)
据我所知,你正在做的是产生1-4号数字的所有排列的随机向量。
幸运的是答案在标准库中:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
bool column_match(const vector<int>& v1, const vector<int>& v2)
{
auto N = std::min(v1.size(), v2.size());
for (size_t i = 0 ; i < N ; ++i) {
if (v1[i] == v2[i])
return true;
}
return false;
}
int main()
{
vector<int> nums = { 1, 2, 3, 4 };
vector<vector<int>> series;
do {
series.push_back(nums);
} while (next_permutation(begin(nums), end(nums)));
random_shuffle(begin(series), end(series));
vector<vector<int>> result;
copy_if(begin(series), end(series), back_inserter(result), [&](const auto& candidate){
return !any_of(begin(result), end(result), [&](const auto& check){
return column_match(candidate, check);
});
});
for (const auto& s : result) {
copy(begin(s), end(s), ostream_iterator<int>(cout, ","));
cout << endl;
}
return 0;
}
示例输出:
4,3,1,2,
3,2,4,1,
1,4,2,3,
2,1,3,4,
Program ended with exit code: 0
答案 2 :(得分:0)
我认为你应该这样做,这是我的想法
首先,你应该像a [4] [4]那样定义arry,当它产生一个数字你将数字存储在arry中,然后产生下一个numbet,将它与水平中的其他数据进行水平比较,如果它重复并且然后生成下一个,如果没有并存储它当第一行完成时,在产生数字的第二行中,你不仅要水平地将它与此行进行比较,还要垂直地与其他行进行比较
就像这一行在线,你会成功。
答案 3 :(得分:0)
你可以作弊。您的问题中已经有一个解决方案:
1 3 2 4
3 1 4 2
2 4 3 1
4 2 1 3
您可以使用该解决方案生成其他人。首先,将该解决方案转换为字母:
A C B D
C A D B
B D C A
D B A C
其次,选择从四个字母A,B,C,D到四个数字1,2,3,4的随机映射。用您的映射中的相应数字替换网格中的字母。这将给出一个解决方案。
对于更多可能的解决方案,您可以在网格中交换列或交换网格中的行,但可能不允许某些生成的网格。如果你这样做,你需要更仔细地检查。