我正在用PHP编写一个基本的莫尔斯电码转换器,它可以获取字符串并将其转换为莫尔斯电码。它使用关联数组、foreach 循环和 for 循环。它可以工作,除了由于某种原因,它在每个转换字符后输出等效的摩尔斯电码"0"。我不知道 0 是从哪里来的。如果我从关联数组中删除 0,没有问题,但我也希望能够转换数字。如果有人能够给我一些反馈,那将不胜感激。
这是代码:
<?php
$string = "dog";
$string_lower = strtolower($string);
$assoc_array = array(
"a"=>".-",
"b"=>"-...",
"c"=>"-.-.",
"d"=>"-..",
"e"=>".",
"f"=>"..-.",
"g"=>"--.",
"h"=>"....",
"i"=>"..",
"j"=>".---",
"k"=>"-.-",
"l"=>".-..",
"m"=>"--",
"n"=>"-.",
"o"=>"---",
"p"=>".--.",
"q"=>"--.-",
"r"=>".-.",
"s"=>"...",
"t"=>"-",
"u"=>"..-",
"v"=>"...-",
"w"=>".--",
"x"=>"-..-",
"y"=>"-.--",
"z"=>"--..",
"0"=>"-----",
"1"=>".----",
"2"=>"..---",
"3"=>"...--",
"4"=>"....-",
"5"=>".....",
"6"=>"-....",
"7"=>"--...",
"8"=>"---..",
"9"=>"----.",
"."=>".-.-.-",
","=>"--..--",
"?"=>"..--..",
"/"=>"-..-.",
" "=>" ");
for($i=0;$i<strlen($string_lower);$i++){
foreach($assoc_array as $letter => $code){
if($letter == $string_lower[$i]){
echo "$code<br/>";
}
}
}
?>
主要问题是你做的"更多"超过了必要的。当您可以使用字符串从中获取所需的数据时,无需像这样循环遍历$assoc_array
。
这也使用更少的资源,因为您不是从a-z
0-9
循环,而是只循环所需的字母/数字/空格的确切数量。
/*Rest of your code above*/
for($i=0;$i<strlen($string_lower);$i++){
echo (isset($assoc_array[$string_lower[$i]])) ? $assoc_array[$string_lower[$i]] . '<br />' : 'ERROR';
}
由于您的数组包含从a-z
到0-9
的所有内容,因此您可以轻松地调用所需的字母,而不必担心丢失数据。
编辑:添加了isset()
检查,几乎不需要,因为$assoc_array
涵盖了每个需要的字母/数字,但安全总比抱歉好。(感谢@Farkie提醒我)
最简单的解决方法很简单,就是在回显后添加一个"中断":
foreach($assoc_array as $letter => $code){
if($letter == $string_lower[$i]){
echo "$code<br/>";
break;
}
}
真正的问题是 0 的计算结果为 false,这意味着当它循环时,它将是一个 truey (false == false)。
您可以通过执行相同的(===
)匹配来更好地解决它:
foreach($assoc_array as $letter => $code){
if($letter === $string_lower[$i]){
echo "$code<br/>";
break;
}
}
使用一些php函数式编程,比如array_reduce()
函数 http://php.net/manual/en/function.array-reduce.php
避免所有这些丑陋的 for 循环并大大简化您的代码:
$convert = function($carry, $item) {
$table = array(
"a" => ".-",
"b" => "-...",
"c" => "-.-.",
"d" => "-..",
"g" => "--.",
"o" => "---");
// Get the correspondent value for the given letter
$morse = $table[$item];
// Return the string with appended morse character
return $carry . $morse;
};
// Split 'dog' into an array, then apply a reduce to convert it to morse
array_reduce(str_split('dog'), $convert);
// ➜ ~ php morse.php
// -..-----.
我知道自从问题发布和给出答案以来已经有一段时间了。我想我会添加我为将来发现这个问题的人编写的这个功能。
法典
/**
* Convert string to morse
*
* @param string $string
* @return string
*/
function str_to_morse(string $string) {
// Make the string lowercase and create an array of the characters
$stringParts = str_split(strtolower($string));
// Define the dictionary
$morseDictionary = [
'a' => '.-',
'b' => '-...',
'c' => '-.-.',
'd' => '-..',
'e' => '.',
'f' => '..-.',
'g' => '--.',
'h' => '....',
'i' => '..',
'j' => '.---',
'k' => '-.-',
'l' => '.-..',
'm' => '--',
'n' => '-.',
'o' => '---',
'p' => '.--.',
'q' => '--.-',
'r' => '.-.',
's' => '...',
't' => '-',
'u' => '..-',
'v' => '...-',
'w' => '.--',
'x' => '-..-',
'y' => '-.--',
'z' => '--..',
'0' => '-----',
'1' => '.----',
'2' => '..---',
'3' => '...--',
'4' => '....-',
'5' => '.....',
'6' => '-....',
'7' => '--...',
'8' => '---..',
'9' => '----.',
'.' => '.-.-.-',
',' => '--..--',
'?' => '..--..',
'/' => '-..-.',
' ' => ' ',
];
$morse = '';
foreach ($stringParts as $stringPart) {
if (array_key_exists($stringPart, $morseDictionary)) {
$morse .= $morseDictionary[$stringPart] . '<br />';
}
}
return $morse;
}
这似乎是 PHP 语言最早出现的摩尔斯电码编码/解码问题,所以我想这是表明 PHP 具有可以使用关联数组翻译子字符串的本机函数的最佳位置。
strtr()
将寻找最长的排位赛并替换找到的子字符串。 与str_replace()
不同,strtr()
不会更换替代品。 preg_
技术似乎没有必要用于这项任务。
一旦你的输入字符串强制为小写(以匹配你的查找/转换数组键),并且每个字符之间有某种分隔字符,你就不需要循环——只需要strtr()
。
摩尔斯编码代码:(演示)
$string = "d o g";
echo strtr($string, CHAR_TO_MORSE);
// output: -.. --- --.
反转翻译就像翻转查找/翻译数组一样简单。
摩尔斯解码代码(演示)
$string = "-.. --- --.";
echo strtr($string, array_flip(CHAR_TO_MORSE));
// output: d o g
查找常量(基于 asker 的翻译数组)可以像这样声明:
const CHAR_TO_MORSE = [
"a" => ".-", "b" => "-...", "c" => "-.-.", "d" => "-..", "e" => ".",
"f" => "..-.", "g" => "--.", "h" => "....", "i" => "..", "j" => ".---",
"k" => "-.-", "l" => ".-..", "m" => "--", "n" => "-.", "o" => "---",
"p" => ".--.", "q" => "--.-", "r" => ".-.", "s" => "...", "t" => "-",
"u" => "..-", "v" => "...-", "w" => ".--", "x" => "-..-", "y" => "-.-- ",
"z" => "--..", "0" => "-----", "1" => ".----", "2" => "..---", "3" => "...--",
"4" => "....-", "5" => ".....", "6" => "-....", "7" => "--...", "8" => "---..",
"9" => "----.", "." => ".-.-.-", "," => "--..--", "?" => "..--..", "/" => "-..-.",
];