最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Find the highest scoring word from a string according to its position in the alphabet using JavaScript - Stack Overflow

programmeradmin5浏览0评论

I am trying to solve CodeWars challenges but I have a problem with this one:

"Given a string of words, you need to find the highest scoring word. Each letter of a word scores points according to its position in the alphabet:

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

You need to return the highest scoring word as a string. If two words score the same, return the word that appears earliest in the original string. All letters will be lowercase and all inputs will be valid."

My code passed 104 cases but got wrong on 1 case. The wrong answer test case is

'what time are we climbing up the volcano' 

According to codewars - Expected: 'volcano', instead got: 'climbing'

Any ideas?

link of the problem -

 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;
}

I am trying to solve CodeWars challenges but I have a problem with this one:

"Given a string of words, you need to find the highest scoring word. Each letter of a word scores points according to its position in the alphabet:

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

You need to return the highest scoring word as a string. If two words score the same, return the word that appears earliest in the original string. All letters will be lowercase and all inputs will be valid."

My code passed 104 cases but got wrong on 1 case. The wrong answer test case is

'what time are we climbing up the volcano' 

According to codewars - Expected: 'volcano', instead got: 'climbing'

Any ideas?

link of the problem - https://www.codewars./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;
}
Share Improve this question edited Mar 31, 2020 at 18:21 Michael Nelles 6,0328 gold badges47 silver badges61 bronze badges asked Mar 31, 2020 at 17:42 Mustafizur Rahman ChoudhuryMustafizur Rahman Choudhury 131 silver badge5 bronze badges 3
  • 1 Your issue is your using charCodeAt which gives it's ascii value not in 1... format you want – Code Maniac Commented Mar 31, 2020 at 17:57
  • use an array storing all the alphabets and use indexOf, the error is due to charCodeAt – Adarsh Hegde Commented Mar 31, 2020 at 18:10
  • welp, there you go, 4 answers and 4 different ways to translate the alphabet into numbers! – Jason Lydon Commented Mar 31, 2020 at 18:19
Add a ment  | 

10 Answers 10

Reset to default 1
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 ;)

You can use reduce and object to keep track of highest count and respective word

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'))

the solution is to use an array of the alphabet and indexing the character position in it,

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];
}

I'm confused by your counterValue += splitChar.charCodeAt(); line. I don't understand how splitChar.charCodeAt() translates into 1-26 aka a letters position in the alphabet. "Each letter of a word scores points according to its position in the alphabet"

I was able to able to make your code work by doing two things:

  1. Add a map to store the value of each letter in the alphabet. I'm sure this can be done many ways but this was my approach:
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 };
  1. And then use this in counterValue += splitChar.charCodeAt(); as counterValue += letterValues[letter];

Idea:

  • Store the score values in a table for easy lookup
  • split sentences into words by non-alphabetic characters
  • get each word's score by first calculating the individual characters' scores and then summing them together (using reduce).
  • Don't forget to sort by original position if scores are the same, do it by keeping track of the original position.

Demo: https://jsfiddle/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
}

The charCodeAt() method returns an integer between 0 and 65535 representing the UTF-16 code unit at the given index.

Basically you need to convert it to an uppercase alphabet and subtract the value of the charCodeAt by 64 which will give you the position of the string in the alphabet.

Check this one out:

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];
}

I made a mistake by not counting letters position in the alphabet. If I subtract 96 from ASCII value then it will calculate a as 1, b as 2......

So the solution is given below

 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;
}
function high(x){
const str = x.split(' ');
const result1 = [];
const result = str.reduce((_, dig) => {
  let c = 0;
  for (let j = 0; j < dig.length; j++) {
    c = c + (dig.charCodeAt(j) - 96);
  }
  result1.push(c);
}, 0);
return str[result1.indexOf(result1.slice().sort((a, b) => b - a)[0])];
}

Thought I'd post since I solved it, even though the post is pretty old. Anyway this was solved from pure javascript.

//This main function loops thru each sum from the helper function and returns the position of the highest scoring word

function highestScoringWord(sentence) {
let arr = []
let sentenceSplit = sentence.split(' ')
for(i=0; i<sentenceSplit.length; i++) {
arr.push(scoringWord(sentenceSplit[i]))
}
let max = arr[0]
for(x=0; x<arr.length; x++) {
    if(arr[x] > max) {
        max = arr[x]
    }   
}

for(p=0; p<arr.length; p++) {
    if(max === arr[p]) {
        return sentenceSplit[p]
    }
}

}

//Helper function that takes a word, splits it, and sums up the numbers that each letter is worth.

function scoringWord(word) {
 let wordSplit = word.split('')
 let alphabet = 'abcdefghijklmnopqrstuvwxyz'
 let sum = 0
 for(j=0; j<word.length; j++) {
     sum+=alphabet.indexOf(word[j])
 }
 return sum
}

function high(x){ const ScoreTable = ["0", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k","l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w","x", "y", "z"];

return x.split(" ").map(word => {
    let code = 0
    word.split("").map(letter => code += ScoreTable.indexOf(letter))
    return [word, code]
}).sort((a,b) => b[1] - a[1])[0][0]

}

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论