我在coderbyte上遇到问题,问题如下:
使用JavaScript语言,使用函数
SimpleSymbols(str)
获取传递的str
参数并确定它是否为 通过返回字符串true
或false
来接受序列。该str
参数将由+
和=
符号组成,并带有多个字母 它们之间(即++d+===+c++==a
)和字符串各为true
字母必须用+
符号包围。所以左边的字符串 将是false
。该字符串不会为空,至少会有 一封信。
我写的代码是:
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;
}
问题在于,当我测试案例SimpleSymbols("+a=")
时,我得到true
我已经阅读了几次代码并且无法对此进行调试。有人能发现错误吗?
答案 0 :(得分:2)
将&
替换为&&
,它们意味着非常不同的东西。
次要评论:您不需要将字符串拆分为数组来访问其字符;您可以使用str[i]
直接访问它们。
忽略提到您需要进行范围检查的评论者:arr[-1]
将返回undefined
,这将不会等同于您所期望的+
。
测试是否存在给出无效序列的正则表达式。如果它在那里,字符串是非法的。
function SimpleSymbols(str) {
return !/([^+]|^)[A-Za-z]([^+]|$)/).test(str);
}
英文:
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
考虑编写此类程序的有用方法是作为状态机。我们将使用三种状态: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;
}
它会更长一些,但它可能更具可读性和可维护性。但我们可以做得更好。我们将状态逻辑封装在数据结构中,如下所示:
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"}
};
现在我们的程序只运行状态机:
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";
}
我们可以将它捆绑到状态机对象中:
function stateMachine(state, transitions) {
return {
go: function(type) { state = transitions[state][type]; }
state: function() { return state; }
};
}
现在我们可以将`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";
}
将标记的分类与运行机器的逻辑分开是很好的做法:
function token_type(c) {
return /A-Za-z]/.test(str[i]) ? 'letter' : str[i] === '+' ? 'plus' : 'other';
}
然后只是
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";
}