Java使用Stack实现字符串全排列结果缺失如何修复
Java字符串全排列迭代实现问题排查与修复
问题根因
原代码无法生成完整全排列的核心问题有4个:
- 栈状态缺失:仅将初始输入字符串压入处理栈,交换生成的中间字符串从未压入栈做后续层级处理,仅完成了第一个位置的交换逻辑,无法深入处理后续位置的排列。
- 状态绑定错误:分开用两个独立栈存储字符串和固定位置索引,没有将当前待处理字符串和它对应的处理位置绑定,且所有交换操作都基于原始输入字符串执行,而非基于上一步生成的中间字符串,导致子排列完全丢失。
- 栈弹出逻辑错误:在非终止分支直接弹出栈内元素,第一次循环处理完初始字符串的第一层交换后就把栈清空,循环直接终止。
- 结果添加时机错误:在交换的第一层循环就直接把中间交换结果加入返回集,没有等排列所有位置固定完成再收集结果,既会漏结果也会混入无效中间状态。
修复后完整代码
import java.util.Stack; import java.util.Vector; public class Permutation { public static Vector<String> permIter(String u) { Vector<String> result = new Vector<>(); if (u == null || u.isEmpty()) { return result; } int strLen = u.length(); // 栈存储二元组:[当前待排列的字符串, 当前需要固定的字符位置索引] Stack<Object[]> processStack = new Stack<>(); processStack.push(new Object[]{u, 0}); while (!processStack.isEmpty()) { Object[] currentState = processStack.pop(); String currStr = (String) currentState[0]; int fixIndex = (int) currentState[1]; // 所有位置都固定完成,加入结果集 if (fixIndex == strLen - 1) { result.add(currStr); continue; } // 倒序遍历交换位置,利用栈后进先出的特性保证输出顺序和递归实现一致 for (int i = strLen - 1; i >= fixIndex; i--) { String swappedStr = swapChar(currStr, fixIndex, i); processStack.push(new Object[]{swappedStr, fixIndex + 1}); } } return result; } // 交换字符串指定两个位置的字符 private static String swapChar(String s, int pos1, int pos2) { char[] charArr = s.toCharArray(); char temp = charArr[pos1]; charArr[pos1] = charArr[pos2]; charArr[pos2] = temp; return new String(charArr); } public static void main(String[] args) { Vector<String> permutations = permIter("abc"); System.out.println("全排列结果:"); for (String str : permutations) { System.out.println(str); } System.out.println("排列总数量:" + permutations.size()); } }
修复效果说明
- 输入
"abc"运行代码,会按顺序输出abc、acb、bac、bca、cab、cba共6个正确排列结果。 - 返回的Vector集合的
size()值就是排列总数量,无重复无遗漏。 - 实现逻辑完全对齐递归版全排列的固定位置+交换思路,仅用栈模拟递归的栈帧存储,没有用递归方法,符合迭代实现的要求。
内容的提问来源于stack exchange,提问作者Gianfranco Mauro
相关产品推荐
相关产品推荐

