Итак, я работаю над проблемой, когда мне нужно создавать перестановки бинарных строк, которые не только имеют определенную длину, но также содержат определенное количество единиц и нулей. У меня есть алгоритм, который делает это, однако он является рекурсивным, и я имею дело с 64-битными целыми без знака, поэтому существует вероятность того, что они будут слишком большими для обработки функции. Надеюсь, кто-то может помочь мне или предложить другой алгоритм, на который я должен взглянуть. Любая помощь приветствуется.Нерекурсивный генератор перестановок двоичной строки
ответ
Если вы выполняете правильную рекурсию, вы можете обрабатывать двоичные последовательности длиной 64 и более.
В следующем алгоритме глубина рекурсии ограничена длиной последовательности (которая равна 64 в вашем случае), и на каждом уровне рекурсии мы кладем только несколько байтов в стек. Вместо сохранения всех результатов мы просто выводим последовательность всякий раз, когда она готова, поэтому мы не накапливаем много последовательностей в памяти. Обратите внимание, как переменная s
передается через рекурсию.
#include <functional>
#include <iostream>
void create_all_binary_subsequence(std::string& s, int offset, int num_of_ones, std::function<void(const std::string& s)> callback)
{
if (num_of_ones == 0)
callback(s);
else {
for (int i = offset; i <= (int)s.size() - num_of_ones; ++i) {
s[i] = '1';
create_all_binary_subsequence(s, i + 1, num_of_ones - 1, callback);
s[i] = '0';
}
}
}
void create_all_binary_sequences(int num_of_ones, int length, std::function<void(const std::string& s)> callback) {
std::string s(length, '0');
create_all_binary_subsequence(s, 0, num_of_ones, callback);
}
int main(int argc, char *argv[])
{
create_all_binary_sequences(3, 5, [](const std::string& s) {
std::cout << s.c_str() << "\n";
});
return 0;
}
И выход
11100
11010
11001
10110
10101
10011
01110
01101
01011
00111
Удивительно, спасибо за помощь. Однако мне нужно получить сгенерированные перестановки как целую строку. Есть ли способ сделать это, используя этот существующий код? Я попытался сыграть с актом, который у вас есть на seq [i], и я также попытался установить этот массив символов в строку, но ни один из них не работал. –
Хорошо. Я модифицировал алгоритм для использования std :: string вместо массивов char. Сейчас короче и быстрее –
Я хотел бы предложить, чтобы опереться на стандартную библиотеку с этой задачей. Вы можете использовать функцию std::next_permutation
, которая предоставит вам все возможные перестановки. Пожалуйста, обратите внимание на этот пример:
#include <iostream>
#include <algorithm>
#include <array>
template <class T>
void print(const T& array)
{
std::cout << "{ ";
for(bool i : array) { std::cout << i << " "; }
std::cout << "}" << std::endl;
}
int main()
{
std::array<bool, 5> data = { false, false, true, true, true };
print(data);
while(std::next_permutation(std::begin(data), std::end(data)))
{
print(data);
}
}
И это привело бы что-то вроде этого:
{ 0 0 1 1 1 }
{ 0 1 0 1 1 }
{ 0 1 1 0 1 }
{ 0 1 1 1 0 }
{ 1 0 0 1 1 }
{ 1 0 1 0 1 }
{ 1 0 1 1 0 }
{ 1 1 0 0 1 }
{ 1 1 0 1 0 }
{ 1 1 1 0 0 }
Edit:
Если вы хотите, чтобы иметь возможность выбрать количество единиц и нулей во время выполнения и вам нужно, чтобы перестановка была в виде строки, вы можете подготовить первую перестановку как std::string
и использовать на ней std::next_permutation
. Пример:
#include <iostream>
#include <algorithm>
#include <string>
std::string constructFirstPermutation(size_t numberOfZeros, size_t numberOfOnes)
{
std::string result;
result.reserve(numberOfZeros + numberOfOnes);
result.append(numberOfZeros, '0');
result.append(numberOfOnes, '1');
return result;
}
int main()
{
std::string data = constructFirstPermutation(5,10);
std::cout << data << std::endl;
while(std::next_permutation(std::begin(data), std::end(data)))
{
std::cout << data << std::endl;
}
}
'vector
@AlanStokes Или просто 'bool [n]' если возможно вообще. – Lingxi
@AlanStokes У меня есть изменения 'vector
- 1. Генератор перестановок Javascript
- 2. Быстрый генератор перестановок
- 3. Почему итеративный генератор перестановок медленнее, чем рекурсивный?
- 4. Генератор перестановок постоянного времени постоянного времени
- 5. C++: перечисление перестановок строки
- 6. Временная сложность перестановок строки
- 7. string.replace возвращение двоичной строки
- 8. Разбиение двоичной строки пополам
- 9. Остаток двоичной строки 3
- 10. Проверьте длину двоичной строки?
- 11. Алгоритм Javascript Heap (нерекурсивный)
- 12. Нерекурсивный os.walk()
- 13. Сложность для генерации перестановок строки
- 14. Создание условных перестановок заданной строки
- 15. Создание перестановок строки в диапазоне
- 16. Генерация упорядоченных перестановок заданной строки
- 17. Пролог: генератор расписания экзаменов - Как избежать перестановок в решениях
- 18. нерекурсивный JavaScript JSON парсер
- 19. Append числовое значение двоичной строки
- 20. Запись двоичной строки в файл
- 21. XAML-сериализация свойств двоичной строки
- 22. Python: Преобразование из двоичной строки
- 23. Строка Python для двоичной строки
- 24. Шестнадцатеричная строка для двоичной строки
- 25. Преобразование двоичной строки в десятичную.
- 26. Разархивирование Zip сжатых двоичной строки
- 27. . NET: чтение/запись двоичной строки
- 28. Преобразование двоичной строки в двоичное число для выполнения двоичной арифметики
- 29. Случайный генератор, отображающий строки
- 30. Нерекурсивный факториал в C
Вы рассмотрели использование std :: next_permutation? – user3188346
Какова максимальная длина строки? – Lingxi
Максимальная длина будет 64 символа –