考虑一个字符串,它的第一个字母总是"M"
,它的其他字符几乎可以是"I"s
和"U"s
的任意组合(不允许使用其他字母,只要Is
和Us
)例如:MIU
,MUI
,MIUIU
,MUIIUIU
,MUIIIUIIIUIII
,MIUUIUIIIUUI
,"III"
都是此类字符串。
我想要一个函数,给定任何这样的字符串作为输入,返回一个数组,其中包含模式"U"
可以使用的所有可能方式,如果它出现在输入字符串中,则在输入中替换为"III"
。例如,有两种方法可以用"U"
替换"MIIII"
,即MUI
和MIU
因此,给定MIIII
作为输入,函数应该返回[MUI, MIU]
。
这是我的(有缺陷的)功能。其背后的思想是循环输入字符串(即MIstring
)以查找"III"
每次发现"III"
时,MIstring
都会添加到IIIoptions
数组中,但"U"
会替换"III"
。
function ruleThree() {
var IIIoptions = [];
for (var i = 0; i < MIstring.length; i++) {
if (MIstring.slice(i, i+3) === "III") {
IIIoptions.push(MIstring.replace(MIstring.slice(i, i+3), "U"));
}
}
return IIIoptions;
}
给定输入
MIIII
,我希望函数返回[MUI, MIU]
。但是,它返回[MUI, MUI]
我尝试过使用不同的输入,但它显示了相同的问题,即数组中的所有项都是相同的例如,给定字符串MIIIIUIIIIU
,它将给我[MUIUIIIIU, MUIUIIIIU, MUIUIIIIU, MUIUIIIIU]
,而不是[MUIUIIIIU, MIUUIIIIU, MIIIIUUIU, MIIIIUIUU]
。所以这个函数得到了mistring right中包含的"III"s
个数,但是它没有返回我希望它返回的数组。我的功能怎么了?
最佳答案
主要的问题是您使用的是String.replace(),并且该方法将始终用您调用它的方式将第一个匹配的III
序列替换为U
当找到匹配项时,可以使用String.slice()生成带有替换项的新字符串,如下所示:
const input = "MIIIII";
function ruleThree(str)
{
var IIIoptions = [];
for (var i = 0; i < str.length; i++)
{
if (str.slice(i, i + 3) === "III")
IIIoptions.push(str.slice(0, i) + "U" + str.slice(i + 3));
}
return IIIoptions;
}
console.log(ruleThree(input));
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}
但是,请注意,如果一次需要多个替换,则前面的方法将失败,例如,如果输入
MIIIIII
,则不会生成MUU
字符串。在这种情况下,必须使用递归方式:const input = "MIIIIIII";
function getCombs(str, res = new Set())
{
for (var i = 0; i < str.length; i++)
{
if (str.slice(i, i + 3) === "III")
{
let r = str.slice(0, i) + "U" + str.slice(i + 3);
res.add(r);
getCombs(r, res);
}
}
return [...res];
}
console.log(getCombs(input));
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}