如何移除generate()内for循环 单循环加递归生成全量密码组合
实现需求
编写递归逻辑从给定字符数组中输出所有可重复的密码组合,规则如下:
- 输入示例:
"ab" - 预期输出:
a b aa ab ba bb
- 实现约束:
- 仅可在
crack()函数中使用一个循环 - 不得新增其他自定义函数
- 仅允许使用现有
crack()、generate()两个函数
- 仅可在
原有实现
import java.util.*; public class PasswordGen { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println("Please enter a string:"); char array[] = sc.next().toCharArray(); System.out.println("All Combination:"); crack(array); sc.close(); } static void crack(char[] array) { for (int i = 1; i <= array.length; i++) { generate(array, i, "", array.length); } } static void generate(char[] array, int i, String string, int length) { //recursion stopping if condition is meet if (i == 0) { System.out.println(string); return; } for (int j = 0; j < length; j++) { String charArray = string + array[j]; generate(array, i -1, charArray , length); } return; } }
原有实现的generate()函数内部包含一个for循环,需要移除该循环后得到完全一致的输出。
可行实现方案
核心思路是将原来for循环遍历字符下标的迭代逻辑,替换为递归遍历逻辑,不需要新增任何函数,仅需要小幅调整crack()的传参和generate()的递归逻辑,完全满足约束要求。
调整后完整代码
import java.util.*; public class PasswordGen { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println("Please enter a string:"); char array[] = sc.next().toCharArray(); System.out.println("All Combination:"); crack(array); sc.close(); } static void crack(char[] array) { for (int i = 1; i <= array.length; i++) { // 第四个参数改为当前遍历的字符起始下标,初始从0开始 generate(array, i, "", 0); } } static void generate(char[] array, int remainLen, String current, int idx) { // 终止条件1:剩余待拼接长度为0,输出当前组合 if (remainLen == 0) { System.out.println(current); return; } // 终止条件2:当前字符下标已经遍历完数组所有元素,直接返回 if (idx == array.length) { return; } // 分支1:选择当前idx位置的字符,拼接到当前串后,剩余长度减1,下一层从下标0开始重新选择所有字符(支持重复选字符) generate(array, remainLen - 1, current + array[idx], 0); // 分支2:不换当前密码长度,遍历下一个字符下标,替代原有for循环的迭代逻辑 generate(array, remainLen, current, idx + 1); } }
逻辑说明
crack()函数仍然只保留一个循环,作用是控制生成密码的长度从1到输入字符数组的长度,符合约束要求。generate()函数内部完全移除了for循环,通过两个递归分支实现原有逻辑:- 第一个分支负责选中当前下标的字符,进入下一位密码的生成,因为密码允许重复字符,下一层递归的字符下标重置为0。
- 第二个分支负责推进当前层的字符遍历,把下标+1后递归,完全替代原来for循环的下标迭代效果。
- 经测试输入
"ab"时,输出顺序和结果完全和预期一致。
内容的提问来源于stack exchange,提问作者PsychoBunny
相关产品推荐
相关产品推荐

