Быстрый декодер Морзе - PullRequest
       22

Быстрый декодер Морзе

2 голосов
/ 02 августа 2020
var morseText = ".... . -.--   - .... . .-. ."

На английском языке sh это «привет, привет»

var morseCodeArray: [String] = []

Это массив, в котором будут храниться отдельные буквы кода Морзе.

var currMorse: String = ""

currMorse используется для отслеживания текущей буквы Морзе.

for char in morseText {
  if char != " " {
    currMorse.append(char)
  } else {
    switch currMorse {
      case "": 
        currMorse += " "
      case " ":
        morseCodeArray.append(" ")
        currMorse = ""
      default: 
        morseCodeArray.append(currMorse)
        currMorse = ""
    }
  }
}
morseCodeArray.append(currMorse)

Не могли бы вы объяснить, что именно происходит в операторе switch ?

Я знаю, что Apple хочет, чтобы операторы switch были исчерпывающими, и, следовательно, у нас есть три case здесь.

Я не понимаю цель случая №1, т.е. case "":

Зачем нам нужен этот параметр null / nil? И даже если мы это сделаем, зачем нам тогда это делать -> currMorse + = ""

Мой мозг новичка в программировании думает, что нам нужен только случай №2, т.е. случай "":

Потому что все остальные параметры char (например, точки, тире в morseText) будут охвачены оператором if

Ответы [ 4 ]

1 голос
/ 02 августа 2020
Оператор

Switch проверяет значение переменной currMorse . Если вы посмотрите на оператор по умолчанию, он делает две вещи:

  1. добавляет текущий морс в массив
  2. сбрасывает значение currMorse

Если бы не было сброса, currMorse будет расти на каждом следующем шаге, и вы получите что-то вроде этого (просто закомментируйте строку):

....
.....
.....-.--
.....-.--
.....-.--
.....-.---
.....-.---....
.....-.---.....
.....-.---......-.

Случай переключателя case "": в значительной степени проверяет следующий случай:

char == " " && currMorse == ""

Если вы установите точку останова, вы увидите, что это произойдет ровно один раз.

1 голос
/ 02 августа 2020

Обычно, когда вы не понимаете, почему требуется определенный фрагмент кода или почему он работает именно так, я предлагаю запустить ваш код в отладчике, чтобы понять, что именно происходит.

Добавьте точки останова во все операторы ветвления и go в каждой строке кода и каждой итерации, чтобы понять эффект каждой строки.

Я только что запустил ваш код в отладчике. Написал в JS, но это не имеет значения. Вот что происходит:

  1. case "" требуется, потому что в вашем morseText сразу после -.-- есть точка, в которой встречается пустая строка. Случай принимает это как null и эффективно преобразует его в строку с пробелом с помощью этого оператора: currMorse += " "
  2. case: " " требуется для обработки вновь созданных пробелов в предыдущей итерации. Таким образом, он добавляет " " как элемент в ваш массив morseCodeArray.
1 голос
/ 02 августа 2020
for char in morseText {                  // iterates thru all characters in morseText
  if char != " " {                       // .. in case char is not one space character 
    currMorse.append(char)               // .. .. append character to currMorse
  } else {                               // .. otherwise case char must be space
    switch currMorse {                   // .. .. but what if currMorse {
      case "":                           // .. .. .. contains nothing yet?
        currMorse += " "                 // .. .. .. .. add space to currMorse 
                                         // .. .. .. .. no need to empty currMorse here
      case " ":                          // .. .. .. contains space allready?
        morseCodeArray.append(" ")       // .. .. .. .. append space to morseCodeArray
        currMorse = ""                   // .. .. .. .. and empty currMorse
      default:                           // .. .. .. if all above fail
        morseCodeArray.append(currMorse) // .. .. .. .. just append to morseCodeArray 
        currMorse = ""                   // .. .. .. .. and empty currMorse
    }                                    // .. .. } end of switch
  }                                      // .. } end of else
}                                        // } end of for loop
morseCodeArray.append(currMorse)         // add all valid currMorse to morseCodeArray

, поэтому он анализирует morseText и проверяет каждый символ на предмет не пробелов , поэтому это должна быть буква , но если она содержит пробел , затем проверьте, является ли currMorse пустым , и заполните один пробел в currMorse, чтобы добавить его в следующей итерации или в конце. Или currMorse это уже один пробел? это нормально, поэтому добавьте один пробел к результату и пустите currMorse (снова), в противном случае просто добавьте то, что currMorse еще содержит, и пусто currMorse, чтобы его нельзя было добавить позже, так только буквы и пробелы добавляются в конце .

Это имеет побочный эффект, совершенно очевидно, что пробелы из morseText не передаются в morseCodeArray напрямую и заменяются пробелами из currMorse .

1 голос
/ 02 августа 2020

В азбуке Морзе один пробел - это буква разделитель.

Пустая строка предназначена для обнаружения слова разделителя, технически "начинается ли слово с пробелом ".

В строке примера учитывается лишний пробел между y и t

Вы можете выполнить sh то же самое с components(separatedBy и reduce

let morseCodeArray = morseText.components(separatedBy: " ").reduce([String]()) { (result, string) -> [String] in
    if result.last?.isEmpty == true && string.isEmpty { // replace two consecutive empty items with one space
        return result.dropLast() + [" "]
    } else {
        return result + [string]
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...