接下来是挑战:
在求职面试中,你要写一个算法来检查给定的字符串s是否可以由另外两个字符串part1和part2组成。 限制是part1和part2中的字符与s中的字符顺序相同。 面试官给出了以下示例,并告诉您从给定的测试用例中找出其余部分。
我做错了什么?无论如何它为什么会失败?
我写了两个不同的脚本,两个都不适用于某些测试用例
function isMerge(s, part1, part2) {
var sArr = s.split('');
var part1Arr = part1.split('');
var part2Arr = part2.split('');
var tempArr = new Array(sArr.length);
function compareArrays(arr1, arr2){
var count = 0;
for (var i = 0; i < arr1.length; i++) {
if (arr1[i] !== arr2[i]) count++;
}
return (count == 0);
}
for (var i = 0; i < sArr.length; i++) {
for (var j = 0; j < part1Arr.length; j++) {
if (sArr[i] == part1Arr[j]) tempArr[i] = j;
}
for (var k = 0; k < part2Arr.length; k++) {
if (sArr[i] == part2Arr[k]) tempArr[i] = k;
}
}
alert(tempArr);
var check = tempArr.slice();
check.sort();
alert(check);
if (compareArrays(tempArr, check)) return true;
else return false;
}
alert(isMerge('codewars', 'cdw', 'oears'));
function isMerge(s, part1, part2) {
// create arrays of letters
var sArr = s.split('');
var part1Arr = part1.split('');
var part2Arr = part2.split('');
// create an associative array 'temp' (0:C, 1:O and so on)
var temp = {};
for (var k = 0; k < sArr.length; k++) {
temp[k] = sArr[k];
}
// reverse an associative array 'temp' (now C:0, O:0 and so on)
for (var key in temp) {
var keyTemp = key;
var keyValue = temp[key];
key = keyValue;
temp[key] = keyTemp;
}
// the function that compares arrays
function compareArrays(arr1, arr2){
var count = 0;
for (var i = 0; i < arr1.length; i++) {
if (arr1[i] !== arr2[i]) count++;
}
return (count == 0);
}
// sorting function
function order(a, b) {
var comparingA;
var comparingB;
for (var char in temp) {
if (char == a) {
comparingA = temp[char]; // comparingA is the number of 'a' in object 'temp'
}
if (char == b){
comparingB = temp[char]; // comparingB is the number of 'b' in object 'temp'
}
}
return (comparingA - comparingB);
}
// create copies of arrays
var part1Sorted = part1Arr.slice();
var part2Sorted = part2Arr.slice();
// and sort that copies
part1Sorted.sort(order);
part2Sorted.sort(order);
// If the array did not change after sorting, the order of the letters was correct
if (compareArrays(part1Sorted, part1Arr) && compareArrays(part2Sorted, part2Arr)) {
// so now we can check is merge possible
sArr = sArr.sort();
var parts = part1Arr.concat(part2Arr);
parts = parts.sort();
var res = compareArrays(sArr, parts);
return res;
}
return false;
}
alert(isMerge('codewars', 'code', 'wasr'));
alert(isMerge('codewars', 'oers', 'cdwa'));
我刚刚在第二个脚本中添加了评论
答案 0 :(得分:2)
我发现很难理解您的代码尝试做什么。如果您提供评论并解释您试图实施的算法背后的想法,将会有所帮助。
这是一个递归的注释示例,它考虑指针i
和j
是否指向第1部分和第1部分。 2可以构成到那一点的有效合并。
function isMerge(s, part1, part2) {
// Merge is invalid if the parts' lengths don't add up to the string's
if (part1.length + part2.length != s.length)
return false;
// Recursive function
function g(i, j){
// Base case: both pointers are exactly at the end of each part
if (i == part1.length && j == part2.length)
return true;
// One of our pointers has extended beyond the part's length,
// that couldn't be right
if (i > part1.length || j > part2.length)
return false;
// Just part1 matches here so increment i
if (part1[i] == s[i + j] && part2[j] != s[i + j])
return g(i + 1, j);
// Just part2 matches here so increment j
else if (part1[i] != s[i + j] && part2[j] == s[i + j])
return g(i, j + 1);
// Both parts match here so try incrementing either pointer
// to see if one of those solutions is correct
else if (part1[i] == s[i + j] && part2[j] == s[i + j])
return g(i + 1, j) || g(i, j + 1);
// Neither part matches here
return false;
}
// Call the recursive function
return g(0,0);
}
console.log(isMerge('codewars', 'cdw', 'oears'));
console.log(isMerge('codecoda', 'coda', 'code'));
console.log(isMerge('codewars', 'oers', 'cdwa'));
console.log(isMerge('codewars', 'cdw', 'years'));
&#13;
真正长字符串的堆栈版本:
function isMerge2(s, part1, part2) {
if (part1.length + part2.length != s.length)
return false;
let stack = [[0,0]];
while (stack.length){
[i, j] = stack.pop();
if (i == part1.length && j == part2.length)
return true;
if (i > part1.length || j > part2.length)
continue;
if (part1[i] == s[i + j] && part2[j] != s[i + j])
stack.push([i + 1, j]);
else if (part1[i] != s[i + j] && part2[j] == s[i + j])
stack.push([i, j + 1]);
else if (part1[i] == s[i + j] && part2[j] == s[i + j]){
stack.push([i + 1, j]);
stack.push([i, j + 1]);
}
}
return false;
}
function test(){
let s = '';
for (let i=0; i<1000000; i++)
s += ['a','b','c','d','e','f','g'][~~(Math.random()*6)];
let lr = {
l: '',
r: ''
};
for (let i=0; i<s.length; i++){
let which = ['l', 'r'][~~(Math.random()*2)];
lr[which] += s[i];
}
console.log(isMerge2(s,lr.l,lr.r));
}
test();
&#13;
答案 1 :(得分:1)
您可以使用递归方法,首先检查字符串和部分字符串的长度,然后检查长度或检查字符并检查给定部分字符串的其余部分。
function isMerge(s, part1, part2) {
if (s.length !== part1.length + part2.length) {
return false;
}
if (!s.length) {
return true;
}
if (part1[0] === s[0] && isMerge(s.slice(1), part1.slice(1), part2)) {
return true;
}
if (part2[0] === s[0] && isMerge(s.slice(1), part1, part2.slice(1))) {
return true;
}
return false;
}
console.log(isMerge('codewars', 'cdw', 'oears')); // true
console.log(isMerge('codewars', 'oers', 'cdwa')); // true
console.log(isMerge('codecoda', 'coda', 'code')); // true
console.log(isMerge('baeabb', 'b', 'baeab')); // true
console.log(isMerge('bdab', 'bdab', '')); // true
console.log(isMerge('bfaef', 'f', 'bfae')); // true
console.log(isMerge('codewars', 'cdw', 'years')); // false
console.log(isMerge('codewars', 'code', 'warss')); // false
console.log(isMerge('codewars', 'codes', 'wars')); // false
console.log(isMerge('', 'a', 'b')); // false
.as-console-wrapper { max-height: 100% !important; top: 0; }
function isMerge(s, part1, part2) {
var stack = [[s, part1, part2]];
if (s.length !== part1.length + part2.length) {
return false;
}
while (stack.length) {
[s, part1, part2] = stack.shift();
if (!s.length) {
return true;
}
if (part1[0] === s[0]) {
stack.push([s.slice(1), part1.slice(1), part2]);
}
if (part2[0] === s[0]) {
stack.push([s.slice(1), part1, part2.slice(1)]);
}
}
return false;
}
console.log(isMerge('codewars', 'cdw', 'oears')); // true
console.log(isMerge('codewars', 'oers', 'cdwa')); // true
console.log(isMerge('codecoda', 'coda', 'code')); // true
console.log(isMerge('baeabb', 'b', 'baeab')); // true
console.log(isMerge('bdab', 'bdab', '')); // true
console.log(isMerge('bfaef', 'f', 'bfae')); // true
console.log(isMerge('codewars', 'cdw', 'years')); // false
console.log(isMerge('codewars', 'code', 'warss')); // false
console.log(isMerge('codewars', 'codes', 'wars')); // false
console.log(isMerge('', 'a', 'b')); // false
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 2 :(得分:1)
这是一种递归方法:它检查字符串的第一个字符与其中任何一个部分的匹配,如果匹配recurses,则尝试将其余字符串与其余字符串匹配部分。棘手的是,当两个部分的第一个字符相同时,你必须检查你是否可以匹配其中任何一个(这解决了Bananas测试)。
function isMerge(str, p1, p2) {
if (!str.length) return !p1.length && !p2.length;
if (p1.length && str.charAt(0) == p1.charAt(0)) {
if (p2.length && str.charAt(0) == p2.charAt(0)) {
return isMerge(str.substr(1), p1.substr(1), p2) || isMerge(str.substr(1), p1, p2.substr(1));
}
else {
return isMerge(str.substr(1), p1.substr(1), p2);
}
}
else if (p2.length && str.charAt(0) == p2.charAt(0)) {
return isMerge(str.substr(1), p1, p2.substr(1));
}
else {
return false;
}
}
答案 3 :(得分:0)
你可以在下面试试吗?
function isMerge(s, part1, part2) {
var result= true;
var total = part1 + part2;
for (var i = 0; i < s.length; i++) {
var char = s.charAt(i);
if(total.indexOf(char) === -1) {
result = false;
break;
}
}
return result;
}
答案 4 :(得分:0)
首先,这是您的代码正常工作:
function isMerge(s, part1, part2) {
var sArr = s.split('');
var part1Arr = part1.split('');
var part2Arr = part2.split('');
var tempArr = new Array(sArr.length);
function compareArrays(arr1, arr2){
var count = 0;
for (var i = 0; i < arr1.length; i++) {
if (arr1[i] != arr2[i]) count++;
}
return (count == 0);
}
for (var i = 0; i < sArr.length; i++) {
for (var j = 0; j < part1Arr.length; j++) {
if (sArr[i] == part1Arr[j]) tempArr[i] = part1Arr[j];
}
for (var k = 0; k < part2Arr.length; k++) {
if (sArr[i] == part2Arr[k]) tempArr[i] = part2Arr[k];
}
}
alert(tempArr);
if (compareArrays(tempArr, sArr)) return true;
else return false;
}
alert(isMerge('codewars', 'cdw', 'oears'));
现在,问题是什么?
for (var j = 0; j < part1Arr.length; j++) {
/* Here you assigned the index (tempArr[i] = j;) not the char */
if (sArr[i] == part1Arr[j]) tempArr[i] = part1Arr[j];
}
for (var k = 0; k < part2Arr.length; k++) {
/* Here you assigned the index (tempArr[i] = k;) not the char */
if (sArr[i] == part2Arr[k]) tempArr[i] = part2Arr[k];
}
希望我能帮助你;)
答案 5 :(得分:0)
简单合并逻辑:
function isMerge(s, part1, part2) {
var sArr = s.split('');
var part1Arr = part1.split('');
var part2Arr = part2.split('');
var j = 0;
var k = 0;
for (var i = 0; i < sArr.length; i++) {
if ((j < part1Arr.length) && (sArr[i] == part1Arr[j]))
j++
else if ((k < part2Arr.length) && (sArr[i] == part2Arr[k]))
k++
else
break
}
return (j == part1Arr.length && k == part2Arr.length && (j + k) == sArr.length);
}
console.log(isMerge('abcd', 'ac', 'bd'));
console.log(isMerge('abcd', 'acd', 'b'));
console.log(isMerge('abcd', 'ac', 'b'));
console.log(isMerge('abcd', 'ac', 'db'));
console.log(isMerge('abcd', 'c', 'b'));
console.log(isMerge('a', '', 'a'));
console.log(isMerge('', '', ''));
console.log(isMerge('', 'a', 'b'));
console.log(isMerge('ab', '', ''));