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

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

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
Автор
Редакция

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

Резюме в Google Docs — быстрый план
Карьера

Резюме в Google Docs — быстрый план

Вернуть покупку в Oculus Store — инструкция
Помощь

Вернуть покупку в Oculus Store — инструкция

Изменить и сбросить пароль в TikTok
Безопасность

Изменить и сбросить пароль в TikTok

Как увеличить миниатюры в Chrome, Firefox и Edge
Браузеры

Как увеличить миниатюры в Chrome, Firefox и Edge

Включить режим «Не беспокоить» в Windows 11
Windows

Включить режим «Не беспокоить» в Windows 11

Split View в Slack — как включить и использовать
Slack

Split View в Slack — как включить и использовать