Найти самое длинное слово в строке в JS, используя этот код? - PullRequest
0 голосов
/ 10 ноября 2019

Пожалуйста, дайте мне знать, что не так с этим кодом:

Я знаю, что есть гораздо более простые способы достичь желаемого результата, однако я хочу понять, как сделать этот конкретный кодбеги, а в чем мои ошибки. Попробуйте как можно меньше изменить это, иначе дайте мне знать, почему это не сработало. Также обратите внимание, что я пытаюсь console.log 3 значения, а не только одно. Спасибо.

РЕДАКТИРОВАТЬ: Вот упражнение freeCodeCamp, с которым я на самом деле тестирую, работает ли код: https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-algorithm-scripting/find-the-longest-word-in-a-string По некоторым причинам большинство ответов работают здесь, а не в freeCodeCamp. Консоль для упражнений?

function findLongestWordLength(str) {

  let arr = [];
  let longestWord = "";
  let longestNum = 0;

/*If there is a character at str[i] add it to the arr, else if there is whitespace
don't add it to the arr. Instead, find the arr.length, if is greater than the
previous overwrite longestNum, longestWord and empty the 
arr, if not just empty the arr and keep going*/

  for (let i = 0; i <= str.length - 1; i++) {
    if (/./i.test(str[i])) {
      arr.push(str[i]);
    } else if (/\s/.test(str[i])) {
      if (arr.length - 1 >= longestNum) {
        longestNum = arr.length - 1;
        longestWord = arr.join("");
        arr = [];
      } else {
        longestNum = longestNum;
        longestWord = longestWord;
        arr = [];
      }
    }
  }
  console.log(arr);
  console.log(longestWord);
  console.log(longestNum);
  return longestNum;
}

  findLongestWordLength("The quick brown fox jumped over the lazy dog");

Ответы [ 5 ]

1 голос
/ 10 ноября 2019

Вам необходимо добавлять элементы, если символ не является пробелом (/\S/ - заглавная S). Если это пробел, вам нужно сравнить длину с предыдущим longestWord.length и назначить слово для longestWord. В случае пробела вы инициализируете arr.

Примечание: назначения longestNum = longestNum; longestWord = longestWord; являются избыточными, они уже равны себе. Кроме того, longestNum также является избыточным, поскольку он является производным от longestWord (longestWord.length).

function findLongestWordLength(str) {
  let arr = [];
  let longestWord = "";

  for (let i = 0; i < str.length; i++) {
    if (/\S/.test(str[i])) { // as long as it's not a space
      arr.push(str[i]);
    } else {
      if (arr.length > longestWord.length) {
        longestWord = arr.join("");
      }

      arr = [];
    }
  }

  return longestWord.length;
}

var result = findLongestWordLength("The quick brown fox jumped over the lazy dog");

console.log(result);
1 голос
/ 10 ноября 2019

С наименьшими изменениями вам необходимо внести следующие изменения:

  • Убедитесь, что длина слова last также проверена. В настоящее время это не так. Для этого вы можете просто добавить пробел во входную строку перед выполнением цикла.
  • Измените тест /./i, так как он будет соответствовать чему угодно , кроме разрыва строки. Вы захотите проверить буквы и, возможно, также цифры и, возможно, подчеркивание, но не пунктуацию. Так что /\w/ будет улучшением. Вы можете думать о еще лучших регулярных выражениях. Браузеры постепенно получают поддержку для /\p{L}/u, что соответствует буквам в любом алфавите.
  • Тест в else должен быть удален, поскольку вы просто хотите иметь дело с любым другим случаем здесь, безусловно. Например, запятая также будет разделять слово, и после нее не должно быть пробела до начала следующего слова.
  • Не вычитайте единицу из длины массива: в ней действительно есть символы слова(только), так что вам нужна полная длина.

Это минимальные изменения, чтобы исправить это:

function findLongestWordLength(str) {

  let arr = [];
  let longestWord = "";
  let longestNum = 0;

  str += " "; // trick to ensure that the last word is also inspected

  for (let i = 0; i <= str.length - 1; i++) {
    if (/\w/i.test(str[i])) { // match alphanumerical character, not anything. 
                              // The `i` suffix doesn't harm, but is useless here
      arr.push(str[i]);
    } else { // Remove any condition here.
      if (arr.length >= longestNum) { // you need the full length, not minus 1
        longestNum = arr.length;      // (idem)
        longestWord = arr.join("");
        arr = [];
      } else {
        longestNum = longestNum; // not needed
        longestWord = longestWord; // not needed
        arr = [];
      }
    }
    //console.log(arr);
    //console.log(longestWord);
    //console.log(longestNum);
  }
  return longestNum;
}
console.log(
  findLongestWordLength("The quick brown fox jumped over the lazy dog")
)

Как вы знаете, есть более короткие способы сделать это, например, с помощью этого функционального программирования решение:

function findLongestWordLength(str) {
    return Math.max(...str.match(/\w+|$/g).map(s => s.length));
}

console.log(findLongestWordLength("The quick brown fox jumped over the lazy dog"));
1 голос
/ 10 ноября 2019

Я предполагаю, что с /./i.test(str[i]) вы пытаетесь сопоставить все, кроме пробелов. . соответствует всему, кроме символов новой строки, поэтому я переключил его на [^\s], который фактически соответствует всем, кроме пробелов. Я также взял журналы консоли вне цикла, чтобы вывод был несколько читабельным.

function findLongestWordLength(str) {

  let arr = [];
  let longestWord = "";
  let longestNum = 0;

  for (let i = 0; i <= str.length - 1; i++) {
    if (/[^\s]/i.test(str[i])) {
      arr.push(str[i]);
    } else if (/[\s]/i.test(str[i])) {
      if (arr.length > longestNum) {
        longestNum = arr.length;
        longestWord = arr.join("");
        arr = [];
      } else {
        longestNum = longestNum;
        longestWord = longestWord;
        arr = [];
      }
    }

  }
  console.log(arr); // last word since you reset arr every step
  console.log(longestWord);
  console.log(longestNum);
  return longestNum;
}

findLongestWordLength("The quick brown fox jumped over the lazy dog");

Лучший способ сделать это будет:

function findLongestWordLength(sentence) {
  const words = sentence.split(' ');
  return words.reduce((max, currentWord) => max > currentWord.length ? max : currentWord.length, 0);
}
0 голосов
/ 10 ноября 2019

Я бы сослался на приведенные выше отличные ответы для реструктуризации и избыточности, но также добавил бы (поскольку OP хочет объяснений), что большинство, если не все используемые здесь методы регулярного выражения / разбиения, будут либо толкать слова и включать в себя начальную / конечную пунктуацию,или ошибочно разделить слова.

Использование \w разделяет на дефисы и одинарные кавычки, что может привести к вводящим в заблуждение результатам, в зависимости от того, что вам нужно.

Например, "привет ...?"имеет большую длину, чем «самая длинная», считая все знаки препинания. Также «Вы» - это одно слово, а не два, поэтому проблематично разделять пробелами или полагаться только на \w.

При разбиении текстового содержимого на слова следует (если обработка текста, я думаю, этодомашнее задание) не только полагаться на пробелы. Я использую это регулярное выражение в текущем, еще не опубликованном проекте: /[\s.,:;!?_<>{}()[\]"`´^$°§½¼³%&¬+=*~#|/\\]/

Вышеупомянутое регулярное выражение допускает дефисные слова, которые, хотя технически несколько слов объединены, часто читаются / обрабатываются как одно слово, то есть когдасоздать существительное janky-type-compund-noun, как я только что это сделал.

Наконец, язык имеет значение. Разделение текстового содержимого с помощью приведенного выше регулярного выражения работает очень хорошо для английского языка и не разделяет слова по одинарным кавычкам, потому что тогда мы будем разделять «ты лжец!»в ["you", "re", "a", "liar"], так что вам все равно придется очистить результирующий массив слов от окружающих одинарных кавычек (опять же, они могут быть множественными, возможно, пользователь написал «Добрый вечер!») по ошибке).

Резюме: фундаментальная часть выполнения NLP (обработка на естественном языке) почти всегда должна включать в себя этап «очистки текста» и полагаться на пробел или встроенный специальный символ \w, даже при обработке текста на английском языке, не будетотрежь.

0 голосов
/ 10 ноября 2019

Вы можете пропустить условие else if(..), если в первом тесте используете немного другое регулярное выражение: /\w/, ища любой символ, который может встречаться в слове.

function findLongestWordLength(str) {
  let arr = [], longestWord = "", longestNum = 0;

  for (let i = 0; i <= str.length - 1; i++) {
    if (/\w/.test(str[i])) {
      arr.push(str[i]);
    } else {
      if (arr.length - 1 >= longestNum) {
        longestNum = arr.length - 1;
        longestWord = arr.join("");
        arr = [];
      } else {
        longestNum = longestNum;
        longestWord = longestWord;
        arr = [];
      }
    }
  }
  console.log(arr);
  console.log(longestWord);
  console.log(longestNum);
  return longestNum;
}
var str="The quick brown fox jumped over the lazy dog";
  findLongestWordLength(str);

// alternatively you could simply do:
console.log(str.split(/\s/).sort((a,b)=>b.length-a.length)[0])
  

Содержимое arr, конечно, будет последним проверенным словом, в данном случае «собака». Есть две строки длиной 5, найдена только первая.

Как вы можете видеть в моем фрагменте, более короткий способ сделать это будет:

var longestWord=str.split(/\s/).sort((a,b)=>b.length-a.length)[0]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...