2016-09-29 4 views
0

Я пытаюсь проверить, введен ли пользователь в массиве букв. А затем переведите письмо в код Морзе, который является массивом Морзе. Мне пришлось использовать массив символов для отображения ввода пользователя по порядку, но он отображает код Морзе в алфавитном порядке. Как я могу остановить отображение его правильно? Заранее спасибо.check char array против другого массива vb.net

Dim strCode As String = txtCode.Text.ToUpper 'What the user enters must be letters it can also be - or = 
    Dim strText() As Char = strCode.ToCharArray 

    Dim strLetter() As String = {"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"} 
    Dim strMorse() As String = {"*=", "=***", "=*=*", "=**", "*", "**=*", "==*", "****", "**", "*===", "=*=", "*=**", "==", "=*", "===", "*==*", "==*=", "*=*", "***", "=", "**=", "***=", "*==", "=**=", "=*==", "==**"} 

    For Each letter As Char In strText 
     For x As Integer = 0 To strLetter.Length - 1 
      If strCode.Contains(strLetter(x)) Then 
       MessageBox.Show(strMorse(x)) 
      End If 
     Next 
    Next 
End Sub 

ответ

2

Просто использовать словарь и перебор всех символов в строке и вам не придется беспокоиться о поиске символов и перевода их в правильном порядке. Используйте букву алфавита в качестве ключа и кода Морзе в качестве значения ... то вы можете просто пройти через текст и перевести каждую букву так:

Dim translate 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", "==**"}} 
    Dim translatedMsg As String = Nothing 
    For Each c As Char In txtCode.Text.ToUpper 
     translatedMsg += translate(c) & " " 
    Next 
    Debug.Print(translatedMsg.TrimEnd) 

    'Output for "Hello World": **** * *=** *=** === *== === *=* *=** =** 

Edit: Ну, идя назад от значения к его ключу не так чисто, как переход от ключа к значению, потому что для него нет никакой нативной функции, но Linq отлично подходит для этого ... и, если честно, я не думал о пробелы, переводящие сначала. Я мог бы добавить специальный символ в словарь для пробелов, и это упростит перевод. Но, тем не менее, я буду придерживаться своего первого примера, например, и вот как вы переводите сообщение назад. Я снова использовал «Hello World», и чтобы обойти проблему с пробелами, я просто подменил подчеркивание для пространства, чтобы я мог правильно декодировать сообщение (также, очевидно, вы теряете разницу в верхнем/нижнем регистре, поскольку код Морзе не различает два):

Dim strMorseMsg As String = "**** * *=** *=** === *== === *=* *=** =**" 

    strMorseMsg = strMorseMsg.Replace(" ", " _ ") 'substitution here to distinguish spaces between words from the space between letters 
    Dim aryMorseMsg() As String = strMorseMsg.Split(CChar(" ")) 

    Dim originalMessage As String = Nothing 
    For Each code As String In aryMorseMsg 
     If code.Equals("_") Then 'here's where the underscore helps branch our logic between adding a space and adding a letter 
      originalMessage += " " 
     Else 
      originalMessage += translate.FirstOrDefault(Function(x) x.Value = code).Key 
     End If 
    Next 
    MsgBox(originalMessage) 

    'Outputs "HELLO WORLD" 
+0

Nice решение, что это именно то, что словарь для. Обратите внимание, что вам понадобятся пробелы между буквами. В противном случае получатель не будет знать, означает ли '***' 'EEE',' EI', 'IE' или' S'. – Heinzi

+0

О да, очень хороший момент! – soohoonigan

+0

@Heinzi I второй это! Со словарем я могу легко сказать, что точка кода, и сразу же знать, как проверить перевод, если я чувствую необходимость. –

2

Если вы выполните свой код с помощью чего-то простого, например «BA», вы увидите логическую ошибку. Вы никогда не сравниваете букву во внешнем цикле с чем-либо во внутреннем. Вместо этого ваш оператор If спрашивает: «Эй, мой вход содержит первую букву в моем массиве strLetter?» Да, «A» там (хотя это не первый символ).

Проще простого решения для назначения будет использовать смещение значения ASCII буквы от «A», если буква находится в пределах диапазона (между A и Z). Это устраняет необходимость определения strLetter. Вы также можете опустить преобразование входного текста в массив символов. Строка уже позволяет вам перечислять символы.

Dim strCode As String = txtCode.Text.ToUpper 'What the user enters must be letters it can also be - or = 

Dim strMorse() As String = {"*=", "=***", "=*=*", "=**", "*", "**=*", "==*", "****", "**", "*===", "=*=", "*=**", "==", "=*", "===", "*==*", "==*=", "*=*", "***", "=", "**=", "***=", "*==", "=**=", "=*==", "==**"} 

For Each letter As Char In strCode 
    If letter >' "A"c AndAlso letter <= "Z"c Then 
    MessageBox.Show(strMorse(AscW(letter) - AscW("A"c))) 
    End If 
Next 
+0

Спасибо. Я попробую. Все еще нова для всего этого, поэтому помощь ценится. – StudentNeedsHelp

0
Sub Main() 
    Dim codes() As String = { _ 
     "*=", "=***", "=*=*", "=**", "*", "**=*", "==*", "****", "**", _ 
     "*===", "=*=", "*=**", "==", "=*", "===", "*==*", "==*=", "*=*", _ 
     "***", "=", "**=", "***=", "*==", "=**=", "=*==", "==**" _ 
    } 

    Dim input As String = Console.ReadLine().ToUpper() 

    ' Convert characters to values that can be used as indexes in the code array 
    Dim indexes = input.[Select](Of Integer)(Function(l As Char) Asc(l) - 65) 
    ' limit the values to based on the range of possible values 
    Dim boundsCheck = indexes.Where(Function(l As Integer) l >= 0 And l <= 26) 
    ' map the valid inputs to codes fro myour array 
    Dim outCodes = boundsCheck.[Select](Of String)(Function(l As Integer) codes(l)) 
    ' concatenate the codes into a string and display 
    Console.WriteLine(String.Join(" ", outCodes)) 
End Sub