我正在尝试完成代码挑战,我必须将手机t9输入的键击解码为字符以创建短信。主函数(reverse_t9)采用一串键,例如" 44 444"或" 999337777"我需要将它们翻译成相应的文本(" hi"或者#34;是"分别)。
我已经完成所有逻辑并且可以生成正确的输出,但挑战是告诉我,我超过了4000毫秒的时间限制。我发现了一些可以提高性能的地方,但仍然无法达到这个标准。我认为最大的浪费时间是我的" getLetterFromDigits"函数必须迭代我的数组才能找到一组击键的相应映射。
我是否遗漏了其他一些明显的性能问题?如果您需要更多信息,请与我们联系。
function reverse_t9(keys) {
var retVal = "";
var maxKeystrokes = 3;
var splitKeystrokes = splitKeystrokesBySpacesAndKeys(keys);
for (i = 0, numSplits = splitKeystrokes.length; i < numSplits; i++){
//console.log("THIS SPLIT:");
//console.log(splitKeystrokes[i]);
//console.log("THIS LETTER:");
//console.log(getLetterFromDigits(splitKeystrokes[i]));
retVal = retVal + getLetterFromDigits(splitKeystrokes[i]);
}
return retVal;
}
function splitKeystrokesBySpacesAndKeys(keys) {
var retVal = [];
var lastKey = "";
var thisKey = "";
var lastSplit = 0;
var isSpace = 0;
for (i = 0, numKeys = keys.length; i <= numKeys; i++) {
thisKey = keys.substring(i, i + 1);
if (i == 0) {
// FIRST TIME AROUND, DO NOTHING ELSE, JUST ASSIGN LAST KEY
lastKey = thisKey;
} else {
if (thisKey != lastKey) {
if (thisKey != " ") {
if (lastKey != " ") {
retVal.push(keys.substring(lastSplit, i));
} else {
retVal.push(keys.substring(lastSplit, i - 1));
}
lastSplit = i;
}
lastKey = thisKey;
} else {
// KEY DID NOT CHANGE, ASSIGN LAST KEY AND CONTINUE ON
lastKey = thisKey;
}
}
}
return retVal;
}
function getLetterFromDigits(digits){
var retVal;
var digitMapping = [
{
digit: "1",
mapping: []
},
{
digit: "2",
mapping: ["a", "b", "c"]
},
{
digit: "3",
mapping: ["d", "e", "f"]
},
{
digit: "4",
mapping: ["g", "h", "i"]
},
{
digit: "5",
mapping: ["j", "k", "l"]
},
{
digit: "6",
mapping: ["m", "n", "o"]
},
{
digit: "7",
mapping: ["p", "q", "r", "s"]
},
{
digit: "8",
mapping: ["t", "u", "v"]
},
{
digit: "9",
mapping: ["w", "x", "y", "z"]
},
{
digit: "0",
mapping: ["*"]
}
];
var digit = digits.substring(0, 1);
for (i = 0, numMappings = digitMapping.length; i < numMappings; i++){
if (digitMapping[i].digit == digit){
retVal = digitMapping[i].mapping[digits.length - 1];
break;
}
}
return retVal;
}
答案 0 :(得分:2)
首先,在函数之外声明您的数字映射,这样您就可以重用该工作的结果,而不是每次调用该函数时都执行该工作。
其次,make digitMapping
使用键/值对,这样您就可以根据给定的属性名进行快速查找,而不必循环遍历它。
var digitMapping =
{
"1": [],
"2": ["a", "b", "c"],
...
};
function getLetterFromDigits(digits){
var digit = digits.substring(0, 1);
return digitMapping[digit][digits.length - 1];
}
答案 1 :(得分:1)
几个指针:
Array.length
将检查每次迭代。{
"1": [],
"2": ["a", "b", "c"]
},
并将其抓取为digitMapping[mapping[digits.length - 1]]
thisKey = keys.substring(i, i + 1);
之类的变量中,而不是char_arr = keys.split("")
,而不是lastKey = char_arr[0]
。lastKey=keys.charAt(0)
或if (thisKey != lastKey)
lastKey = thisKey;
的其他部分。如果两个值相同,则无需设置if (!Monitor.TryEnter(...)) return;
答案 2 :(得分:0)
试试我的版本。
function getMsg(val){
//split digits to array
val = val.split('');
//some internal vars
var letter = [];
var last = val[0];
var msg='';
for(var i=0,n=val.length;i<n;i++){
if(val[i]==last)
//collect sequential digits
letter.push(val[i]);
else{
//new digit
msg += digMap[letter[0]][letter.length-1];
//reinit letter array
letter=[val[i]];
last = val[i];
}
}
msg += digMap[letter[0]][letter.length-1];
return msg; //return decoded
}
//map digits as @Rajesh recommended
var digMap={
"1":[" "],
"2":'abc'.split(''),
"3":'def'.split(''),
"4":'ghi'.split(''),
"5":'jkl'.split(''),
"6":'mno'.split(''),
"7":'pqrs'.split(''),
"8":'tuv'.split(''),
"9":'wxyz'.split(''),
"0":["*"],
" ":['']
}
//test functionality
console.time('txt');
console.log(getMsg('999337777'));
//yes
console.timeEnd('txt');