此题为第一题:密码测试
- 题目描述
- 解题思路
先将n个输入的字符进行排序,数字排在前面,字母排在后面
使用回溯法实现字符数组的全排列,动态生成字符串,当字符串的长度为m且第一个字符为数字且最后两个字符为字母,则符合条件,将字符串放到结果数组
全排列的代码模板可参考之前的另一篇文章:
https://blog.csdn.net/MiSiTeLin/article/details/115376368?spm=1001.2014.3001.5501
- 代码如下
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
/**
* @author junfeng.lin
* @date 2021/3/31 9:08
*/
public class Main {
//结果集合
static List<StringBuffer> result;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int m = sc.nextInt();
int n = sc.nextInt();
if (m < 3 || n < 3) {
return;
}
StringBuffer sb = new StringBuffer();
for (int i = 0;i < n;i++) {
sb.append(sc.next());
}
//先将字符数组排序
char[] chars = sb.toString().toCharArray();
Arrays.sort(chars);
/**
* 全排列+判断是否至少1数字加2字母
*/
result = new ArrayList<>();
getResult(chars ,new StringBuffer(), m, 0);
for (int j = 0;j < result.size();j++) {
System.out.println(result.get(j));
}
}
/**
* 分别为n个不同字符的数组,当前组合成的密码,密码长度,下一个字符
* @param chars
* @param cur
* @param m
* @param start
*/
public static void getResult(char[] chars, StringBuffer cur ,int m, int start) {
//加入结果数组
if (cur.length() == m && isRight(cur)) {
//此处要生成一个新对象,否则所有结果都引用同一个对象
result.add(new StringBuffer(cur));
return;
}
for (int i = start;i < chars.length;i++) {
//加入字符
cur.append(chars[i]);
//从i + 1开始向后递归
getResult(chars, cur, m, i + 1);
//减去当前字符
cur.deleteCharAt(cur.length() - 1);
}
}
/**
* 判断密码是否符合规则
* 第一个字符为数字,最后两个字符为字母即可
*/
public static boolean isRight(StringBuffer cur) {
if (cur.charAt(0) >= '0' && cur.charAt(0) <= '9' &&
cur.charAt(cur.length() - 1) >= 'a' && cur.charAt(cur.length() - 1) <= 'z' &&
cur.charAt(cur.length() - 2) >= 'a' && cur.charAt(cur.length() - 2) <= 'z') {
return true;
}
return false;
}
}
- 用例测试