[英]PHP Huffman Decode Algorithm
我最近申请了一份工作,并收到了一份有几个问题的黑客等级考试。其中一个是霍夫曼解码算法。 这里有一个类似的问题,它比我能更好地解释格式。
实际任务是接受两个参数并返回解码后的字符串。
第一个参数是代码,它是一个字符串数组,如:
[
"a 00",
"b 101",
"c 0111",
"[newline] 1001"
]
就像:单个字符,两个选项卡,霍夫曼代码。
由于黑客排名的设置方式,换行符被指定为这种格式。
第二个参数是要使用代码解码的字符串。 例如:
101000111 = bac
这是我的解决方案:
function decode($codes, $encoded) {
$returnString = '';
$codeArray = array();
foreach($codes as $code) {
sscanf($code, "%s\t\t%s", $letter, $code);
if ($letter == "[newline]")
$letter = "\n";
$codeArray[$code] = $letter;
}
print_r($codeArray);
$numbers = str_split($encoded);
$searchCode = '';
foreach ($numbers as $number) {
$searchCode .= $number;
if (isset($codeArray[$searchCode])) {
$returnString .= $codeArray[$searchCode];
$searchCode = '';
}
}
return $returnString;
}
它通过了两个初始测试,但还有另外五个隐藏测试没有通过并且没有给出任何反馈。
我意识到如果字符是空格,这个解决方案不会通过,所以我尝试了一个不太理想的解决方案,它使用 substr 来获取第一个字符和正则表达式匹配来获取数字,但这仍然通过了前两个,而隐藏的五个失败了。 我在hacker rank平台中尝试使用空格作为输入的函数,沙盒环境无论如何都无法处理它,所以我回到了上面的解决方案,因为它更优雅。
我尝试使用特殊字符、来自其他语言的字符、各种大小的代码的代码,它总是返回所需的解决方案。
我只是很沮丧,因为我发现这是一个优雅的解决方案,因此我找不到导致此失败的案例。 我希望得到一些关于为什么在没有空白的情况下会失败的反馈,以及关于性能提升的任何反馈。
你的基本方法是合理的。 由于霍夫曼代码是一个前缀代码,即没有代码是另一个代码的前缀,那么如果您的搜索找到匹配项,那么它必须是代码。 代码的后半部分将适用于任何适当的霍夫曼代码和使用它编码的任何消息。
一些评论。 首先,您提供的示例不是霍夫曼代码,因为前缀010
、 0110
、 1000
和11
不存在。 霍夫曼代码是完整的,而这个前缀代码不是。
这带来了第二个问题,即您没有检测到此错误。 您应该在循环结束后检查$searchCode
是否为空。 如果不是,则代码不完整,或者代码在中间结束。 无论哪种方式,相对于提供的前缀代码,消息都已损坏。 问题是否指定了如何处理错误?
我希望这段代码唯一真正的问题是你没有对代码描述进行足够的解码。 问题是说总是有两个选项卡,还是您得出结论? 也许它只是任意数量的空间和制表符。 您需要在哪里转换其他字符编码,例如[newline]
? 如果有效的示例之一包含一个,我认为您实际上确实需要转换它们。 做到了吗? 否则,也许你不应该转换。
我对编码挑战有同样的问题。 做了一些修改,因为输入是一个带有 (a 111101,b 110010,[newline] 111111 ....)
我采用了不同的方法来解决它,使用 hashmap 但我仍然只通过了 2 个示例测试用例。
下面是我的代码:
public static String decode(List<String> codes, String encoded) {
// Write your code here
String result = "";
String buildvalue ="";
HashMap <String,String> codeMap= new HashMap<String,String>();
for(int i=0;i<codes.size();i++){
String S= codes.get(i);
String[] splitedData = S.split("\\s+");
String value=splitedData[0];
String key=(splitedData[1].trim());
codeMap.put(key, value);
}
for(int j=0;j<encoded.length();j++){
buildvalue+=Character.toString(encoded.charAt(j));
if(codeMap.containsKey(buildvalue)){
if(codeMap.get(buildvalue).contains("[newline]")){
result+="\n";
buildvalue="";
}
else{
result+=codeMap.get(buildvalue);
buildvalue="";
}
}
}
return result.toString();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.