按字典顺序打印所有排列

我想按字典顺序打印字符串的所有排列.我写这段代码
void permute(char *a,int i,int n) {
   if (i == (n-1)) printf("\"%s\"\n",a);
   else {
       for (int j = i; j < n; j++) {
           swap((a+i),(a+j));
           permute(a,i+1,n);
           swap((a+i),(a+j));
       }
   }
}

我有例如字符串abc,所以我想按照左列列出的字典顺序接收所有排列,但是我的结果如右栏所示.

"abc"                   "abc"
"acb"                   "acb"
"bac"                   "bac"
"bca"                   "bca"
"cab"            <
"cba"                   "cba"
                 >      "cab"

有人可以帮我弄这个吗?我看到一些算法,但他们看起来很困难.我想我可以将所有生成的字符串保存在数组中,然后对该数组进行排序,但是我无法写入(我是初学者C).

解决方法

在C

geeksforgeeks上有一个非常简单的算法描述(加上实现):

Given a string,print all permutations of it in sorted order. For
example,if the input string is “ABC”,then output should be “ABC,
ACB,BAC,BCA,CAB,CBA”.

We have discussed a program to print all permutations in this post,
but here we must print the permutations in increasing order.

Following are the steps to print the permutations lexicographic-ally

  1. Sort the given string in non-decreasing order and print it. The first permutation is always the string sorted in non-decreasing order.

  2. Start generating next higher permutation. Do it until next higher permutation is not possible. If we reach a permutation where all
    characters are sorted in non-increasing order,then that permutation
    is the last permutation.

Steps to generate the next higher permutation:
1. Take the prevIoUsly printed permutation and find the rightmost character in it,which is smaller than its next character. Let us call
this character as ‘first character’.

  1. Now find the ceiling of the ‘first character’. Ceiling is the smallest character on right of ‘first character’,which is greater
    than ‘first character’. Let us call the ceil character as ‘second
    character’.

  2. Swap the two characters found in above 2 steps.

  3. Sort the substring (in non-decreasing order) after the original index of ‘first character’.

我在下面重新实现了:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void swap(char* left,char* right)
{
    char temp = *left;
    *left = *right;
    *right = temp;
}
int compare (const void * a,const void * b)
{
  return ( *(char*)a - *(char*)b );
}
void PrintSortedPermutations(char* inStr)
{
    // Re-implementation of algorithm described here:
    // http://www.geeksforgeeks.org/lexicographic-permutations-of-string/
    int strSize = strlen(inStr);
    // 0. Ensure input container is sorted
    qsort(inStr,strSize,sizeof(char),compare);


    int largerPermFound = 1;
    do{
        // 1. Print next permutation
        printf("%s\n",inStr);
        // 2. Find rightmost char that is smaller than char to its right
        int i;
        for (i = strSize - 2; i >= 0 && inStr[i] >= inStr[i+1]; --i){}

        // if we Couldn't find one,we're finished,else we can swap somewhere
        if (i > -1)
        {
            // 3 find character at index j such that 
            // inStr[j] = min(inStr[k]) && inStr[k] > inStr[i] for all k > i
            int j = i+1;
            int k;
            for(k=j;k<strSize && inStr[k];++k)
            {
                if (inStr[k] > inStr[i] && inStr[k] < inStr[j])
                    j = k;
            }

            // 3. Swap chars at i and j
            swap(&inStr[i],&inStr[j]);

            // 4. Sort string to the right of i
            qsort(inStr+i+1,strSize-i-1,compare);
        }
        else
        {
            largerPermFound = 0;
        }
    }while(largerPermFound);
}

int main(void) {
    char str[] = "abc";

    PrintSortedPermutations(str);
    return 0;
}

产量

abc
acb
bac
bca
cab
cba

Live Demo

在C

std::next_permutation从< algorithm>图书馆将为您做这件事,只需确保您先对容器进行排序:

Return value

true if the function Could rearrange the object as a lexicographicaly
greater permutation. Otherwise,the function returns false to indicate
that the arrangement is not greater than the prevIoUs,but the lowest
possible (sorted in ascending order).

例如:

std::string myStr = "abc";
std::stable_sort(std::begin(myStr),std::end(myStr));
do {
    for(auto&& element : myStr)
        std::cout << element << " ";
    std::cout << std::endl;
} while (std::next_permutation(std::begin(myStr),std::end(myStr)));

输出

a b c
a c b
b a c
b c a
c a b
c b a

Live Demo

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...