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

Posted

技术标签:

【中文标题】VB网。摩尔斯电码翻译器:使用 Mid() 剪切正确的符号并将它们与字母匹配【英文标题】:VB net. Morse code translator: cut correct signs using Mid() and match them with the letter 【发布时间】:2018-12-25 17:49:39 【问题描述】:

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

奇怪的是,在翻译“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

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

【问题讨论】:

【参考方案1】:

用“/”作为分隔符分割字符串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

【讨论】:

【参考方案2】:

如果你需要一些大写字母,你需要提供额外的逻辑(例如,第一个字母总是大写)。以下代码使用代码及其字母创建字典,使用正则表达式解析摩尔斯电码字符串,一一提取代码并根据这些代码获取字母。我创建了两个版本 - 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

【讨论】:

这是另一种方法,但为什么 OP 的代码不起作用? 你可以用字典(morse) 做到这一点,没有“正则表达式魔法”:text.Split("/ ").Select(Function(c) morse[c]).Aggregate(new StringBuilder(), Function(b, c) b.Append(c)).ToString() @Fabio 实际上,我确实有 Split 版本 - 你没看到吗? 很好,是的。我从来没有读过 cmets,因为他们从不说真话;) @Fabio 实际上,有一个代码,甚至在答案的文本中提到了两个版本! ?新年快乐! ?【参考方案3】:

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

Select Case s
    Case " .-" : morsCodF = morsCodF + " a"
    Case "#" : morsCodF = morsCodF + " "
    Case Else : morsCodF = morsCodF + " WRONG! "
End Select

    检查此行 oddel = j - oddel 是否按预期工作。 根据您拥有的逻辑 oddel 应该是先前找到的 / 字符之后的字符数。如果是这样,那么计算 oddel = j - oddel 看起来不正确。 因为你用当前的j 更新i 计算应该是oddel = j - (i -1)

    检查For循环。 因为i 每次都更新为j 的当前值,所以代码会产生一个额外的循环,这将产生“错误”的值。

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

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

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"

【讨论】:

很高兴您永远不会阅读此内容,但您使用空格作为分隔符的版本更难阅读。斜线更便于维护。【参考方案4】:

用于快速查找的字典、用于简洁的 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

【讨论】:

不错的复制粘贴 ;)

以上是关于VB网。摩尔斯电码翻译器:使用 Mid() 剪切正确的符号并将它们与字母匹配的主要内容,如果未能解决你的问题,请参考以下文章

摩尔斯电码音频解码器(Android)[关闭]

CTF 基础 1(摩尔斯电码)

摩尔斯电码

i love you用摩尔斯电码怎么写?

摩尔斯电码解码

摩尔斯电码解码