@pavelsazonov

Как решить задачу на dictionaries из книги?

Если я правильно понял условие, надо написать функцию, которая принимает строку и возвращает словарь, в котором ключ - символ из строки, значение - сколько раз он повторяется в строке.
Вот оригинал:
Declare a function occurrencesOfCharacters that calculates which characters occur in a string, as well as how often each of these characters occur. Return the result as a dictionary. This is the function signature:
func occurrencesOfCharacters(in text: String) -> [Character: Int]
func occurencesOfCharacters(in text: String) -> [Character: Int] {
  var dicOfChars: [Character: Int] = [:]
  var i = 1
  for character in text.characters {
    if dicOfChars.updateValue(i, forKey: character) != nil {
      dicOfChars[character] = i + 1
      i += 1
    } else {
      i = 1
      dicOfChars[character] = i
    }
  }
  return dicOfChars
}
print(occurencesOfCharacters(in: "memerr")) // ["r": 2, "m": 2, "e": 3]


Как видите, у меня проблема с переменной i, в которой я отслеживаю количество повторений символа.
Либо просто тут нужно другое решение.
  • Вопрос задан
  • 351 просмотр
Решения вопроса 2
DevMan
@DevMan
func occurencesOfCharacters(in text: String) -> [Character: Int] {
  var dicOfChars: [Character: Int] = [:]
  for character in text.characters {
	  if dicOfChars[character] != nil {
		  dicOfChars[character]? += 1
	  }
	  else {
		  dicOfChars[character] = 1
	  }
  }
  return dicOfChars
}
print(occurencesOfCharacters(in: "memerr"))
Ответ написан
Начиная с Swift 4, следующее решение более короткое:

func occurencesOfCharacters(in text: String) -> [Character: Int] {
  return Dictionary(text.map{ ($0, 1) }, uniquingKeysWith: { $0 + $1 })
}
print(occurencesOfCharacters(in: "memerr"))

Как это работает
В Swift 4, .characters не нужно, так как строки - это последовательности символов.
Код text.map{ ($0, 1) } даёт последовательность вида ("m", 1), ("e", 1), ...
Конструктор Dictionary превращает эту последовательность в словарь вида ["m": 1, "e": 1, ...].
Когда этот конструктор встречает две пары с одинаковыми ключами, он мержит их значения по указанному правилу, по сути, подсчитывая количество вхождений данного символа.

Замечу, что решение от DevMan, выписанное "вручную", должно работать более быстро, так как там нет промежуточного представления в виде последовательности кортежей. Но только если убрать двойное обращение к Dictionary на каждой итерации.

Edit: Этот код должен чуть быстрее работать. Мог бы быть ещё быстрее, но увы, в Dictionary нет для этого некоторых нужных методов.
func occurencesOfCharacters(in text: String) -> [Character: Int] {
  var dicOfChars: [Character: Int] = [:]
  for character in text.characters {
    dicOfChars[character] = (dicOfChars[character] ?? 0) + 1
  }
  return dicOfChars
}
print(occurencesOfCharacters(in: "memerr"))
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы