按字典顺序打印所有排列

2023-12-19

我想按字典顺序打印字符串的所有排列。我写了这段代码:

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 初学者)。


In C

有一个非常简单的算法描述(加上实现)极客之极客 http://www.geeksforgeeks.org/lexicographic-permutations-of-string/:

给定一个字符串,按排序顺序打印它的所有排列。为了 例如,如果输入字符串是“ABC”,则输出应该是“ABC, ACB、BAC、BCA、CAB、CBA”。

我们在这篇文章中讨论了一个打印所有排列的程序, 但这里我们必须按升序打印排列。

以下是按字典顺序打印排列的步骤

  1. 按非降序对给定字符串进行排序并打印它。第一个排列始终是按非降序排序的字符串。

  2. 开始生成下一个更高的排列。这样做直到不可能进行下一个更高的排列。如果我们达到一个排列,其中所有 字符按非递增顺序排序,然后排列 是最后一个排列。

生成下一个更高排列的步骤:
1. 取出先前打印的排列并找到其中最右边的字符,该字符小于其下一个字符。让我们打电话 该字符作为“第一个字符”。

  1. 现在找到“第一个字符”的上限。 Ceiling 是“第一个字符”右侧最小的字符,较大者 比“第一个字符”。让我们将 ceil 字符称为“第二个” 特点'。

  2. 交换上面 2 个步骤中找到的两个字符。

  3. 在“第一个字符”的原始索引之后对子字符串进行排序(按非降序)。

我在下面重新实现了它:

#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, sizeof(char), compare);
        }
        else
        {
            largerPermFound = 0;
        }
    }while(largerPermFound);
}

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

    PrintSortedPermutations(str);
    return 0;
}

Output

abc
acb
bac
bca
cab
cba

现场演示 http://ideone.com/3WHHtG


In C++

std::next_permutation http://www.cplusplus.com/reference/algorithm/next_permutation/来自<algorithm>库将为您执行此操作,只需确保首先对容器进行排序:

返回值

true 如果函数可以按字典顺序重新排列对象 更大的排列。否则,函数返回 false 来指示 该排列不大于前一个,但最低 可能(按升序排列)。

例如:

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)));

Output:

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

现场演示 http://ideone.com/2yzLva

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • 启动时出现 OData v4 错误:找不到段“Whatever”的资源

    我正在构建新的 v4 服务 一切进展顺利 直到我为新模型 实体添加了新控制器 并在启动站点进行测试运行时收到此错误 控制器似乎编码正确 就像其他控制器一样 控制器 CustomersOData 中的操作 GetFeed 上的路径模板 Cus
  • 如何将 #ifdef DEBUG 添加到 Xcode?

    我的项目中有一些代码永远不应该在发布版本中使用 但在测试时很有用 我想做这样的事情 ifdef DEBUG Run my debugging only code endif 在 Xcode 4 中哪里添加 DEBUG 设置 我尝试将其放入
  • 互斥体实现可以互换(独立于线程实现)

    所有互斥体实现最终都会调用相同的基本系统 硬件调用吗 这意味着它们可以互换吗 具体来说 如果我使用 gnu parallel算法 使用openmp 并且我想让他们称之为线程安全的类我可以使用boost mutex用于锁定 或者我必须编写自己
  • 单元测试一起运行时失败,单独运行时通过

    所以我的单元测试遇到了一些问题 我不能只是将它们复制并粘贴到这里 但我会尽力而为 问题似乎是 如果我一项一项地运行测试 一切都会按预期进行 但如果我告诉它一起运行测试 则 1 5 将通过 TestMethod public void Obj
  • 如何访问另一个窗体上的ListView控件

    当单击与 ListView 所在表单不同的表单中的按钮时 我试图填充 ListView 我在 Form1 中创建了一个方法以在 Form2 中使用 并将参数传递给 Form1 中的方法 然后填充 ListView 当我调试时 我得到了传递的
  • 生成(非常)大的非重复整数序列而不进行预洗牌

    背景 我编写了一个简单的媒体客户端 服务器 我想生成一个不明显的时间值 随从客户端到服务器的每个命令一起发送 时间戳中将包含相当多的数据 纳秒分辨率 即使它不是真正准确 因为现代操作系统中计时器采样的限制 等 我想做的 在 Linux 上
  • C# Dns.GetHostEntry 不返回连接到 WiFi 的移动设备的名称

    我有一个 C 中的 Windows 窗体应用程序 我试图获取列表中所有客户端的主机名 下面给出的是 ra00l 来自此链接的代码示例 GetHostEntry 非常慢 https stackoverflow com questions 99
  • 无法在 Windows 运行时组件库的 UserControl 中创建依赖项属性

    我想在用户控件内创建数据可绑定属性 这个用户控件包含一个 Windows 运行时组件 项目 我使用下面的代码来创建属性 public MyItem CurrentItem get return MyItem GetValue Current
  • 如何在 C# 中定义文本框数组?

    您好 当我在 Windows 申请表上创建文本框时 我无法将其命名为 box 0 box 1 等 我这样做的目的是因为我想循环使用它们 其实我发现TextBox array firstTextBox secondTextBox 也有效
  • 将 Excel 导入到 Datagridview

    我使用此代码打开 Excel 文件并将其保存在 DataGridView 中 string name Items string constr Provider Microsoft Jet OLEDB 4 0 Data Source Dial
  • 使用 JNI 从 Java 代码中检索 String 值的内存泄漏

    我使用 GetStringUTFChars 从使用 JNI 的 java 代码中检索字符串的值 并使用 ReleaseStringUTFChars 释放该字符串 当代码在 JRE 1 4 上运行时 不会出现内存泄漏 但如果相同的代码在 JR
  • Powershell - 将字符串拆分为由开始和结束字符串划分的数组

    我有一个多行字符串 来自 json 例如 somekey somevalue somekey somevalue somekey somevalue somekey somenumber somekey null 我想将字符串拆分为一个数组
  • 未经许可更改内存值

    我有一个二维数组 当我第一次打印数组的数据时 日期打印正确 但其他时候 array last i 的数据从 i 0 到 last 1 显然是一个逻辑错误 但我不明白原因 因为我复制并粘贴了 for 语句 那么 C 更改数据吗 I use g
  • PlaySound 可在 Visual Studio 中运行,但不能在独立 exe 中运行

    我正在尝试使用 Visual Studio 在 C 中播放 wav 文件 我将文件 my wav 放入项目目录中并使用代码 PlaySound TEXT my wav NULL SND FILENAME SND SYNC 我按下播放按钮 或
  • C++:.bmp 到文件中的字节数组

    是的 我已经解决了与此相关的其他问题 但我发现它们没有太大帮助 他们提供了一些帮助 但我仍然有点困惑 所以这是我需要做的 我们有一个 132x65 的屏幕 我有一个 132x65 的 bmp 我想遍历 bmp 并将其分成小的 1x8 列以获
  • 批量更新 SQL Server C#

    我有一个 270k 行的数据库 带有主键mid和一个名为value 我有一个包含中值和值的文本文件 现在我想更新表格 以便将每个值分配给正确的中间值 我当前的方法是从 C 读取文本文件 并为我读取的每一行更新表中的一行 必须有更快的方法来做
  • Qcut Pandas:ValueError:Bin 边缘必须是唯一的

    我使用 Pandas 中的 Qcut 将数据离散化为大小相等的存储桶 我想要有价格桶 这是我的数据框 productId sell prix categ popularity 11997 16758760 0 28 75 50 524137
  • 如何编写一个同时需要请求和响应Dtos的ServiceStack插件

    我需要提供本地化数据服务 所有本地化的响应 Dto 都共享相同的属性 IE 我定义了一个接口 ILocalizedDto 来标记那些 Dto 在请求端 有一个ILocalizedRequest对于需要本地化的请求 Using IPlugin
  • .NET中的LinkedList是循环链表吗?

    我需要一个循环链表 所以我想知道是否LinkedList是循环链表吗 每当您想要移动列表中的 下一个 块时 以循环方式使用它的快速解决方案 current current Next current List First 电流在哪里Linke
  • 用于 C# 的 TripleDES IV?

    所以当我说这样的话 TripleDES tripledes TripleDES Create Rfc2898DeriveBytes pdb new Rfc2898DeriveBytes password plain tripledes Ke

随机推荐

  • DataType 属性破坏日期时间字段上的 jQuery 日期选择器

    我在用MVC 4 and 剃刀视图我无法理解为什么我的日期字段上的编辑视图没有正确绑定到内置 jQuery 日期选择器 该字段是数据类型Date在数据库中 以及DateTime在域模型中 我不想显示时间 只想显示日期 该字段是必填字段 需要
  • 透明度实际上是如何实现的?

    给定两个图像 A B 我想要第三个图像 C 就好像 B 的透明度为 t 0 5 并放置在 A 的顶部 现实中C是如何计算的以及n如何影响它 我对任何程序或伪代码都不感兴趣 我只想知道基本原理 我认为 C 的一种方式只不过是 A 和 B 的交
  • ImportError:colab google 中没有名为 object_detection.builders 的模块

    我运行时出现此错误 cd git clone quiet https github com tensorflow models git apt get install qq protobuf compiler python tk pip i
  • 为什么不为 Rspec + Selenium 使用共享 ActiveRecord 连接?

    处理 Selenium 和测试的最普遍接受的方法似乎是避免使用事务固定装置 然后在测试 场景之间使用诸如 database cleaner 之类的东西 我最近遇到了以下情况article http blog plataformatec co
  • 为什么 Eclipse 的 Egit 中 Commit 是灰色的

    EGit 中的提交按钮神秘地变灰了 几天前还运行得很好 有谁知道如何解决这一问题 我在谷歌上没有找到任何线索 我会附上屏幕截图 但我还没有足够的声誉点 我遇到了这个问题 发现在远程获取和合并后我有未暂存的更改 将未暂存的更改移至 Git S
  • null 不是对象(评估“ShareDialog.canShow”)

    我有这样的代码 import React Component from react import AppRegistry StyleSheet Text TouchableHighlight View from react native i
  • Sitecore Field Renderer - 在渲染内添加标记

    作为 SEO 增强项目的一部分 我的任务是在字段渲染器在页面上生成的图像的标记内添加以下属性 itemprop contentURL 在结束标签之前
  • 如何将PIL Image.image对象转换为base64字符串? [复制]

    这个问题在这里已经有答案了 我正在尝试以 90 度旋转的方式操作 Base64 编码的图像 经过此操作 我想将其转换回 Base64 字符串 但不幸的是还无法实现这一目标 这是我到目前为止所做的 image string StringIO
  • Android:从服务调用片段方法

    运行 Firebase Cloud 消息服务 我希望每次收到新消息时都会调用特定片段中的方法 public class FirebaseMsgService extends FirebaseMessagingService public F
  • 在sql中以管道分隔的列中搜索值

    我想搜索列中以管道分隔的值 见下文 Column1 1 1 2 23 2 6 6 12 我想在所有行中搜索 2 这样它将返回下面的行 Column1 1 2 23 2 谁能告诉我我们怎样才能实现这一目标 您可以使用like where co
  • 如何更改 Xamarin 表单中的密码屏蔽字符 - 条目

    我目前面临一个相当简单的问题 最终使我陷入了死胡同 我正在构建一个使用 Xamarin Forms 的应用程序 并希望在用户输入密码时将掩码字符从项目符号更改为星号 为了输入密码 我在内容页面的可移植库项目中使用条目控件 在 VS2017
  • C++ STL 中的确定性随机数流

    我想提供一个数字 然后收到一组随机数 但是 我希望这些数字是相同的 无论我在哪台计算机上运行它 假设我提供相同的种子 基本上我的问题是 在 C 中 如果我使用rand 但供应srand 使用用户定义的种子而不是当前时间 我是否能够在任何计算
  • 列表以按间隔返回特定字段的值

    我正在使用大量数据实施 Telerik Chart 图表 x 轴上的标签重叠 我已经克服了这个问题 但从长远来看它并不可靠 这些是列表具有的字段 FieldName DataType Date DATETIME DateString STR
  • 数据流中的近似重复检测

    我目前正在开发一个可以生成大量文本内容的流 API 正如预期的那样 API 给出了大量重复数据 而且我们也有过滤接近重复数据的业务需求 我对数据流中的重复检测做了一些研究 并阅读了 稳定布隆过滤器是用于数据流中重复检测的数据结构 具有误报率
  • makemigrations 未检测到模型中的更改

    我正在使用 django 1 9 6 我最近删除了我的迁移并运行migrate run syncdb and makemigrations my app 今天 我向我的一个模型添加了一个新字段 模型 py value models Posi
  • java - 在 spring mvc 中按名称获取 cookie 值

    我正在开发 java spring mvc 应用程序 我以这种方式在控制器的方法之一中设置了 cookie RequestMapping value news method RequestMethod GET public ModelAnd
  • 更新不可变对象

    我建立了以下课程 class Player val name String val onField Boolean val draft Int val perc Int val height Int val timePlayed Int o
  • iPhone iOS 如何合并Core Data NSManagedObjectContext?

    我正在尝试在后台下载一些 JSON 对象 并且正在执行大量多线程操作 操作完成后 我注意到此断言失败 NSAssert user managedObjectContext isEqual AppUser managedObjectConte
  • Kubernetes ingress 对于特定服务给出 404 错误

    我已经在 Azure 上使用 nginx 入口设置了一个 kubernetes 集群 导航到特定路径时出现 404 错误 我已经设置了一些示例应用程序 它们返回一个简单的回声 效果非常好 我的 ban api 应用程序总是返回 404 错误
  • 按字典顺序打印所有排列

    我想按字典顺序打印字符串的所有排列 我写了这段代码 void permute char a int i int n if i n 1 printf s n a else for int j i j lt n j swap a i a j p