目录
排列
排列定义:从n个元素中获取m(m<=n)个元素,并进行排序(假定元素各不相同)
ps:获取第一个元素有n种可能性,获取第二个元素有(n-1)种可能性,当需要获取第m个元素的时候时有(n-m+1)种可能性
计算方式:
其余概念: 0!=1 n=m时是全排列
组合
组合定义:从n个元素中获取m(m<=n)个元素,这m个元素不用进行排序(假定个元素各不相同)
ps:上面排列中获取m个元素时时进行了排序,也就是组合的数量 * m个元素排序的数量 = 排序的数量
计算方式:
其余概念:C(n,m)=C(n,n-m)
题
有四个字符A、B、B、C,从中获取三个字符进行排序,请问有多少种场景?
ps:首先我们从四个字符中获取三个字符并排序的数量是A(4,3),其次因为B字符出现了两次他的他的顺序是我们重复计算的A(2,2),因此实际结果应该是A(4,3)/A(2,2)
扩展场景1:输入一个纯大写字母的字符串(可能存在重复字母),对这个字符串中的所有字符进行重新排序,可以组装出多少种字符串?
package com.anran.example.test;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class Test3 {
/**
* 场景:输入一个纯大写字母的字符串(可能存在重复字母),对这个字符串中的所有字符进行重新排序,可以组装出多少种字符串
* 输入:ABBC
*
* 输出:所有字符串的组合数量
*
* @param args
*/
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.next();
char[] chars = str.toCharArray();
// 判断其中重复的字符以及个数
Map<Character, Integer> charMap = new HashMap<>();
for (char c : chars) {
if (charMap.containsKey(c)) {
charMap.put(c, charMap.get(c) + 1);
} else {
charMap.put(c, 1);
}
}
// 计算A(n,n)的全排列
int result = calFactorial(chars.length);
// 处理重复的数据
for (Map.Entry<Character, Integer> entry : charMap.entrySet()) {
if (entry.getValue() > 1) {
result = result / calFactorial(entry.getValue());
}
}
System.out.println(result);
}
/**
* 计算阶乘
* @param num 数字
* @return 结果
*/
private static int calFactorial(int num) {
int result = 1;
for (int i = 2; i <= num; i++) {
result = result * i;
}
return result;
}
}
扩展场景2:输入一个纯大写字母的字符串(可能存在重复字母),对这个字符串中的所有字符进行重新排序,请输出所有字符不能重复?
package com.anran.example.test;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Scanner;
public class Test4 {
/**
* 场景:输入一个纯大写字母的字符串(可能存在重复字母),对这个字符串中的所有字符进行重新排序,请输出所有字符不能重复
* 输入:ABBC
*
* 输出:所有字符串的组合
*
* @param args
*/
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.next();
char[] chars = str.toCharArray();
// 判断其中重复的字符以及个数
Map<Character, Integer> charMap = new HashMap<>();
for (char c : chars) {
if (charMap.containsKey(c)) {
charMap.put(c, charMap.get(c) + 1);
} else {
charMap.put(c, 1);
}
}
calChildStr(charMap, new StringBuffer());
}
private static void calChildStr(Map<Character, Integer> charMap, StringBuffer sb) {
if (charMap.size() == 0){
// 如果已经没有值则输出结果
System.out.println(sb.toString());
return ;
}
Map<Character, Integer> copyMap = new HashMap<>();
copyMap.putAll(charMap);
for (Map.Entry<Character, Integer> entry : charMap.entrySet()) {
// 处理当前循环
char c = entry.getKey();
int count = entry.getValue();
sb.append(c);
// 处理下一个循环
if (count > 1) {
copyMap.put(c, charMap.get(c) - 1);
} else {
copyMap.remove(c);
}
calChildStr(copyMap, sb);
//处理当前循环结束
if (count > 1) {
copyMap.put(c, copyMap.get(c) + 1);
} else {
copyMap.put(c, 1);
}
// 删除之前添加的字符
sb.deleteCharAt(sb.length() - 1);
}
}
}