Найдите слово с наибольшим количеством очков в строке в соответствии с его положением в алфавите, используя JavaScript - PullRequest
1 голос
/ 31 марта 2020

Я пытаюсь решить задачи CodeWars, но у меня есть проблема с этим:

"При заданной строке слов вам нужно найти слово с наибольшим количеством очков. Каждая буква слова набирает очки в соответствии с его позиция в алфавите:

 a = 1, b = 2, c = 3 etc.

Вам нужно вернуть слово с наибольшим количеством очков в виде строки. Если два слова имеют одинаковый результат, вернуть слово, которое появляется раньше в исходной строке. Все буквы будут строчными и все входные данные будут действительными. "

Мой код прошел 104 случая, но ошибся в 1 случае. Неправильный ответ теста:

'what time are we climbing up the volcano' 

В соответствии с кодовыми войнами - Ожидается: «вулкан», вместо этого получено: «восхождение»

Есть идеи?

ссылка на проблему - https://www.codewars.com/kata/57eb8fcdf670e99d9b000272/train/javascript

 function high(x){
  let result = '', value =0, counterValue = 0; 

  let splittedArray = x.split(' ');

  splittedArray.map(splitItem => {
    counterValue = 0;

    let splitItemArray = splitItem.split('');

    splitItemArray.map(splitChar => { 
      counterValue += splitChar.charCodeAt();
    })

    if(counterValue>value){
      result = splitItem;
      value = counterValue;
    }
  });
  return result;
}

Ответы [ 7 ]

1 голос
/ 31 марта 2020

решение состоит в том, чтобы использовать массив алфавита и индексировать положение символа в нем,

let al = `abcdefghijklmnopqrstuvwxyz`.split('')


   function high(x){
     let words = x.split(" ");
     let out = words.map(word => {
     let score = 0;
     let letters = word.split("");
     letters.map(c => {
      score += al.indexOf(c);
     })
     return [word, score];
    });

    out = out.sort((a,b) => { 
      if(a[1] > b[1]) return -1;
      else if(a[1] < b[1]) return 1; 
      else return 0;  });

return out[0][0];
}
1 голос
/ 31 марта 2020

Вы можете использовать «уменьшить» и «объект», чтобы отслеживать наибольшее количество и соответствующее слово.

function high(x){
  let mapper = [...`abcdefghijklmnopqurstuvwxyz`].reduce((op,inp,index)=>{
    op[inp] = index+1
    return op
  },{})
  return x.split(' ').reduce((op,inp)=>{
    let currentCount = 0;
    [...inp].forEach(v=>{
      currentCount += mapper[v]
    })
    if(currentCount > op.maxCount){
      op.maxCount = currentCount
      op.word = inp
    }
    return op
  }, {maxCount:0, word:''}).word
}

console.log(high('what time are we climbing up the volcano'), 'volcano'))
0 голосов
/ 31 марта 2020

Я допустил ошибку, не считая буквы в алфавите. Если я вычту 96 из значения ASCII, тогда он вычислит a as 1, b as 2......

Таким образом, решение дано ниже

 function high(x){
  let result = '', value =0, counterValue = 0; 

  let splittedArray = x.split(' ');

  splittedArray.map(splitItem => {
    counterValue = 0;

    let splitItemArray = splitItem.split('');

    splitItemArray.map(splitChar => { 
      counterValue += splitChar.charCodeAt()-96; // if I subtract 96 then it will calculate a as 1, b as 2......
    })

    if(counterValue>value){
      result = splitItem;
      value = counterValue;
    }
  });
  return result;
}
0 голосов
/ 31 марта 2020

Метод charCodeAt () возвращает целое число от 0 до 65535, представляющее кодовую единицу UTF-16 с заданным индексом.

В основном вам необходимо преобразовать его в прописные буквы алфавита и вычтите значение charCodeAt на 64, что даст вам положение строки в алфавите.

Проверьте это:

function high(x) {
    let splittedArray = x.split(' ');
    let splitChar = splittedArray.map(el => el.split(''));
    let charValue = splitChar.map(el => {
        let counter = 0;
        el.map(element => counter += element.toUpperCase().charCodeAt() - 64);
        return counter;
    });
    let largest = 0;
    let largestIndex;
    for (let i = 0; i < charValue.length; i++) {
        if (charValue[i] > largest) {
            largest = charValue[i];
            largestIndex = i;
        }
    }
    return splittedArray[largestIndex];
}
0 голосов
/ 31 марта 2020

Идея:

  • Сохранение значений оценки в таблице для удобного поиска
  • разбиение предложений на слова без буквенных символов c символов
  • получите оценку каждого слова, сначала вычислив оценки отдельных персонажей, а затем суммируя их вместе (используя уменьшение).
  • Не забудьте отсортировать по исходной позиции, если оценки совпадают, сделать это с помощью отслеживание исходной позиции.

Демо: https://jsfiddle.net/9xkfqh1m/

const ScoreTable = {
  "a": 1,
  "b": 2,
  "c": 3,
  "d": 4,
  "e": 5,
  "f": 6,
  "g": 7,
  "h": 8,
  "i": 9,
  "j": 10,
  "k": 11,
  "l": 12,
  "m": 13,
  "n": 14,
  "o": 15,
  "p": 16,
  "q": 17,
  "r": 18,
  "s": 19,
  "t": 20,
  "u": 21,
  "v": 22,
  "w": 23,
  "x": 24,
  "y": 25,
  "z": 26
};

// non-ascii letters = 0
function CharScore(char) {
  const lowerCaseChar = char.toLowerCase();
  return lowerCaseChar in ScoreTable ? ScoreTable[lowerCaseChar] : 0;
}

function WordScore(word) {
  return word.split("").reduce((score, char) => {
    return score + CharScore(char);
  }, 0);
}

function SplitOnNonAlphabeticCharacters(str) {
  return str.split(/[^a-zA-Z]+/gm);
}

function high(str){
  const scoreObjects = SplitOnNonAlphabeticCharacters(str)        // split into words
  .map((word, index) => {                                         // map our words into an object with its score and original position
    return {
      text: word,
      score: WordScore(word),
      originalPosition: index
    };
  }).sort((word1, word2) => {                                        // sort
    return word2.score - word1.score                                 // highest score first
                ||  word1.originalPosition - word2.originalPosition; // if score same, earliest original position in string
  });

  return scoreObjects.length > 0 ? scoreObjects[0].text : null;   // return word by the highest score (or earliest original position), or null
}

0 голосов
/ 31 марта 2020

Я смущен вашей counterValue += splitChar.charCodeAt(); строкой. Я не понимаю, как splitChar.charCodeAt() переводит в 1-26, иначе говоря, положение букв в алфавите. «Каждая буква слова набирает очки в соответствии с его положением в алфавите»

Я смог заставить ваш код работать, выполнив две вещи:

  1. Добавить карту в сохранить значение каждой буквы в алфавите. Я уверен, что это можно сделать разными способами, но это был мой подход:
let letterValues = { a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7, h: 8, i: 9, j: 10, k: 11, l: 12, m: 13, n: 14, o: 15, p: 16, q: 17, r: 18, s: 19, t: 20, u: 21, v: 22, w: 23, x: 24, y: 25, z: 26 };
А затем используйте это в counterValue += splitChar.charCodeAt(); как counterValue += letterValues[letter];
0 голосов
/ 31 марта 2020
function high(x) {
  const words = x.split(' ');
  const alphabetMap = {};
  for (let i='a'.charCodeAt(), j = 1; i <= 'z'.charCodeAt(); i++, j++) {
    alphabetMap[i] = j;
  }
  let highestScoringWord = { word: '', score: 0 };
  words.forEach(w => {
    const chars = w.split('');
    const sumOfChars = chars.reduce((count, char) => count + alphabetMap[char.charCodeAt()], 0);
    if (sumOfChars > highestScoringWord.score) {
      highestScoringWord = { word: w, score: sumOfChars };
    }
  });

  return highestScoringWord.word;
}

console.log(high('what time are we climbing up the volcano')) // volcano ;)
...