网站用户名,规则如下:
1. 同时包含大写字母、小写字母、数字
2. 长度12-20
给定任意字符串(简单起见,不包含其他特殊字符),可以对其进行增加、删除、替换操作,每次只能操作一个字符。问,最少经过多少次操作,能使其满足前面提到的网站用户名的要求
例如:
aaabbbccc -> 3
aaabbbcccdddeeefffggg -> 3
代码如下
import java.util.ArrayList;
import java.util.List;
public class WebsiteNameCheck {
public static void main(String[] args) {
WebsiteNameCheck cha = new WebsiteNameCheck();
cha.checkName("sd");
cha.checkName("sd1");
cha.checkName("sd1U");
cha.checkName("sdfjsdaaaa");
cha.checkName("1111111111");
cha.checkName("AAAAAAAAAAAA");
cha.checkName("AAAAAAAAAAAA112334DDDddddd");
cha.checkName("sdfjsd123");
cha.checkName("sdfUd123");
}
private static int MIN_LENGTH = 6;
private static int MAX_LENGTH = 12;
public void checkName(String src) {
//大写字母位置记录
List<Integer> upper = new ArrayList<>();
//小写字母位置记录
List<Integer> lower = new ArrayList<>();
//数字位置记录
List<Integer> num = new ArrayList<>();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < src.length(); i++) {
char ch = src.charAt(i);
sb.append(ch);
if (ch >= 'A' && ch <= 'Z') {
upper.add(i);
} else if (ch >= 'a' && ch <= 'z') {
lower.add(i);
} else {
num.add(i);
}
}
int index = this.adjust(sb, upper, lower, num);
System.out.println("src:" + src + " to desc:" + sb.toString() + " adjest:" + index);
}
public int adjust(StringBuilder sb, List<Integer> upper,
List<Integer> lower,
List<Integer> num) {
int index = 0;
// 长度不足时进行数据填充
if (sb.length() < MIN_LENGTH) {
if (sb.length() < MIN_LENGTH && upper.size() == 0) {
sb.append("U");
upper.add(sb.length() - 1);
index++;
}
if (sb.length() < MIN_LENGTH && lower.size() == 0) {
sb.append("u");
lower.add(sb.length() - 1);
index++;
}
if (sb.length() < MIN_LENGTH && num.size() == 0) {
sb.append("0");
num.add(sb.length() - 1);
index++;
}
// 后面即可随机填充,这里默认填充0
while (sb.length() < MIN_LENGTH) {
sb.append(0);
index++;
}
}
return index + this.adjustChar(sb, upper, lower, num);
}
/**
* 删除超长的字符
*
* @param sb 带操作的字符集合
* @param index 变化的次数
* @param more 删除的字符串索引
* @return
*/
private int removeExtraChar(StringBuilder sb, int index, List<Integer> more) {
for (int i = more.size(); i > 1 && sb.length() > MAX_LENGTH; i--) {
int j = more.get(i - 1);
sb.delete(j, j + 1);
index++;
}
return index;
}
private int adjustChar(StringBuilder sb, List<Integer> upper,
List<Integer> lower,
List<Integer> num) {
// 调整策略,找到最长的种类作为调整依据
List<Integer> replace = new ArrayList<>();
if (replace.size() < upper.size()) {
replace = upper;
}
if (replace.size() < lower.size()) {
replace = lower;
}
if (replace.size() < num.size()) {
replace = num;
}
int index = 0;
if (upper.size() == 0) {
sb.replace(replace.get(0), replace.get(0) + 1, "U");
upper.add(replace.get(0));
replace.remove(0);
index++;
}
if (lower.size() == 0) {
sb.replace(replace.get(0), replace.get(0) + 1, "u");
lower.add(replace.get(0));
replace.remove(0);
index++;
}
if (num.size() == 0) {
sb.replace(replace.get(0), replace.get(0) + 1, "0");
num.add(replace.get(0));
replace.remove(0);
index++;
}
if (replace.size() > MAX_LENGTH) {
replace = mergeTwoSortList(upper.subList(1, upper.size()), num.subList(1, num.size()));
replace = mergeTwoSortList(replace, lower.subList(1, lower.size()));
index = removeExtraChar(sb, index, replace);
}
return index;
}
public List<Integer> mergeTwoSortList(List<Integer> aList, List<Integer> bList) {
int aLength = aList.size(), bLength = bList.size();
List<Integer> mergeList = new ArrayList<Integer>();
int i = 0, j = 0;
while (aLength > i && bLength > j) {
if (aList.get(i) > bList.get(j)) {
mergeList.add(i + j, bList.get(j));
j++;
} else {
mergeList.add(i + j, aList.get(i));
i++;
}
}
// blist元素已排好序, alist还有剩余元素
while (aLength > i) {
mergeList.add(i + j, aList.get(i));
i++;
}
// alist元素已排好序, blist还有剩余元素
while (bLength > j) {
mergeList.add(i + j, bList.get(j));
j++;
}
return mergeList;
}
}
运行结果: