问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501
你好,欢迎来到懂视!登录注册
当前位置: 首页 - 正文

C语言怎么实现有重复元素的全排列?

发布网友 发布时间:2022-12-29 04:52

我来回答

1个回答

热心网友 时间:2023-10-25 12:21

整体思路就是利用回溯的思想,也可认为是深度优先搜索

从字符串第一位idx=0开始,每次递归都从s[idx]之后选择一个字符与s[idx]交换

因为可能有重复字符,可使用哈希数组标记当前循环每个字符是否被选择

因为字符范围不超过ASCII码,所以使用128空间的数组足够用来标记了

选择好当前字符s[i]并与s[idx]交换之后,递归调用继续排列下一位s[idx+1]

注意这里要进行回溯,即不选s[i]而选择之后的某个字符交换到s[idx]

所以要将之前的s[i]与s[idx]交换过来,恢复原状,才能循环判断下一个选择

具体代码截图如下:

运行结果如下:

结果正确,望采纳~

附源码:

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#define MAXN 1000000 // 排列总数可能很多

int num = 0; // 记录排列总数

char *res[MAXN] = {NULL}; // 指针数组保存排列结果

void swap(char *x, char *y) { // 交换两个字符变量的内容

    char ch = *x;

    *x = *y;

    *y = ch;

}

void perm(char *s, int n, int idx) { // 回溯产生字符串全排列

    if (idx == n) { // 已排列到字符串结尾

        res[num] = (char *)malloc(sizeof(char) * (n + 1));

        //printf("%s\n", s); // 输出当前排列

        strcpy(res[num], s); // 保存当前排列

        num++; // 排列总数加1

        return;

    }

    int i, hash[128] = {0}; // 哈希数组,标记每个字符是否被选择

    for (i = idx; i < n; i++) {

        if (hash[s[i]] == 1)

            continue; // 跳过已被标记过的重复字符

        hash[s[i]] = 1; // 选过的话在数组中标记为1

        swap(&s[idx], &s[i]); // 选择s[i]交换到s[idx]

        perm(s, n, idx + 1); // 递归,继续s[idx+1]的选择

        swap(&s[idx], &s[i]); // 回溯,当前不选择s[i],而选择其他字符

    }

}

int main() {

    int n, i;

    scanf("%d", &n);

    char *s = (char *)malloc(sizeof(char) * (n + 1));

    scanf("%s", s);

    perm(s, n, 0);

    printf("一共有%d种排列:\n", num); // 输出排列总数

    for (i = 0; i < num; i++) { // 输出所有排列

        printf("%s\n", res[i]);

        free(res[i]); // 释放内存空间

    }

    free(s);

    return 0;

}

声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。
E-MAIL:11247931@qq.com
幼儿珠心算有那些口诀 儿童免费小学教育网站请推荐几个小学二年级网络教育的网站 高频热处理后,产品的表面质量如何改善? ...2B的外螺纹滚丝后是OK的,但经过热处理与发黑后就有20%止规止不住... 真空热处理后的产品是否需要进一步处理? 教你怎么改变iOS 13充电慢 金铲铲之战 金铲铲s8.5纳尔给什么装备? 英雄联盟双排玩什么英雄英雄联盟中双排哪些英雄配合打套路特别叼金属日... 金铲铲之战 名流纳尔阵容解析 推荐LOL最值得入手最好上分的十大英雄?另外问下兰博还强力吗?_百度知 ... 发表了十几篇文章,来给大家推荐我容易过稿的平台 关于微生物对人类生活影响的资料 地铁上如何委婉地告诉别人自己是孕妇? 谁能告诉下面这个人物是哪部动漫的?急!!! 玛利亚狂热 ALIVE结局是什么?谁和谁在一起? 请问玛利亚狂热漫画是不是已经完了?还有没有第九卷? 玛利亚狂热漫画的结局是什么,那两位男女主人公之间会发生爱的摩擦吗,男主角被人发现是男生了吗 玛利亚狂热漫画完结一共多少话? 手机版金山文档填手机号码怎么靠前 单人双吹风淋室的结构说明 我参与过的话题怎么删啊。新浪的 专科卫生专项好不好?卫生专项计划如何填报? 高考医学专项是什么 荞麦面(面食)详细资料大全 快乐大本营2018年的有时代少年团吗 银行卡绑定手机号码是不是就可以在网上买东西了 顾司寒和叶若初的小说名字叫什么 叶若初顾司寒是哪部小说 大理国简介及详细资料 我的QQ登陆不上,但是申请的密码保护时的证件号码忘记了。怎么办? c语言,函数全排列,求代码,如图? 《王者荣耀》辅助明世隐怎么玩得好? 普者黑适合哪个季节去 普者黑适合什么季节去 昆明到普者黑旅游怎么坐车,有没有推荐的酒店 抖音陈子壹微博叫什么 鹅蛋不能和什么一起吃鹅蛋不能一起吃的食物是什么 吃鹅蛋不能吃什么 白求恩是谁?有什么事迹? 光伏板卡扣位置 关示白求恩的资料有哪些? 关于白求恩的故事50字以内 治疗支气管炎用中成药有哪些 支气管炎最好的中成药事什么? 更新到win7后,所有下载的软件都打不开了 win7有个软件显示更新中···暂停使用怎么办 win7升级win10以后,软件打不开,显示程序出现了一个问题,导致程序无法正常工作&#12855 短句名言警句大全集? 请问名言警句励志短句 捷达vs5后挡风玻璃尺寸 易信账号不用手机号怎么注册?
  • 焦点

最新推荐

猜你喜欢

热门推荐