字符串的全组合

大家千万不要把全组合和全排列搞混了,给定一个字符串:abc,

全组合形式:a,b,c,ab,ac,bc,abc

全排列形式:abc,acb,bac,bca,cab,cba

下面我就讲一下全组合问题。

首先讲一下组合问题原理:

n个元素选m个元素的组合问题的实现. 从后往前选取, 选定位置i后, 再在前i-1个里面选取m-1个. * 如: 1, 2, 3, 4, 5 中选取3个元素. * 1) 选取5后, 再在前4个里面选取2个, 而前4个里面选取2个又是一个子问题, 递归即可; * 2) 如果不包含5, 直接选定4, 那么再在前3个里面选取2个, 而前三个里面选取2个又是一个子问题, 递归即可; * 3) 如果也不包含4, 直接选取3, 那么再在前2个里面选取2个, 刚好只有两个. 如果m个元素选好了后,i-m还是有剩余,那么抛下第一个元素继续往前找,比如:

1 2 3中选两个元素组合,先选3再选2,此时23正好组成2位数的组合,但是13也是2位数的组合,所以因为找到2以后打印,但是前面还有一个1,所以会继续查找1代替2的位置,打印13.

代码:

public class Main {
    public static void combination(char[] chars) {
        char[] subchars = new char[chars.length]; //存储子组合数据的数组
        //全组合问题就是所有元素(记为n)中选1个元素的组合, 加上选2个元素的组合...加上选n个元素的组合的和
        //此for循环就是完成1个元素,2个元素,...n个元素选取问题
        for (int i = 0; i < chars.length; ++i) {
            int m = i + 1;
            //combination函数就是完成n中取m个元素组合问题
            combination(chars, chars.length, m, subchars, m);
        }
    }

    //n表示还剩下多少元素可以被用来组合,m表示还需要多少元素来组合。subn表示存放待打印的元素个数
   public static void combination(char[] chars, int n, int m, char[] subchars, int subn) {
        if (m == 0) { //出口
            for (int i = 0; i < subn; ++i) {
                System.out.print(subchars[i]);
            }
            System.out.println();
        } else {
            for (int i = n; i >= m; i--) { // 从后往前依次选定一个
                subchars[m - 1] = chars[i - 1]; // 选定一个后
                combination(chars, i - 1, m - 1, subchars, subn); // 从前i-1个里面选取m-1个进行递归
            }
        }
    }

    public static void main(String[] args) {
        char[] ch = {‘a‘,‘b‘,‘c‘};
        combination(ch);
    }
}
时间: 2024-10-10 05:10:23

字符串的全组合的相关文章

剑指offer-拓展训练-字符的所有组合-全组合

/* 题目: 给定不含重复字符字符串的全组合. */ /* 思路: 递归法. 例给定abc,输出的组合长度为1,2,3. 对于长度为2的组合,分选择a(ab,ac)和不选择a的情况(bc). 选择a,则在剩余字符串中选择长度为1的字符组合: 不选择a,则在剩余字符串中选择长度为2的字符组合. */ #include<iostream> #include<stdio.h> #include<string> using namespace std; string curr;

JAVA----编程列出一个字符串的全字符组合情况,原始字符串中没有重复字符

package com.pb.demo.packclass.demo1; import java.util.HashSet; /** * 编程列出一个字符串的全字符组合情况,原始字符串中没有重复字符 例如: 原始字符串是"abc",打印得到下列所有组合情况 "a" "b" "c" "ab" "bc" "ca" "ba" "cb"

字符串全组合(淘宝宝贝关键字)

小伙伴最近开了家淘宝店,每天为宝贝的名称弄得很麻烦,经常需要根据不同的关键字来组合宝贝的名称,但不知道啥组合能引入更多的流量,所以每个都试着弄弄看,所以这就需要一个字符串的组合. 在那个夜黑风高的晚上,小伙伴带着我去华强北吃了寿司,无意间谈了这个小东西,实现难度不高,立刻动手: 1 internal class Program 2 { 3 /* 4 思路:获取需要组合的字符串数组,循环读取字符串数组成立组合,再根据该组合循环再去组合,其实就是递归读取,用Contains判断是有包含即可 5 */

字符串的全排列和全组合

输入:abc 输出:bac,cba,acb,bca,cab,abc 全排列的问题: public ArrayList<String> Permutation(String str) { ArrayList<String> list = new ArrayList<String>(); if(str!=null && str.length()>0){ helper(str.toCharArray(),list,0); Collections.sort

常见算法之全排列 全组合

全排列算法是一种比较常考的算法,他的做法也比较多样. 首先我们来看看最符合我们直观思考的,思路是这样的:假如没有重复元素时,传入一个数组A,并插入到另外一个数组B中,假如B中已经包含这个元素,则跳过,否则插入数组B.我们来看看具体代码: <span style="font-size:14px;">public static void permutation1(final String str, String buffer){ if (str.length() == buff

全排列和全组合实现

记得@老赵之前在微博上吐槽说,“有的人真是毫无长进,六年前某同事不会写程序输出全排列,昨天发邮件还是问我该怎么写,这时间浪费到我都看不下去了.” 那时候就很好奇全排列到底是什么东西,到底有多难? 今天复习的时候终于碰到这题了,结果果然自己太渣,看了好久都没明白,代码实现又是磕磕碰碰的.所以,就把它整理成笔记加深记忆,也希望能帮到和我一样的人. 全排列 所谓全排列,就是打印出字符串中所有字符的所有排列.例如输入字符串abc,则打印出 a.b.c 所能排列出来的所有字符串 abc.acb.bac.b

算法:全组合算法

public static List<int[]> combin(final int TOTAL, final int SELETED) { List<int[]> list = new ArrayList<int[]>(400000); int[] i = new int[SELETED]; for (int x = 1; x <= SELETED; x++) i[x - 1] = x; final int LAST = SELETED - 1; while (

js判断字符串是否全为空(使用trim函数/正则表达式)

我们需要判断用户输入的是否全是空格,可以使用以下方法: 方法一: 使用trim() /* 使用String.trim()函数,来判断字符串是否全为空*/ function kongge1(test) { let str = test.trim(); if (str.length == 0) { console.log('字符串全是空格'); } else { console.log('输入的字符串为:' + test); } } 如果 trim() 不存在,可以在所有代码前执行下面代码 /* 给

字符串的排列组合总结

问题1 :输入一个字符串,打印出该字符串中字符的所有排列.例如输入字符串abc,则输出由字符a.b.c所能排列出来的所有字符串abc.acb.bac.bca.cab和cba. 思路:这是个递归求解的问题.递归算法有四个特性:(1)必须有可达到的终止条件,否则程序将陷入死循环:(2)子问题在规模上比原问题小:(3)子问题可通过再次递归调用求解:(4)子问题的解应能组合成整个问题的解. 对于字符串的排列问题.如果能生成n - 1个元素的全排列,就能生成n个元素的全排列.对于只有1个元素的集合,可以直