VB净。摩尔斯电码翻译器:使用 Mid() 剪切正确的符号并将它们与字母匹配

VB net. Morse code translator: cut correct signs using Mid() and match them with the letter

我正在尝试将摩尔斯电码翻译成 VB.net 中的文本。 使用下面的代码,文本中的一些字母保持未翻译状态。我认为问题出在 "oddel" 上,它应该指示在选择大小写时应该在 Mid(morsC, i, oddel) 中剪切多少个字母。 代码应该能够将此 >…./ ./ .-../ .-../ ---/< 翻译成 Hello.

奇怪的是,在翻译 "Hello" 时,第一个字母 "H" 被正确地截断为 " ..../" 但它与大小写不匹配 "H"

'Hello = …./ ./ .-../ .-../ ---/
Sub EE15a()
    Dim veta As String, morsCod As String, st As String
    morsCod = InputBox("Enter the morse code.")
    veta = morsCodF(morsCod)
    st = "Preklad dle funkce " + Chr(10) + veta + Chr(10)
    MsgBox(st)
End Sub
Function morsCodF(morsC As String) As String
    Dim pismeno As String, znak As String
    Dim i As Integer, j As Integer, oddel As Integer
    Dim nasel As Boolean
    znak = "/"
    morsC = Trim(morsC)
    j = 1
    For i = 1 To (morsC.Length)
        i = j
        Do
            If Mid(morsC, j, 1) = znak Then
                oddel = j - oddel
                nasel = True
                Exit Do
            End If
            j = j + 1
        Loop Until nasel = True Or j > (morsC.Length)
        If i = 1 Then
            pismeno = (" " + Mid(morsC, i, oddel))
        Else
            pismeno = Mid(morsC, i, oddel)
        End If
        Select Case pismeno '" ...-/"
            Case " .-/" : morsCodF = morsCodF + " a"
            Case " -.../" : morsCodF = morsCodF + " b"
            Case " -.-./" : morsCodF = morsCodF + " c"
            Case " -../" : morsCodF = morsCodF + " d"
            Case " ./" : morsCodF = morsCodF + " e"
            Case " ..-./" : morsCodF = morsCodF + " f"
            Case " --./" : morsCodF = morsCodF + " g"
            Case " ..../" : morsCodF = morsCodF + " h"
            Case " ../" : morsCodF = morsCodF + " i"
            Case " .---/" : morsCodF = morsCodF + " j"
            Case " -.-/" : morsCodF = morsCodF + " k"
            Case " .-../" : morsCodF = morsCodF + " l"
            Case " --/" : morsCodF = morsCodF + " m"
            Case " -./" : morsCodF = morsCodF + " n"
            Case " ---/" : morsCodF = morsCodF + " o"
            Case " .--./" : morsCodF = morsCodF + " p"
            Case " --.-/" : morsCodF = morsCodF + " q"
            Case " .-./" : morsCodF = morsCodF + " r"
            Case " .../" : morsCodF = morsCodF + " s"
            Case " -/" : morsCodF = morsCodF + " t"
            Case " ..-/" : morsCodF = morsCodF + " u"
            Case " ...-/" : morsCodF = morsCodF + " v"
            Case " .--/" : morsCodF = morsCodF + " w"
            Case " -..-/" : morsCodF = morsCodF + " x"
            Case " -.--/" : morsCodF = morsCodF + " y"
            Case " --../" : morsCodF = morsCodF + " z"
            Case "#" : morsCodF = morsCodF + " "
        End Select
        nasel = False
        pismeno = ""
        j = j + 1
    Next
End Function

代码应该翻译整个单词或句子,而不是只翻译部分文本。例如。 > …./ ./ .-../ .-../ ---/ 预期:"Hello",实际:"e o"

用“/”作为分隔符拆分字符串 morsCod

Public Class Form1
    Sub EE15a()
        Dim veta As String, morsCod As String, st As String
        'morsCod = InputBox("Enter the morse code.")
        morsCod = "..../ ./ .-../ .-../ ---/ --"
        morsCod = " .-/ -.../ -.-./ -../ ./ ..-./ --./ ..../ ../ .---/ -.-/ .-../ --/ -./ ---/ .--./ --.-/ .-./ .../ -/ ..-/ ...-/ .--/ -..-/ -.--/ --.."
        veta = morsCodF(morsCod)
        st = "Preklad dle funkce " + Chr(10) + veta + Chr(10)
        MsgBox(st)
    End Sub
    Function morsCodF(morsC As String) As String
        Dim arr As String() = morsC.Split("/"c)
        For Each s As String In arr
            Select Case s
                Case " .-" : morsCodF = morsCodF + " a"
                Case " -..." : morsCodF = morsCodF + " b"
                Case " -.-." : morsCodF = morsCodF + " c"
                Case " -.." : morsCodF = morsCodF + " d"
                Case " ." : morsCodF = morsCodF + " e"
                Case " ..-." : morsCodF = morsCodF + " f"
                Case " --." : morsCodF = morsCodF + " g"
                Case " ...." : morsCodF = morsCodF + " h"
                Case " .." : morsCodF = morsCodF + " i"
                Case " .---" : morsCodF = morsCodF + " j"
                Case " -.-" : morsCodF = morsCodF + " k"
                Case " .-.." : morsCodF = morsCodF + " l"
                Case " --" : morsCodF = morsCodF + " m"
                Case " -." : morsCodF = morsCodF + " n"
                Case " ---" : morsCodF = morsCodF + " o"
                Case " .--." : morsCodF = morsCodF + " p"
                Case " --.-" : morsCodF = morsCodF + " q"
                Case " .-." : morsCodF = morsCodF + " r"
                Case " ..." : morsCodF = morsCodF + " s"
                Case " -" : morsCodF = morsCodF + " t"
                Case " ..-" : morsCodF = morsCodF + " u"
                Case " ...-" : morsCodF = morsCodF + " v"
                Case " .--" : morsCodF = morsCodF + " w"
                Case " -..-" : morsCodF = morsCodF + " x"
                Case " -.--" : morsCodF = morsCodF + " y"
                Case " --.." : morsCodF = morsCodF + " z"
                Case "#" : morsCodF = morsCodF + " "
            End Select
        Next
    End Function

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        EE15a()
    End Sub
End Class

如果您需要将某些字母大写,则需要提供额外的逻辑(例如,首字母始终大写)。以下代码创建包含代码及其字母的字典,使用 Regex 解析摩尔斯电码字符串,逐个提取代码并根据这些代码获取字母。我创建了两个版本 - RegexSplit.

Dim morse = New Dictionary(Of String, String) From
{
    {".-", "a"},
    {"-...", "b"},
    {"-.-.", "c"},
    {".", "e"},
    {"....", "h"},
    {".-..", "l"},
    {"---", "o"},
    {"#", " "}
}

Dim s = "..../ ./ .-../ .-../ ---/"

'// 1. REGEX
'// Search for '.', '-' and '#' in any combinations followed by '/'
Dim mc = Regex.Matches(s, "[\.\-#]+(?=/)")
'// Fetch each code from dictionary and concatenate them
Dim x = String.Join("", mc.Cast(Of Match).Select(Function(m) morse(m.Value)))

'// 2. SPLIT
'// Dim x = String.Join("", s.Split({"/"}, StringSplitOptions.RemoveEmptyEntries).
'//                           Select(Function(z) morse(z.Replace("/", "").Trim())))

Console.WriteLine(x)

'// Output: hello

我认为如果您为 Select Case 开关添加默认大小写,您将获得更多代码反馈。

Select Case s
    Case " .-" : morsCodF = morsCodF + " a"
    Case "#" : morsCodF = morsCodF + " "
    Case Else : morsCodF = morsCodF + " WRONG! "
End Select
  1. 检查此行 oddel = j - oddel 是否按预期工作。
    根据您的逻辑,oddel 应该是先前找到的 / 个字符之后的字符数。如果是这样,那么计算 oddel = j - oddel 看起来不正确。
    因为您使用当前 j 计算更新 i 应该是 oddel = j - (i -1)

  2. 检查 For 循环。
    因为 i 每次都用当前值 j 更新,代码将进行一个额外的循环,产生 "wrong" 值。

  3. 其他建议。
    将摩尔斯电码解码为文本是从一个字符串到另一个字符串的简单映射。
    在 vb.net Dictionary(Of String, String) 中可能是一个很好的工具。

你真的需要/角色吗?相反,您可以使用简单的 space 作为字母分隔符。

Function FromMorse(code As String) As String
    Const DELIMETER As Char = " "c
    Static Secret As New Dictionary(Of String, String) From
    {
        {".-", "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"},
        {"#", " "}
    }

    Return code.Split(DELIMETER).
                Select(Function(c) Secret(c)).
                Aggregate(New StringBuilder(), Function(b, c) b.Append(c)).
                ToString()
End Function

用法

Dim code = ".... . .-.. .-.. --- # .-- --- .-. .-.. -.."
Dim decoded = FromMorse(code)

Console.WriteLine(decoded) ' => "hello world"

字典用于快速查找,String.Split 用于简洁,StringBuilder 用于避免在每次迭代时创建新字符串。

 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim s As String = GetTextFromMorse("..../ ./ .-../ .-../ ---/")
        Debug.Print(s)
 End Sub

 Private DictCode As New Dictionary(Of String, String) From
    {
        {".-", "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"},
        {"#", " "}
    }

Private Function GetTextFromMorse(input As String) As String
    Dim strArray() As String = input.Split({"/"}, StringSplitOptions.RemoveEmptyEntries)
    Dim sb As New StringBuilder
    For Each s In strArray
        sb.Append(DictCode(s.Trim))
    Next
    Return sb.ToString
End Function