请考虑一个字符串,其首字母始终为"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中包含的"III"s
的数量,但不会返回我希望它返回的数组。
我的功能出了什么问题?
答案 0 :(得分:2)
主要问题是您正在使用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;}