Гид по технологиям

Как вывести все перестановки строки

4 min read Алгоритмы Обновлено 07 Jan 2026
Перестановки строки: примеры на C++, Python, JS, C
Перестановки строки: примеры на C++, Python, JS, C

Фрагменты пазла, символизирующие перестановки

Перестановка — это расположение объектов в определённом порядке. Строку длины n можно переставить n! способами.

В этой статье показано, как найти все перестановки заданной строки с примерами на C++, Python, JavaScript и C. Код предназначен для демонстрации: вы можете подставить свои строки вместо примеров.

Как работают перестановки

Рассмотрим строку str = “MUO”. Требуется вывести все перестановки.

Пример 1: str = “MUO”

Перестановки “MUO”:

  • “MUO”
  • “MOU”
  • “UMO”
  • “UOM”
  • “OUM”
  • “OMU”

Пример 2: str = “AB”

Перестановки “AB”:

  • “AB”
  • “BA”

Если в строке есть повторяющиеся символы (например, “ABBA”), простые рекурсивные алгоритмы будут печатать дубликаты. Мы позже покажем, как этого избежать.

Важно: рост количества перестановок факториален — для n=10 это 3 628 800 перестановок. На практике это ограничивает применение полного перебора небольшими n.

C++ программа для вывода всех перестановок строки

Ниже — исходный C++ код, печатающий все перестановки рекурсивным обменом символов:

// C++ program to print all  
// permutations of a string  
#include   
using namespace std;  
  
  
// Function to print permutations of string  
void findPermutations(string str, int leftIndex, int rightIndex)  
{  
    if (leftIndex == rightIndex)  
    {  
        cout << str << endl;  
    }  
    else  
    {  
        for (int i = leftIndex; i <= rightIndex; i++)  
        {  
            swap(str[leftIndex], str[i]);  
            findPermutations(str, leftIndex+1, rightIndex);  
            //backtrack  
            swap(str[leftIndex], str[i]);  
        }  
    }  
}  
  
// Driver Code  
int main()  
{  
    string str1 = "MUO";  
    int size1 = str1.size();  
    cout << "str1: " << str1 << endl;  
    cout << "Permutations of " << str1 << ":" << endl;  
    findPermutations(str1, 0, size1-1);  
  
    string str2 = "AB";  
    int size2 = str2.size();  
    cout << "str2: " << str2 << endl;  
    cout << "Permutations of " << str2 << ":" << endl;  
    findPermutations(str2, 0, size2-1);  
  
    string str3 = "XYZ";  
    int size3 = str3.size();  
    cout << "str3: " << str3 << endl;  
    cout << "Permutations of " << str3 << ":" << endl;  
    findPermutations(str3, 0, size3-1);  
  
    return 0;  
}

Вывод программы:

str1: MUO  
Permutations of MUO:  
MUO  
MOU  
UMO  
UOM  
OUM  
OMU  
str2: AB  
Permutations of AB:  
AB  
BA  
str3: XYZ  
Permutations of XYZ:  
XYZ  
XZY  
YXZ  
YZX  
ZYX  
ZXY

Python программа для вывода всех перестановок строки

Пример на Python с рекурсивной перестановкой элементов списка:

# Python program to print all  
# permutations of a string  
  
def convertToString(List):  
    return ''.join(List)  
  
# Function to print permutations of string  
def findPermutations(s, leftIndex, rightIndex):  
    if leftIndex == rightIndex:  
        print(convertToString(s))  
    else:  
        for i in range(leftIndex, rightIndex+1):  
            s[leftIndex], s[i] = s[i], s[leftIndex]  
            findPermutations(s, leftIndex+1, rightIndex)  
            # backtrack  
            s[leftIndex], s[i] = s[i], s[leftIndex]  
  
# Driver Code  
str1 = "MUO"  
size1 = len(str1)  
s1 = list(str1)  
print("str1:", str1)  
print("Permutations of", str1,":")  
findPermutations(s1, 0, size1-1)  
  
str2 = "AB"  
size2 = len(str2)  
s2 = list(str2)  
print("str2:", str2)  
print("Permutations of", str2,":")  
findPermutations(s2, 0, size2-1)  
  
str3 = "XYZ"  
size3 = len(str3)  
s3 = list(str3)  
print("str3:", str3)  
print("Permutations of", str3,":")  
findPermutations(s3, 0, size3-1)

Вывод тот же, что и в C++ примере.

Совет: в реальных проектах на Python проще использовать itertools.permutations для генерации уникальных перестановок или всех перестановок с учётом повторений.

JavaScript программа для вывода всех перестановок строки

Пример на JavaScript, печать в документ (демонстрация):

// JavaScript program to print all  
// permutations of a string  
  
// Function to swap characters of the string  
function swap(str, leftIndex, i) {  
    let temp;  
    let tempArray = str.split("");  
    temp = tempArray[leftIndex] ;  
    tempArray[leftIndex] = tempArray[i];  
    tempArray[i] = temp;  
    return (tempArray).join("");  
}  
  
// Function to print permutations of string  
function findPermutations(str, leftIndex, rightIndex) {  
    if (leftIndex == rightIndex) {  
        document.write(str + "\n");  
    } else {  
        for (let i = leftIndex; i <= rightIndex; i++) {  
            str = swap(str, leftIndex, i);  
            findPermutations(str, leftIndex+1, rightIndex);  
            //backtrack  
            str = swap(str, leftIndex, i);;  
        }  
    }  
}  
  
// Driver Code  
  
var str1 = "MUO";  
var size1 = str1.length;  
document.write("str1: " + str1 + "\n");  
document.write("Permutations of " + str1 + ":" + "\n");  
findPermutations(str1, 0, size1-1);  
  
var str2 = "AB";  
var size2 = str2.length;  
document.write("str2: " + str2 + "\n");  
document.write("Permutations of " + str2 + ":" + "\n");  
findPermutations(str2, 0, size2-1);  
  
var str3 = "XYZ";  
var size3 = str3.length;  
document.write("str3: " + str3 + "\n");  
document.write("Permutations of " + str3 + ":" + "\n");  
findPermutations(str3, 0, size3-1);

Здесь полезно помнить про обход без дубликатов и про более эффективные алгоритмы для больших n.

C программа для вывода всех перестановок строки

C-реализация с обменом символов и рекурсией:

// C program to print all  
// permutations of a string  
#include   
#include   
  
// Function to swap characters of the string  
void swap(char str[], int leftIndex, int i)  
{  
    char temp = str[leftIndex];  
    str[leftIndex] = str[i];  
    str[i] = temp;  
}  
  
// Function to print permutations of string  
void findPermutations(char str[], int leftIndex, int rightIndex)  
{  
    if (leftIndex == rightIndex)  
    {  
        printf("%s \n", str);  
    }  
    else  
    {  
        for (int i = leftIndex; i <= rightIndex; i++)  
        {  
            swap(str, leftIndex, i);  
            findPermutations(str, leftIndex+1, rightIndex);  
            //backtrack  
            swap(str, leftIndex, i);  
        }  
    }  
}  
  
// Driver Code  
int main()  
{  
    char str1[] = "MUO";  
    int size1 = strlen(str1);  
    printf("str1: %s \n", str1);  
    printf("Permutations of %s: \n", str1);  
    findPermutations(str1, 0, size1-1);  
  
    char str2[] = "AB";  
    int size2 = strlen(str2);  
    printf("str2: %s \n", str2);  
    printf("Permutations of %s: \n", str2);  
    findPermutations(str2, 0, size2-1);  
  
    char str3[] = "XYZ";  
    int size3 = strlen(str3);  
    printf("str3: %s \n", str3);  
    printf("Permutations of %s: \n", str3);  
    findPermutations(str3, 0, size3-1);  
  
    return 0;  
}

Вывод совпадает с предыдущими примерами.

Альтернативные подходы и когда они лучше

  • Использовать библиотечные функции: в C++ есть std::next_permutation, в Python — itertools.permutations. Подходы проще и часто быстрее в разработке.
  • Heap’s algorithm — эффективен для генерации перестановок без лишних копирований; полезен при ограничениях по памяти.
  • Итерирование по лексикографическому порядку (next_permutation) подходит, когда нужна сортированная выдача.
  • Генерация без дубликатов: если вход содержит повторяющиеся символы, сортируйте и применяйте next_permutation или используйте set/просеивание, чтобы выводить только уникальные варианты.

Когда эти решения не подходят:

  • Если n большой (обычно n>10), полный вывод всех перестановок непрактичен из-за факториального взрыва.
  • Если нужна случайная перестановка без полного перечисления — используйте алгоритм Фишера–Йейтса.

Практические советы и эвристики

  • Оцените n!: если n! превышает допустимое число операций/памяти, переключитесь на выборочные или вероятностные методы.
  • Для уникальных перестановок сортируйте массив и применяйте next_permutation или фильтр на уровне вывода.
  • Избегайте ненужных копий строки внутри рекурсии: в критичных по скорости реализациях меняйте символы in-place и затем возвращайте назад (backtrack).
  • Для многопоточной генерации разбейте пространство перестановок по фиксированным префиксам.

Быстрая методология адаптации к проекту

  1. Определите максимальное n, с которым вы будете работать.
  2. Выберите стратегию: полная генерация, генерация уникальных, случайные перестановки.
  3. Если нужна полная генерация и n≤9, используйте рекурсию или next_permutation.
  4. Если есть повторяющиеся символы, примените сортировку + фильтр или структуры данных для уникальности.
  5. Напишите тесты и определите ограничения по времени/памяти.

Критерии приёмки

  • Алгоритм корректно печатает все перестановки для строк без повторов.
  • При строках с повторяющимися символами — поведение согласовано с требованиями (печать дубликатов или только уникальных).
  • Время выполнения и использование памяти соответствуют заданным ограничениям проекта.

Факт-бокс: рост сложности

  • n = 5 → 120 перестановок
  • n = 8 → 40 320 перестановок
  • n = 10 → 3 628 800 перестановок

Фактор роста — факториал n (n!). Это ключевой фактор при принятии решения о полном перечислении.

Ролевые чек-листы

Для разработчика: проверить корректность обменов и возврат состояний (backtrack).
Для тестировщика: составить набор тестов с повторяющимися символами, пустой строкой и короткими/длинными входами.
Для архитектора: оценить, возможно ли использовать библиотечные методы или требуется кастомизация ради производительности.

Итог

Вы узнали, как рекурсивно генерировать все перестановки строки на C++, Python, JavaScript и C. Для практических задач выбирайте библиотечные функции или оптимальные алгоритмы (Heap, next_permutation), избегайте полного перечисления при больших n и используйте фильтры для удаления дубликатов.

Важно: перестановки растут факториально, поэтому всегда проверяйте ограничения по n и оценивайте альтернативные подходы.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Пересылка почты Outlook ↔ Gmail: полное руководство
Почта

Пересылка почты Outlook ↔ Gmail: полное руководство

Как узнать, что пора менять батарейку AirTag
Гаджеты

Как узнать, что пора менять батарейку AirTag

Как удалить устройства из Google Home
Умный дом

Как удалить устройства из Google Home

Вернуть «Open command window here» в Windows 11
Windows

Вернуть «Open command window here» в Windows 11

Подключение Bluetooth-наушников к Wear OS
Гаджеты

Подключение Bluetooth-наушников к Wear OS

Запустить успешную страницу на Patreon
Монетизация

Запустить успешную страницу на Patreon