编写递归算法以获取字符串的字谜。
字符串abc
的预期输出为['abc', 'acb', 'bac', 'bca', 'cab', 'cba']
但是,我得到的是[ 'abc', 'acb', 'ba', 'cab', 'cba' ]
。
我知道问题出在哪里: 当递归返回到0级(意味着str ==='abc'和i == 1)时,子串工作(exracts'a'),但切片不工作(不提取c)。
function anagramPermutationMemo(str, memo, resultsArr, level) {
if (!memo) {
memo = '';
resultsArr = [];
level = 0;
}
console.log('str -', str);
console.log('memo -', memo, '\n');
if (str.length === 0) {
resultsArr.push(memo);
return;
}
for (var i in str) {
console.log('level', level);
console.log('str', str);
console.log('i -', i, str[i]);
console.log('substring', str.substring(0, i));
console.log('slice', str.slice(i + 1));
var newStr = str.substring(0, i).concat(str.slice(i + 1));
console.log('newStr - ', newStr, '\n');
anagramPermutationMemo(newStr, memo + str[i], resultsArr, level + 1);
}
level -= 1;
console.log('backtrack', level,'\n');
return resultsArr;
};
答案 0 :(得分:1)
如果您还记录i+1
(您传递给slice
)的值,这将有所帮助。 problem with your for…in
enumeration是枚举属性,即字符串。您的i
将为"0"
,"1"
和"2"
(如果使用可枚举方法扩展String.prototype
,则可能还有其他内容)。
当你为它添加1时,它会进行字符串连接,你最终会得到"01"
,"11"
和"21"
而不是所需的数字。鉴于slice
将其参数转换为数字,"01"
实际上按照需要工作,但其他的将在字符串结束后导致索引,因此您最终完全省略这些部分:
anagramPermutationMemo("abc".substring(0, "1")+"abc".slice("11"), ""+"abc"["1"], […], 0+1);
// ^^^^ should be 2
anagramPermutationMemo("a", "b", […], 1);
// ^ should be "ac"
要解决此问题,只需使用标准for (var i=0; i<str.length; i++)
循环。
答案 1 :(得分:0)
我知道问题出在哪里
问题是for..in
循环。
说明:
variable
循环的{p> for..in
是String
,而不是Number
。括号内的符号
str[i]
返回预期结果,因为object的属性是一个字符串,例如str["0"]
; Number
也可用于在括号表示法str[0]
中获取对象的属性。
String.prototype.slice()
调用ToInteger
参数,但不使用sign
ToInteger
抽象操作ToInteger将其参数转换为整数 数值。这个抽象操作的功能如下:
- 设number是输入参数上调用ToNumber的结果。
- 如果number为NaN,则返回+0。
- 如果number为+ 0,-0,+∞或-∞,则返回数字。
- 返回计算结果
醇>sign
(数字)×floor
(绝对(数字))。
String.prototype.substring()
期望Number
作为参数。
如果任一参数为
NaN
或为负,则将其替换为零;如果 两个参数都大于String的长度,它是 替换为String的长度。
解决方案,用for
循环代替for..in
循环
function anagramPermutationMemo(str, memo, resultsArr, level) {
if (!memo) {
memo = '';
resultsArr = [];
level = 0;
}
console.log('str -', str);
console.log('memo -', memo, '\n');
if (str.length === 0) {
resultsArr.push(memo);
return;
}
for (var i = 0; i < str.length; i++) {
console.log('level', level);
console.log('str', str);
console.log('i -', i, str[i]);
console.log('substring', str.substring(0, i));
console.log('slice', str.slice(i + 1));
var newStr = str.substring(0, i).concat(str.slice(i + 1));
console.log('newStr - ', newStr, '\n');
anagramPermutationMemo(newStr, memo + str[i], resultsArr, level + 1);
}
level -= 1;
console.log('backtrack', level, '\n');
return resultsArr;
};
var p = anagramPermutationMemo("abc");
console.log(p);
解决方案:
i
使用Number
运算符在+
调用.substring()
,.slice()
时使用for..in
投放Number
参数} loop,其中方法的参数期望function anagramPermutationMemo(str, memo, resultsArr, level) {
if (!memo) {
memo = '';
resultsArr = [];
level = 0;
}
if (str.length === 0) {
resultsArr.push(memo);
return;
}
for (var i in str) {
var newStr = str.substring(0, +i).concat(str.slice(+i + 1));
var _newStr = str.substring(0, i).concat(str.slice(i + 1));
console.log(`newStr with string as parameter:${_newStr}`);
console.log(`newStr with number as parameter:${newStr}`);
console.log(`i:${str.substring(0, i)}, ${str.slice(i + 1)}`);
console.log(`+i:${str.substring(0, +i)}, ${str.slice(+i + 1)}`)
anagramPermutationMemo(newStr, memo + str[i], resultsArr, level + 1);
}
level -= 1;
return resultsArr;
};
Object.defineProperty(String, "abc", {
value:123,
enumerable:true
})
var p = anagramPermutationMemo("abc");
console.log(p);
。
class User(db.Model):
name = db.StringProperty(required=True)
pw_hash = db.StringProperty(required=True)
email = db.StringProperty()
@classmethod
def by_id(cls, uid):
return cls.get_by_id(uid, parent=users_key())
@classmethod
def by_name(cls, name):
u = cls.all().filter('name=', name).get()
return u
@classmethod
def register(cls, name, pw, email=None):
pw_hash = make_pw_hash(name, pw)
return cls(parent=users_key(),
name=name,
pw_hash=pw_hash,
email=email)
@classmethod
def login(cls, name, pw):
u = cls.by_name(name)
if u and valid_pw(name, pw, u.pw_hash):
return u