题解 | #密码验证合格程序#
密码验证合格程序
http://www.nowcoder.com/practice/184edec193864f0985ad2684fbc86841
let input = readline();
const inputList = [];
while(input) {
inputList.push(input);
input = readline();
}
function validator(str) {
if (str.length < 9) {
return false;
}
// 大写字母
const upperLetter = /[A-Z]/;
// 小写字母
const lowerLetter = /[a-z]/;
// 数字
const num = /[0-9]/;
// 其他字符,不含空格或换行
const others = /[^a-z0-9\s]/i;
// 统计满足的条件个数,至少满足三个条件
let count = 0;
if (upperLetter.test(str)) {
count++;
}
if (lowerLetter.test(str)) {
count++;
}
if (num.test(str)) {
count++;
}
if (others.test(str)) {
count++;
}
// 至少满足三个条件,否则校验失败
if (count < 3) {
return false;
}
// 判断是否存在长度大于2且没有公共元素的重复子串,
// 把字符串按长度为3的大小拆分成段,判断这些字符串段中是否有重复的,
// 而且也要判断重复的两段字符串是否有公共元素,用下标是否存在交集判断,
// 如果存在交集,则还不属于“长度大于2的不含公共元素的子串重复”,map中只记录
// 某种长度为3的子串第一次出现时的开始和结束下标。
const arr = str.split('');
// <key, value>,key: 长度为3的子串,value: [startIdx, endIdx],子串key第一次出现时的开始和结束下标
const map = new Map();
for (let i = 0, len = arr.length; i < len - 2; i++) {
const s = `${arr[i]}${arr[i + 1]}${arr[i + 2]}`;
// 有长度大于2的重复字串
if (map.has(s)) {
const range = map.get(s);
// 进一步判断两个重复子串有没有公共元素,没有公共元素则校验失败
if (i > range[1]) {
return false;
}
} else {
map.set(s, [i, i + 2]);
}
}
return true;
}
inputList.forEach(ipt => {
if (validator(ipt)) {
console.log('OK');
} else {
console.log('NG');
}
});

