康拓公式应用
问题:现在有"abcdefghijkl”12个字符,将其所有的排列中按字典序排列, 给出任意一种排列,说出这个排列在所有的排列中是第几小的?
公式:

code:
package yrc4;
import java.util.Scanner;
/*
*
现在有"abcdefghijkl”12个字符,将其所有的排列中按字典序排列,
给出任意一种排列,说出这个排列在所有的排列中是第几小的?
*/
public class Main13 {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
int n = s.nextInt();
//读物enter键(换行)
s.nextLine();
for(int i = 0; i < n; i++){
String str = s.nextLine();
char[] ch = str.toCharArray();
long res = find2(ch);
System.out.println(res);
}
s.close();
}
//通用算法
public static long find(char[] ch) {
long res = 1;
for(int i=0;i<ch.length;i++) {
int count = 0;
//寻找小于ch[i]的值并计数
for(int j=i+1;j<ch.length;j++) {
if(ch[j]<ch[i]) {
count++;
}
}
res+=count*factorial(ch.length-i);
}
return res;
}
//求n的阶乘
public static int factorial(int n) {
int sum = 1;
for(int i=1;i<n;i++) {
sum*=i;
}
return sum;
}
//另一种实现形式:基于该问题特性所做的改变
//最初的ch[i]-'a':记录小于当前位置的字符的数量(默认比自己小的值都在自己后面)
//计算当前位置后,后续所有大于当前值的位置,记录数量需要减1。表明最初的假设需要进行调整
public static long find2(char[] ch) {
long res = 1;
for(int i=0;i<ch.length;i++) {
res+=(ch[i]-'a')*factorial(ch.length-i);
for(int j=i+1;j<ch.length;j++) {
if(ch[j]>ch[i]) {
ch[j]--;
}
}
}
return res;
}
}
博客参考:https://blog.csdn.net/ltrbless/article/details/87696372

浙公网安备 33010602011771号