我想按字典顺序打印字符串的所有排列.我写这段代码:
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

按字典顺序打印所有排列的更多相关文章

  1. 正则表达式使用案例-OCP试题

    mod=viewthread&tid=1327778

  2. 解读047关于正则表达式'[^Ale|ax.r$]'

    92.EvaluatethefollowingexpressionusingMeta.characterforregularexpression:'[^Ale|ax.r$]'Whichtwomatcheswouldbereturnedbythisexpression?(Choosetwo.)A.AlexB.AlaxC.AlxerD.AlaxendarE.AlexenderAnswer:DE首先看些

  3. 正则表达式转载

    #comment)这种类型的组不对正则表达式的处理产生任何影响,用于提供注释让人阅读比如:2[0-4]\d(?\(\)将\(和\)之间的表达式定义为“组”,并且将匹配这个表达式的字符保存到一个临时区域,它们可以用\1到\9的符号来引用。IgnorePatternWhitespace忽略表达式中的非转义空白并启用由#标记的注释。

  4. [每日一题] OCP1z0-047 :2013-08-21   正则表达式---REGEXP_INSTR....................................91

    您可以随意指定您想要开始搜索的start_position。occurrence参数默认为1,除非您指定您要查找接下来出现的一个模式。return_option的默认值为0,它返回该模式的起始位置;值为1则返回符合匹配条件的下一个字符的起始位置。'^'匹配输入字符串的开始位置,在方括号表达式中使用,此时它表示不接受该字符集合。

  5. [每日一题] OCP1z0-047 :2013-08-21 正则表达式---REGEXP_INSTR....................................91

    您可以随意指定您想要开始搜索的start_position。occurrence参数默认为1,除非您指定您要查找接下来出现的一个模式。return_option的默认值为0,它返回该模式的起始位置;值为1则返回符合匹配条件的下一个字符的起始位置。'^'匹配输入字符串的开始位置,在方括号表达式中使用,此时它表示不接受该字符集合。

  6. 按字典顺序打印所有排列

    我想按字典顺序打印字符串的所有排列.我写这段代码:我有例如字符串abc,所以我想按照左列列出的字典顺序接收所有排列,但是我的结果如右栏所示.有人可以帮我弄这个吗?

  7. 在C中将符号扩展名从16位扩展到32位

    我必须为16位整数做一个符号扩展,由于某种原因,它似乎没有正常工作.谁能告诉我代码中的bug在哪里?我已经工作了几个小时.指令是32位,在里面我有一个16位的数字.解决方法尝试:

随机推荐

  1. 从C到C#的zlib(如何将byte []转换为流并将流转换为byte [])

    我的任务是使用zlib解压缩数据包(已接收),然后使用算法从数据中生成图片好消息是我在C中有代码,但任务是在C#中完成C我正在尝试使用zlib.NET,但所有演示都有该代码进行解压缩(C#)我的问题:我不想在解压缩后保存文件,因为我必须使用C代码中显示的算法.如何将byte[]数组转换为类似于C#zlib代码中的流来解压缩数据然后如何将流转换回字节数组?

  2. 为什么C标准使用不确定的变量未定义?

    垃圾价值存储在哪里,为什么目的?解决方法由于效率原因,C选择不将变量初始化为某些自动值.为了初始化这些数据,必须添加指令.以下是一个例子:产生:虽然这段代码:产生:你可以看到,一个完整的额外的指令用来移动1到x.这对于嵌入式系统来说至关重要.

  3. 如何使用命名管道从c调用WCF方法?

    更新:通过协议here,我无法弄清楚未知的信封记录.我在网上找不到任何例子.原版的:我有以下WCF服务我输出添加5行,所以我知道服务器是否处理了请求与否.我有一个.NET客户端,我曾经测试这一切,一切正常工作预期.现在我想为这个做一个非托管的C客户端.我想出了如何得到管道的名称,并写信给它.我从here下载了协议我可以写信给管道,但我看不懂.每当我尝试读取它,我得到一个ERROR_broKEN_P

  4. “这”是否保证指向C中的对象的开始?

    我想使用fwrite将一个对象写入顺序文件.班级就像当我将一个对象写入文件时.我正在游荡,我可以使用fwrite(this,sizeof(int),2,fo)写入前两个整数.问题是:这是否保证指向对象数据的开始,即使对象的最开始可能存在虚拟表.所以上面的操作是安全的.解决方法这提供了对象的地址,这不一定是第一个成员的地址.唯一的例外是所谓的标准布局类型.从C11标准:(9.2/20)Apointe

  5. c – 编译单元之间共享的全局const对象

    当我声明并初始化一个const对象时.两个cpp文件包含此标头.和当我构建解决方案时,没有链接错误,你会得到什么如果g_Const是一个非const基本类型!PrintInUnit1()和PrintInUnit2()表明在两个编译单元中有两个独立的“g_Const”具有不同的地址,为什么?

  6. 什么是C名称查找在这里? (&amp;GCC对吗?)

    为什么在第三个变体找到func,但是在实例化的时候,原始变体中不合格查找找不到func?解决方法一般规则是,任何不在模板定义上下文中的内容只能通过ADL来获取.换句话说,正常的不合格查找仅在模板定义上下文中执行.因为在定义中间语句时没有声明func,并且func不在与ns::type相关联的命名空间中,所以代码形式不正确.

  7. c – 在输出参数中使用auto

    有没有办法在这种情况下使用auto关键字:当然,不可能知道什么类型的.因此,解决方案应该是以某种方式将它们合并为一个句子.这可用吗?解决方法看起来您希望默认初始化给定函数期望作为参数的类型的对象.您无法使用auto执行此操作,但您可以编写一个特征来提取函数所需的类型,然后使用它来声明您的变量:然后你就像这样使用它:当然,只要你重载函数,这一切都会失败.

  8. 在C中说“推动一切浮动”的确定性方式

    鉴于我更喜欢将程序中的数字保留为int或任何内容,那么使用这些数字的浮点数等效的任意算术最方便的方法是什么?说,我有我想写通过将转换放在解析的运算符树叶中,无需将表达式转化为混乱是否可以使用C风格的宏?应该用新的类和重载操作符完成吗?解决方法这是一个非常复杂的表达.更好地给它一个名字:现在当您使用整数参数调用它时,由于参数的类型为double,因此使用常规的算术转换将参数转换为double用C11lambda……

  9. objective-c – 如何获取未知大小的NSArray的第一个X元素?

    在objectiveC中,我有一个NSArray,我们称之为NSArray*largeArray,我想要获得一个新的NSArray*smallArray,只有第一个x对象…

  10. c – Setprecision是混乱

    我只是想问一下setprecision,因为我有点困惑.这里是代码:其中x=以下:方程的左边是x的值.1.105=1.10应为1.111.115=1.11应为1.121.125=1.12应为1.131.135=1.14是正确的1.145=1.15也正确但如果x是:2.115=2.12是正确的2.125=2.12应为2.13所以为什么在一定的价值是正确的,但有时是错误的?请启发我谢谢解决方法没有理由期望使用浮点系统可以正确地表示您的帖子中的任何常量.因此,一旦将它们存储在一个双变量中,那么你所拥有的确切的一

返回
顶部