【发布时间】:2020-01-08 02:14:12
【问题描述】:
我一直在尝试解决this codewars challenge。这个想法是返回字符串,根据其层次结构重新排列,或者根据重复字符分成块。
您将收到一个由小写字母、大写字母和数字组成的字符串作为输入。您的任务是将此字符串作为由破折号(“-”)分隔的块返回。块的元素应按照下面列出的层次结构进行排序,并且每个块不能包含同一字符的多个实例。
层次结构是:
小写字母 (a - z),按字母顺序排列 大写字母 (A - Z),按字母顺序 数字 (0 - 9),按升序排列 例子
"21AxBz" -> "xzAB12"
- 由于输入不包含重复字符,因此您只需要 1 个块
"abacad" -> "abcd-a-a"
- 字符“a”重复 3 次,因此需要 3 个块
"" -> ""
- 空输入应导致空输出
我尝试过的实际上适用于给定的测试用例:
describe("Sample tests", () => {
it("Tests", () => {
assert.equal(blocks("21AxBz"), "xzAB12");
assert.equal(blocks("abacad"), "abcd-a-a");
assert.equal(blocks(""), "");
});
});
但是当有任何重复字符时会失败,除了在测试用例中:
function repeatingChar(str){
const result = [];
const strArr = str.toLowerCase().split("").sort().join("").match(/(.)\1+/g);
if (strArr != null) {
strArr.forEach((elem) => {
result.push(elem[0]);
});
}
return result;
}
function blocks(s) {
if (s.length === 0) {
return '';
}
//if string does not contain repeating characters
if (!/(.).*\1/.test(s) === true) {
let lower = s.match(/[a-z]/g).join('');
let upper = s.match(/[A-Z]/g).join('');
let numbers = s.match(/[\d]/g).sort().join('');
return lower + upper + numbers;
}
//if string contains repeating characters
if (!/(.).*\1/.test(s) === false) {
let repeatChar = (repeatingChar(s)[0]);
let repeatRegex = new RegExp(repeatingChar(s)[0]);
let repeatCount = s.match(/[repeatRegex]/gi).length;
let nonAChars = s.match(/[^a]/gi).join('');
function getPosition(string, subString, index) {
return s.split(repeatChar, index).join(repeatChar).length;
}
let index = getPosition(s, repeatChar, 2);
// console.log('indexxxxx', index);
return s.slice(0, index) + nonAChars.slice(1) + ('-' + repeatChar).repeat(repeatCount - 1);
}
}
console.log(blocks("abacad"));
实际上,我不确定它有什么问题,因为我不知道如何解锁 Codewars 上的任何其他测试。
您可以看到我正在尝试做的是找到重复字符,获取所有不是重复字符的字符,然后将字符串从起点切到重复字符的 2 个实例,然后在末尾添加剩余的重复字符,用破折号分隔。
关于如何做到这一点的任何其他建议?
【问题讨论】:
标签: javascript regex string substring