简体   繁体   English

在JavaScript中检查字符串中的符号

[英]Checking symbols in string in Javascript

I am doing a problem on coderbyte and the problem is as follows: 我在coderbyte上遇到问题,问题如下:

Using the JavaScript language, have the function SimpleSymbols(str) take the str parameter being passed and determine if it is an acceptable sequence by either returning the string true or false . 使用JavaScript语言,让函数SimpleSymbols(str)接受传递的str参数,并通过返回字符串truefalse来确定它是否是可接受的序列。 The str parameter will be composed of + and = symbols with several letters between them (ie. ++d+===+c++==a ) and for the string to be true each letter must be surrounded by a + symbol. str参数将由+=符号以及它们之间的几个字母组成(即++d+===+c++==a ),并且++d+===+c++==a字符串为true每个字母必须用+符号包围。 So the string to the left would be false . 因此,左侧的字符串将为false The string will not be empty and will have at least one letter. 该字符串将不为空,并且将至少包含一个字母。

The code that I have written is this: 我写的代码是这样的:

var SimpleSymbols = function(str){
    var alpha = /[A-Za-z]/;
    var symbolarr = str.split("");
    for(var i = 0; i < symbolarr.length; i++) {
        if(alpha.test(symbolarr[i])) { 
            if(symbolarr[i-1] != "+" & symbolarr[i+1] != "+") {
                return false;
            }
        }
    }   
    return true;
}    

The problem is that when I test the case SimpleSymbols("+a=") I am getting true I have read through my code a few times and can't debug this. 问题是,当我测试的情况下SimpleSymbols("+a=")我得到true我已经通过我的代码读几遍,无法调试此。 Can anyone spot the error? 谁能发现错误?

Tweaking your solution 调整您的解决方案

Replace & with && , they mean very different things. &&替换& ,它们的含义截然不同。

Minor comment: you don't need to split the string into an array to access its characters; 次要注释:您无需将字符串拆分为数组即可访问其字符; you can access them directly with str[i] . 您可以使用str[i]直接访问它们。

Ignore the commenter who said you need a range check: arr[-1] will just return undefined , which will not be equal to + as you would expect. 忽略说您需要进行范围检查的评论者: arr[-1]只会返回undefined ,它不会像您期望的那样等于+

Regexp solution 正则表达式解决方案

Test for the presence of a regexp giving the invalid sequence. 测试是否存在给出无效序列的正则表达式。 If it's there, the string is illegal. 如果存在,则字符串是非法的。

function SimpleSymbols(str) {
    return !/([^+]|^)[A-Za-z]([^+]|$)/).test(str);
}

In English: 用英语:

Test for the presence of the following regexp:
    Find any character other than +, or the beginning of the string
    followed by a letter
    followed by any character other than +, or the end of the string
If it is present, return false, else true

State machine approach 状态机方法

A useful way to think about writing such programs is as a state machine. 考虑编写此类程序的一种有用方法是使用状态机。 We will use three states: start for the beginning, have_plus when we have just seen a plus sign, and need_plus when we need a plus sign following a letter. 我们将使用三种状态: start的开始, have_plus当我们刚才看到一个加号,然后need_plus当我们需要以下一个字母加号。

function SimpleSymbols(str) {
    var state = "start";
    var alpha = /[A-Za-z]/;

    for (var i = 0; i < str.length; i++) {
        var type = alpha.test(str[i]) ? 'letter' : str[i] === '+' ? 'plus' : 'other';

        switch (state) {
            case "start":
                switch (type) {
                    case 'letter':                      return false;
                    case 'plus'    state = "have_plus"; break;
                    case 'other':                       break; 
                }
                break;
            case "need_plus":
                switch (type) {
                    case 'letter':                      return false;
                    case 'plus':   state = "have_plus"; break;
                    case 'other':                       return false;
                }
                break;
            case "have_plus":
                switch (type) {
                    case 'letter': state = "need_plus"; break;
                    case 'plus':                        break;
                    case 'other':  state = "start";     break;
                }
                break;
        }

    }
    if (state === "need_plus") return false;
    return true;
}

It's a little longer, but it might be more readable and more maintainable. 它稍长一些,但可能更具可读性和可维护性。 But we can do better. 但是我们可以做得更好。 We will encapsulate the state logic in a data structure as follows: 我们将状态逻辑封装在一个数据结构中,如下所示:

var transitions = {
    start:     {letter: "fail",      plus: "have_plus",   other: "start"},
    need_plus: {letter: "fail",      plus: "have_plus",   other: "fail"},
    have_plus: {letter: "need_plus", plus: "have_plus",   other: "start"},
    fail:      {letter: "fail",      plus: "fail",        other: "fail"}
};

Now our program just runs through the state machine: 现在,我们的程序仅通过状态机运行:

function SimpleSymbols(str) {
    var state = "start",
        alpha = /[A-Za-z]/;

    for (var i = 0; i < str.length; i++) {
        var type = alpha.test(str[i]) ? 'letter' : str[i] === '+' ? 'plus' : 'other';
        state = transitions[state][type];
    }
    return state != "fail";
}

We could bundle this up into a state-machine object: 我们可以将其捆绑成一个状态机对象:

function stateMachine(state, transitions) {
    return {
        go: function(type) { state = transitions[state][type]; }
        state: function() { return state; }
    };
}

Now we can write `SimpleSymbols' as 现在我们可以将`SimpleSymbols'编写为

function SimpleSymbols(str) {
    var machine = stateMachine("start", transitions),
        alpha = /[A-Za-z]/;

    for (var i = 0; i < str.length; i++) {
        var type = alpha.test(str[i]) ? 'letter' : str[i] === '+' ? 'plus' : 'other';
        machine.go(type);
    }
    return machine.state() != "fail";
}

It would be good practice to disentangle the classification of tokens from the logic for running the machine: 最好将令牌的分类与运行机器的逻辑区分开来:

function token_type(c) {
    return /A-Za-z]/.test(str[i]) ? 'letter' : str[i] === '+' ? 'plus' : 'other';
}

Then just 然后就

function SimpleSymbols(str) {
    var machine = stateMachine("start", transitions);
    for (var i = 0; i < str.length; i++) { machine.go(token_type(str[i])); }
    return machine.state() != "fail";
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM