四位随机数,无数字重复
Four digit random number without digit repetition
有什么方法可以不重复地拥有 4 位数字 - 例如不是1130
而是1234
?我读到std::random_shuffle
可以做到这一点,但它只会交换两者之间的数字。
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
#include <random>
unsigned seed = static_cast<size_t>(std::chrono::system_clock::now().time_since_epoch().count());
using namespace std;
class Player {
private:
string playername;
public:
void setName(string b) {
cout << "Please enter your name:" << endl;
getline(cin, b);
playername = b;
}
string getName () {
return playername;
}
};
class PasswordGuessingGame {
private:
std::mt19937 random_engine;
std::uniform_int_distribution<size_t> random_generator;
public:
PasswordGuessingGame():
random_engine(seed),
random_generator(1000,9999)
{
}
int getNumber () {
return random_generator(random_engine);
}
};
int main () {
Player newgame;
PasswordGuessingGame b;
newgame.setName("");
cout << newgame.getName() << " " << "password " << b.getNumber() << endl;
}
一种可能性是生成一个包含数字的字符串,并使用 C++14 函数std::experimental::sample()
#include <iostream>
#include <random>
#include <string>
#include <iterator>
#include <experimental/algorithm>
int main() {
std::string in = "0123456789", out;
do {
out="";
std::experimental::sample(in.begin(), in.end(), std::back_inserter(out), 4, std::mt19937{std::random_device{}()});
std::shuffle(out.begin(), out.end(), std::mt19937{std::random_device{}()});
} while (out[0]=='0');
std::cout << "random four-digit number with unique digits:" << out << 'n';
}
编辑:
已更改以防止以 0 开头的结果。帽子提示给@Bathsheba谁表示这可能是一个问题。
我认为您需要单独生成每个数字。例如,您有从 0 到 9 的数组,其中包含 0..9 位数字。对于第一个数字,您生成从 0 到 9 的数字并从该数组中选取数字。然后,将此数组元素 t 与数组的最后一个元素交换。对于第二个数字,您生成 0 到 8 的数字形式。等等。
我认为std::random_shuffle
没有问题:
#include <iostream>
#include <string>
#include <algorithm>
#include <random>
#include <chrono>
int main()
{
std::string s;
std::generate_n(std::back_inserter(s), 10,
[]() { static char c = '0'; return c++; });
// s is now "0123456789"
std::mt19937 gen(std::random_device{}());
// if 0 can't be the first digit
std::uniform_int_distribution<size_t> dist(1, 9);
std::swap(s[0], s[dist(gen)]);
// shuffle the remaining range
std::shuffle(s.begin() + 1, s.end(), gen); // non-deprecated version
// convert only first four
auto x = std::stoul(s.substr(0, 4));
std::cout << x << std::endl;
}
住在科里鲁
如果你能计算出有多少个有效(即可接受的)序列存在,并且你可以设计一个双射函数,从这个计数器映射到每个有效的序列实例,那么事情就变得微不足道了。
如果我正确理解您的示例,您希望生成一个随机的 4 位序列 ABCD(表示 [0,9999] 范围内的整数),其中数字 A、B、C 和 D 彼此不同。
有 5040 个这样的有效序列:10 * 9 * 8 * 7。
给定 [0, 5039] 范围内的任何整数,以下函数将返回一个有效序列(即每个数字都是唯一的序列),表示为整数:
int counter2sequence(int u) {
int m = u/504;
u %= 504;
int h = u/56;
u %= 56;
int t = u/7;
u %= 7;
const int ih = h;
const int it = t;
if (ih >= m) ++h;
if (it >= ih) ++t;
if (t >= m) ++t;
if (u >= it) ++u;
if (u >= ih) ++u;
if (u >= m) ++u;
return ((m*10 + h)*10 + t)*10 + u;
}
例如
counter2sequence(0) => 0123
counter2sequence(5039) => 9876
另一种方法,仅使用标准数据和数值算法。
#include <random>
#include <array>
#include <iostream>
#include <numeric>
template<class Engine>
int unrepeated_digits(int ndigits, Engine &eng) {
std::array<int, 10> digits = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
auto add_digit = [](auto x, auto digit) {
return x * 10 + digit;
};
std::shuffle(std::begin(digits), std::end(digits), eng);
return std::accumulate(std::begin(digits), std::next(std::begin(digits), ndigits), 0, add_digit);
}
int main() {
std::random_device rnd;
std::default_random_engine eng(rnd());
for (int i = 0; i < 10; ++i)
std::cout << unrepeated_digits(4, eng) << std::endl;
}
示例输出:
7623
3860
9563
9150
3219
8652
4789
2457
1826
9745
相关文章:
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- 在将数字随机生成为数组期间从内存输出随机数的数组
- 无符号的 int 到有效数字
- 使用移位的无符号数字作为数组的索引号是一种很好的做法
- C++:如何在从给定缓存中排除数字的同时生成随机数
- 使用指针选择长无符号变量中的数字
- 为无符号字符* 分配一个数字
- 如何在C++中创建数字列表,以便它可以选择一个随机数?
- 我在一个生成随机数的程序工作,我想将这些数字存储在一个数组中
- 如何在C++中生成低于或高于某个数字的任何随机数?
- 在 Python/C++ 中用更改文件中的随机数替换数字
- 移位运算符如何影响无符号数字
- 有没有一种更快的方法,从特定的数字池中获取随机数
- C++随机数生成器通常在 Visual Studio 中运行程序时在 2 次后停止生成数字
- 在随机数组中找到一个特定数字
- 我的随机数生成器不断获得相同的数字?(C )
- C++ 无重复随机数生成器
- 如何在C 中生成4个不同的数字随机数
- 四位随机数,无数字重复
- 无偏随机数生成器