我认为您将遇到的最大问题不是计算,而是磁盘写入速度或内存大小。顺便说一句,您似乎错误地确定了n = 250 和k = 6 的组合数量。你用uint64_t了吗?我的号码是244 140 625 000 000。
所以对于这个数字,您需要~1.4 Petabyte (~1400 Tb) 的内存。这是你的主要问题。如果你有那么大的硬盘,写的时候最好使用memory mapping。您可以考虑使用多个线程进行写入:每个线程都会写入自己的内存块。
所以,我认为您应该考虑其他方法来提供组合以解决您的实际目标。
一个幼稚的解决方案。用内存映射对象更改std::ofstream。
int main()
{
const constexpr uint8_t N = 250;
const constexpr uint8_t K = 6;
const constexpr uint64_t CombinationsCount = std::pow(N, K);
using TCombination = std::array<uint8_t, K>;
std::cout << CombinationsCount << std::endl;
std::ofstream file("output.txt");
TCombination c;
for (uint64_t i = 0; i < CombinationsCount; ++i)
{
auto I = i;
for (auto j = 0; j < K; ++j)
{
c[j] = I % N;
I /= N;
file << (int)c[j];
}
file << std::endl;
}
}
如果你想使用线程,只需将CombinationsCount 与核心数相除,然后给每个线程一个任务,从内存的特定地址(偏移量)写入。
您要求提供类似函数的解决方案。您可以传递不同的文件名称并使用不同的线程。买了还需要用到内存映射。
const constexpr uint8_t N = 250;
const constexpr uint8_t K = 6;
const constexpr uint64_t CombinationsCount = std::pow(N, K);
using TCombination = std::array<uint8_t, K>;
void Generate(uint64_t start, uint64_t size, const char* fileName)
{
std::ofstream file(fileName);
TCombination c;
for (uint64_t i = start; i < start + size; ++i)
{
auto I = i;
for (auto j = 0; j < K; ++j)
{
c[j] = I % N;
I /= N;
file << (int)c[j];
}
file << std::endl;
}
}
int main()
{
std::cout << CombinationsCount << std::endl;
unsigned int threadsNum = std::thread::hardware_concurrency();
std::vector<std::thread> workers;
for (size_t i = 0; i < threadsNum; ++i)
workers.emplace_back(
Generate,
i * CombinationsCount / threadsNum,
CombinationsCount / threadsNum,
(std::string("output") + std::to_string(i)).c_str());
for (size_t i = 0; i < threadsNum; ++i)
workers[i].join();
}