【问题标题】:Cannot get my head around this basic algorithm involving a simple for-loop?无法理解这个涉及简单 for 循环的基本算法?
【发布时间】:2019-10-03 02:12:50
【问题描述】:

考虑一个字符串,其首字母始终为"M",而其其他字符几乎可以是"I"s"U"s 的任意组合(不允许使用其他字母,只有IsUs)。例如:MIUMUIMIUIUMUIIUIUMUIIIUIIIUIIIMIUUIUIIIUUI都是这种字符串。

我想要一个函数,它给定任何这样的字符串作为输入,返回一个数组,该数组具有模式 "III" 的所有可能方式,如果它出现在输入字符串中,则在输入中用 "U" 替换。比如"MIIII"中的"III"可以用"U"替换有两种方式,即MUIMIU。因此,给定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 的数量,但它没有返回我期望它返回的数组。

我的功能有什么问题?

【问题讨论】:

  • 这是因为您的 .replace 总是替换 第一个 III -- 无论实际位置是什么。你需要的是result.push(slice-before-the-position + U + slice-after-the-position) 而不是replace
  • 或者,如果您不需要使用for() 循环,请使用reduce() 并避免代码的副作用。
  • 谢谢大家的回答!

标签: javascript arrays string algorithm for-loop


【解决方案1】:

主要问题是您使用的是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;}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-14
    • 1970-01-01
    • 1970-01-01
    • 2013-10-15
    • 1970-01-01
    • 1970-01-01
    • 2021-03-16
    • 2020-07-06
    相关资源
    最近更新 更多