我想以这种方式将这个数字“12145”映射到字符
12145-> 1,2,1,4,5->一种,B,A,d,E
它也可以是
12145-> 12,1,4,5-> l,a,d,e
它也可以是
12145-> 12,14,5-→1,M,E
等等,
但是12145不能是1,2,1,45,因为在字母表中没有45的映射。
任何人都可以解释一个简单的算法来生成这些排列吗?
答案 0 :(得分:1)
"12345"
所以基本上起初我们想得到我们的大数字字符串的子字符串,它们是一个或两个字节长,所以我们只从一个字节开始:
["1", "2","3","4","5"]
然后我们将其中两个从左到右分组:
["12","3","4","5"]
["12","34","5"]
我们继续不是从头开始,而是在第二个char:
["1","23","4","5"]
["1","23","45"]
我们重复此操作直到将最后一个分组,我们应该拥有所有组合:
var val = (12345 +"").split("");//convert to string array
var result = [val.slice(0)];
//the start at loop:
for(var start = 0; start < val.length - 1; start++){
//join groups one after each other:
var grouped = [];
for(var i = start; i < val.length - 1; i+=2){
//group sth:
grouped.push( val.slice(i,i+2).join("") );
//generate the result:
result.push(
val.slice(0,start).concat(//the numbers before the grouping
grouped,//the grouped
val.slice(i+2)) //after grouping
);
}
}
你现在唯一需要做的就是转换回一个数字,过滤掉&gt; 26(如果当前分组为&gt; 26,甚至更好地打破内循环),并将它们转换为带有以下内容的字母: / p>
String.fromCharCode( number + 40 );
//A is 41, B is 42, so number + 40 should do it
答案 1 :(得分:1)
您可以尝试获取单个数字或双数字并获取其字母值。
它适用于带有两个参数fork
和left
的递归函数right
,而left
是给定字符串,right
是临时数组用于收集有效数字字符表示的部分组。
在函数fork
开始时,退出条件检查是否所有字符都已分发。在这种情况下,如果字符串left
的长度为0,则临时数组右转换为字母字符串并推送到结果集,同样也返回该函数。
主要部分基本相同,检查子字符串值是否有效,大于零且小于或等于26,然后使用没有新子字符串和数组的字符串再次调用递归函数其中也包含新的子字符串。
最后,result
包含所有可能的组合。
function getCombinations(string) {
function fork(left, right) {
if (!left.length) {
result.push(right.map(function (v) { return (+v + 9).toString(36); }).join(''));
return;
}
if (+left[0] > 0) {
fork(left.slice(1), right.concat(left[0]));
}
if (left.length >= 2 && +(left.slice(0, 2)) <= 26) {
fork(left.slice(2), right.concat(left.slice(0, 2)));
}
}
var result = [];
fork(string, []);
return result;
}
console.log(getCombinations('12145'));
&#13;