RatiboR1978
@RatiboR1978

Как сделать такую сортировку?

Доброе время суток! Изучаю js вот застрял с такой задачей: Дан массив со словами. Отсортируйте его следующим образом: первое слово должно быть первым по алфавиту, следующее за ним слово должно начинаться на ту букву, на которую заканчивается первое слово или, если такого слова в массиве нет, должно начинаться на ближайшую по алфавиту букву.
К примеру, первое слово заканчивается на "а", значит второе слово должно начинаться на "а", или на "б", если слов на "а" нету. И так далее.
Вот мой код: https://codepen.io/RatiboR1978/pen/WKXBOx?editors=1010 я реализовал то что в массиве набираются слова у которых последняя буква первого слова совпадает с первой буквой второго слова, но не могу додуматься как сделать когда берется уже не первая буква второго слова а последующие. Не знаю понятно объяснил или нет. Прошу помощи.
  • Вопрос задан
  • 249 просмотров
Решения вопроса 2
Stalker_RED
@Stalker_RED
Для начала алфавит:
let alphabet = 'абвгдеёжзийклмнопрстуфхцчшщъыьэюя'.split('')
charcode использовать нельзя, потому что в юникоде буква "ё" идет после буквы "я". И это, похоже, навсегда.

Дальше функция, которая определяет "расстояние" между буквами.
function getRange(a, b) {
  let iA = alphabet.indexOf(a), iB = alphabet.indexOf(b) // ищем на каких позициях встречаются эти буквы в алфавите
  if (iA === -1 || iB === -1) return Infinity // если вообще не встречаются - расстояние бесконечность.
  return Math.abs(iA - iB)
}


getRange('а', 'р') // -> 17
getRange('а', 'я') // -> 32
getRange('к', 'в') // -> 9
getRange('а', 'f') // -> Infinity  (и никто не мешает добавить английский алфавит)


На основе этой функции не сложно написать сортировку по расстоянию:
function getClosestWord(letter) {
  return [...words].sort((word1, word2) => {
  	return getRange(word1[0], letter) - getRange(word2[0], letter)
  })
}

getClosestWord('а') // ->
["аметист", "баржа", "дом", "еж", "креветка", "каток", "кот", "лимон", "море", "морж", "нора", "рога", "рыба", "рак", "сани", "сом", "собака", "том", "танк"]

getClosestWord('п') // ->
["рыба", "рак", "рога", "нора", "собака", "сани", "сом", "танк", "море", "том", "морж", "лимон", "каток", "кот", "креветка", "еж", "дом", "баржа", "аметист"]


Дело за малым - повторять пока не закончатся слова.
Ответ написан
Комментировать
0xD34F
@0xD34F Куратор тега JavaScript
не могу додуматься как сделать когда берется уже не первая буква второго слова а последующие

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

Как отсортировать алфавит (точнее - получить отсортированную копию): получаете индекс последней буквы последнего слова, создаёте массив с последней буквой, затем делаете цикл от 1 до размера алфавита, закидываете в массив элементы исходного алфавита с индексами, равными индексу последней буквы +/- текущее значение счётчика цикла. Потом отфильтровываете из массива undefined элементы (ну или делайте соответствующую проверку ещё в цикле, тогда ничего фильтровать не надо) - алфавит готов.

UPD. Выглядеть это может как-то так:
const alphabet = 'абвгдеёжзийклмнопрстуфхцчшщъыьэюя'.split('');
const arr = [ 'нора','дом','аметист','баржа','танк','каток','еж','рак','сом','морж','рога','том','сани','лимон','рыба','кот','собака','море','креветка' ];
const result = [];

getWord(alphabet);


while (arr.length) {
  const lastLetter = result[result.length - 1].split('').pop();
  const lastLetterIndex = alphabet.indexOf(lastLetter);
  let letters = [ lastLetter ];

  for (let i = 1; i < alphabet.length; i++) {
    letters.push(alphabet[lastLetterIndex + i], alphabet[lastLetterIndex - i]);
  }
  letters = letters.filter(n => !!n);

  getWord(letters);
}

console.log(arr);
console.log(result);

function getWord(letters) {
  for (let i = 0; i < letters.length; i++) {
    const letter = letters[i];
    const index = arr.findIndex(n => n[0] === letter);

    if (index !== -1) {
      result.push(arr.splice(index, 1)[0]);
      return;
    }
  }
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

Похожие вопросы