#include <iostream>
#include <string>
using namespace std;
void enumerate(const string& s, int n, string t = "")
{
if (n == 0)
cout << t << endl;
else
{
for (char c : s)
enumerate(s, n - 1, t + c);
}
}
int main()
{
enumerate("abc", 5);
}
Привет, ребята, я хочу сделать все возможные перестановки символов выбранной длины, но, может быть, отключилось питание, или я внезапно закрыл программу, или, может быть, мне нужно перезагрузить компьютер, поэтому я должен снова открыть программу, и она начинается сначала, так что наше время и энергия будет потеряна. также я не знаю, как работает этот тип цикла for (for (char c: s)) так как я могу сохранить прогресс, например, если это 100 раз, что цикл работает, сохраните число 100 в текстовом файле или все остальное, и после этого, если я закрыл программу по какой-то причине и открыл снова, прочитайте число 100 из текстового файла и не делайте этого. t начать заново и продолжить цикл.
Кажется, вы хотите декартово произведение, а не перестановку.
Какой вопрос?
C++ имеет удобный алгоритм стандартной библиотеки std::next_permutation, который вы можете использовать для обработки перестановок строк.
Ниже приведен метод грубой силы, в котором перебираются все возможные перестановки большей «родительской» строки, а первая подстрока n
символов проверяется на уникальность. Если эта дочерняя подстрока уникальна, то она печатается и добавляется к набору «уже используемых» дочерних перестановок.
После каждой итерации вы можете сохранить текущее состояние родительской перестановки. Позже вы можете передать его функции print_permutation
, которая возобновит расчет перестановки с этой точки. См. реализацию ниже для более подробной информации.
#include <algorithm>
#include <functional>
#include <iostream>
#include <string>
#include <unordered_set>
typedef std::function<void(const std::string& masterPerm, const bool finished)> PermutationCallback;
std::string new_master_permutation(std::string&& str) {
std::sort(str.begin(), str.end());
return str;
}
void print_permutation_if_unused(
const std::string& childPermutation,
std::unordered_set<std::string>& childPermsTried
) {
if (!childPermsTried.contains(childPermutation)) {
childPermsTried.insert(childPermutation);
std::cout << childPermutation << '\n';
}
}
void print_permutations(
std::string masterPermutation,
const size_t numCharsInPerm,
const PermutationCallback& callback
) {
std::unordered_set<std::string> childPermsTried;
// Actual constrained length of child permutation strings
const size_t permutationLength = std::min(masterPermutation.size(), numCharsInPerm);
do {
print_permutation_if_unused(masterPermutation.substr(0, permutationLength), childPermsTried);
callback(masterPermutation, false);
} while (std::next_permutation(masterPermutation.begin(), masterPermutation.end()));
callback(masterPermutation, true);
}
int main(void) {
// Begin with a new permutation, starting with the sorted string "abbc"
print_permutations(new_master_permutation("bacb"), 3,
[](const std::string& masterPerm, const bool finished) {
// Save the master permutation for reference
}
);
// Begin at any midpoint permutation ("bacb"), and calculate the rest.
print_permutations("bacb", 3, [](const std::string& masterPerm, const bool finished) {
// Save the master permutation for reference
});
return EXIT_SUCCESS;
}
Обратите внимание, что эта реализация далека от оптимальной. Выполнение увеличивается на факториальное время с каждым символом, добавляемым в основную строку перестановки. Большая длина дочерней перестановки значительно увеличивает использование памяти, поскольку каждая уникальная перестановка хранится в наборе. Тем не менее, это работает и должно стать как минимум хорошей отправной точкой.
Спасибо за ваш полный ответ и реальное объяснение, но есть небольшая проблема: в строке 18 команда .contains неверна. Я пробовал MinGW С++ 11 и компилятор VS, но это не сработало.
Ах да, извините. .contains
является частью C++ 20. Замените условное выражение на childPermsTried.emplace(childPermutation) == childPermsTried.end()
, и оно будет работать с C++ 11. Вызов insert
в строке 19 также необходимо изменить на emplace
, потому что вставка является частью C++ 17.
Проверьте, что
n < s.length()
в вашейenumerate()
функции.