java-全排列(无序)

该文详细介绍了如何使用Java编程实现全排列算法,包括递归方法实现全排列、处理含有相同元素的情况以及计算排列组合数。文章强调了在处理相同元素时可能出现重复输出的问题,并提出了通过数组或字符串去重的解决方案。同时,提供了核心的交换排序代码段和阶乘计算的递归函数。
摘要由CSDN通过智能技术生成

题目来自:原文链接:(13条消息) 第十四届蓝桥杯集训——练习解题阶段(无序阶段)-Java全排列公式_红目香薰的博客-CSDN博客

!!!本文方法在遇到 两个相同其余不同 以及类似 情况时,会出现输出重复的情况!!!

本文方法只适用全不同或全相同处理

去重方法,可以通过将排序结果输入数组或字符串去重等等

五种去重方法:原文链接:(14条消息) Java 去除重复数据的五种方式_狼魂豹速的博客-CSDN博客

题目

全排列题目要求

题目解析

从字符串数组中每次选取一个元素,作为结果中的第一个元素;然后,对剩余的元素全排列

全排列

从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列。

公式:全排列数f(n)=n!(定义0!=1)

例如:如果是对任意的三个字符进行全排列,也就是3!=6,当然,如果是相同的就只有1次

String s="我爱你";

三个字符,全排列,6中结果

我爱你

我你爱

爱我你

爱你我

你爱我

你我爱

问题分析与解题思路

1、注意字符字符串相同情况

  1. 注意无数据情况

全排列的数量是阶乘

阶乘需要递归方法实现

所以输出全部排列组合也需要递归方法

代码实现

主体代码

public static void main(String[] args) {
        // TODO Auto-generated method stub
        String s="祝好运";
        char[] cs =s.toCharArray();
        //确定是否有不同字符
        for (int i = 0; i < s.length()-1; i++) {
            if (cs[i]==cs[i+1]) {
                System.out.println("含有相同字符");
                break;
            }
        }
        
        f(cs,0,s.length()-1);
        System.out.println("排列组合数:"+f1(s.length())));
        
    }

在这部分我们实现了字符串的输入、转化为char数组类型,判断字符才能是否相同、调用两个自定义函数输出排列结果和排列组合数

很好理解,难点主要是核心的交换排列程序

核心代码

交换排序部分

    private static void f(char[] cs, int start, int end) {
        if (start==end) {//递归终止条件
            System.out.println(cs);
        }
        for (int i = start; i <= end; i++) {
            //交换,
            changeIndex(cs,i,start);
            //再次函数实现递归排序
            f(cs, start + 1,end);//再次循环避免重复解法
            //还原,保证下一次循环
            changeIndex(cs,i,start);
        }
    }


    private static void changeIndex(char[] cs, int start, int end) {
        //缓存交换
        char temp = cs[start];
        cs[start]=cs[end];
        cs[end]=temp;
    }

使用自定义函数完成,注意写递归时先写终止条件,避免死循环

递归方法也就是 多次循环,在原函数的基础上在进行多次,我们也就实现了递归方法、

最后一次交换就是回到原始状态,方便下一次循环使用

函数changeIndex就是一个简单的通过缓存媒介来交换的方法、

排列组合计数部分

    private static int f1(int i) {    
        if(i==1) {
            return 1;
        }
        if (i==0) {
            return 1;
        }
        //递归阶乘
        return i*f1(i-1);
    }

在字符0/1的情况不适应阶乘函数(定义0!=1)

所以在这两种情况下,输出次数为1

其他情况就进行阶乘运算即可

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CLODVEP

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值