字典序排列算法解析

字典序排列算法解析字典序全排列算法分析 给定一组字符串 s 首先将字符串转化为字符数组 c 将字符数组 c 中的元素从小到大排序 得到的即为字典序全排列的第一个排列 因为每个字符的大小是按照他的 Ascii 码对应的数字比较大小的 所以这里以一串数字为例 例如 15432 其实可以将字典序全排列看作数字进位的过程 例如 从后往前数 倒数第四位的数达到了最大值 即从后往前找 后面的数总是小于或等于前面的数 满足从尾部向前递增

private static boolean nextPermutate(char[] data) { int end = data.length - 1; int swapPoint1 = end, swapPoint2 = end; // the actual swap-point is swapPoint1 - 1 while (swapPoint1 > 0 && data[swapPoint1] <= data[swapPoint1 - 1])//从尾部向前找到第一个变小的数 swapPoint1--; if (swapPoint1 == 0) return false; else { while (swapPoint2 > 0 && data[swapPoint2] <= data[swapPoint1 - 1])//从尾部到swapPoint1找到第一个大于swapPoint1-1的位置 swapPoint2--; swap(data, swapPoint1 - 1, swapPoint2); reverse(data, swapPoint1, end);//用的是反转的操作,但其实起到的作用是从小到大排序。 return true; } } private static void swap(char[] data, int left, int right) { //调换顺序 char temp = data[left]; data[left] = data[right]; data[right] = temp; } private static void reverse(char[] data, int left, int right) { for (int i = left, j = right; i < j; i++, j--) swap(data, i, j); } 
public static void Prim(char[] data) { Arrays.sort(data); do{ System.out.println(data); }while(nextPermutate(data)//data 下一个排列); } 

以上代码是将全排列依次打印,也可以按需要改为接收全排列,代码如下:

public static void Prim(char[] data,char[][] q) {//传入一个二维数组q接收全排列 Arrays.sort(data); int i =0; do{ for(int j = 0; j< data.length; j++){ q[i][j] = data[j]; } i++; }while(nextPermutate(data)); } 

因为要传入一个二维数组q用来接收全排列列表,所以要对其大小定义。

 int len = s.length(); //s为传入的字符串 int l = factorial(len); //总排列数 char [][] q = new char [l][len]; Prim(s.toCharArray(),q);//将字符串s转为字符数组,获取其字典序全排列结果 public static int factorial(int n){ int sun = 1; for(int i=1; i<= n; i++){ sun = sun * i; } return sun; } 

4.寻找谜底

public static void main(String[] args) { //接收输入 Scanner sc = new Scanner(System.in); int n = 0; if(sc.hasNext()){ n = sc.nextInt(); } String rv[] = new String[n]; for(int i = 0; i < n; i++){ rv[i] = sc.next(); } for(int i = 0; i < n; i++){ miDi(rv[i]); } } public static void miDi(String s){ //输出s 的谜底 int len = s.length(); int l = factorial(len); //总排列数 char [][] q = new char [l][len]; Prim(s.toCharArray(),q);//字典序全排列结果 int indexB = (indexA(q,s.toCharArray()) + len)%l; //谜底 System.out.println(q[indexB]); } public static int indexA(char[][]q, char[] d){ for(int i = 0; i < q.length; i++){ if(charCompare(q[i], d)){ return i; } } return -1; } public static boolean charCompare(char[] a, char[] b){ for(int j = 0; j < a.length; j++){ if (a[j] != b[j]){ return false; } } return true; } 
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/228941.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月16日 下午5:50
下一篇 2026年3月16日 下午5:50


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号