#javascript #arrays #time-complexity #big-o
#javascript #массивы #временная сложность #big-o
Вопрос:
Я создаю простую игру hangman с использованием Javascript и хотел узнать, каким будет наилучший способ оптимизации моего кода.
const Hangman = function (word, remainingGuesses) {
this.word = word.toLowerCase().split("");
this.remainingGuesses = remainingGuesses;
this.guessedLetters = [];
};
Hangman.prototype.getPuzzle = function () {
let puzzle = "";
this.word.forEach((char) => {
this.guessedLetters.includes(char) || char === " "
? (puzzle = char)
: (puzzle = "*");
});
return puzzle;
};
На данный момент, как вы можете видеть из приведенного выше кода, я выполняю forEach
цикл for this.word
, а затем внутри forEach
цикла, который я использую .includes()
, чтобы определить, было ли угадано слово, если нет, то установите значение char *
равным .
На данный момент я считаю, что временная сложность из O(n2)
-за includes()
внутренней forEach
части, что было бы лучшим способом переписать getPuzzle()
функцию?
Ответ №1:
Используйте Set
for guessedLetters
для постоянного поиска по времени:
const Hangman = function (word, remainingGuesses) {
this.word = word.toLowerCase().split("");
this.remainingGuesses = remainingGuesses;
this.guessedLetters = new Set(); // this is a Set now
};
Hangman.prototype.getPuzzle = function () {
let puzzle = "";
this.word.forEach((char) => {
// use Set.has instead of Array.includes
this.guessedLetters.has(char) || char === " "
? (puzzle = char)
: (puzzle = "*");
});
return puzzle;
};
Вы можете добавить новую угаданную букву с this.guessedLetters.add(char)
помощью .
Комментарии:
1. Да, использование Set или hash — это правильный путь для более быстрого поиска (в отличие от повторяющихся линейных поисков по массиву). НО, поскольку строки неизменяемы, ваш цикл forEach ПО-ПРЕЖНЕМУ выполняет много ненужной работы; при каждом использовании ‘ =’ приходится заново создавать всю строку заново. Чтобы избежать этого, измените переменную puzzle на массив, измените «(puzzle = char)» на «puzzle.push(char)» (то же самое для «*») и верните puzzle.join(«). Это означает, что вы создаете строку только один раз.
2. Очень интересное и чистое решение с набором. Однако у меня есть один вопрос: не является ли простой объект (сопоставление ключа и значения) еще быстрее? Объект будет выглядеть примерно так: {‘a’: ‘a’, ‘b’: ‘b’ }, где ‘a’ и ‘b’ — это угаданные буквы.
3. Наборы, как правило, быстрее, чем объекты.
4. Мне стало любопытно об этом сравнении, потому что я всегда думал, что объекты быстрее. Итак, я нашел тест, который говорит, что объекты намного быстрее, чем наборы и карты. К сожалению, я не смог найти, какие операции были использованы для получения этих результатов. measurethat.net/Benchmarks/Show/5364/0/set-vs-object-vs-map