how to find the most repeat word in string? - javascript

can you please tell me how to find the most repeat word in string ?
Example
If input is this
"how do you do"
Output is "do"
var str="how do you do"
function findMostReaptedWord(str){
var res = str.split(" ");
alert(res.length);
var count;
var compareString;
for(var i=0;i<res.length ;i++){
count=0;
compareString=res[i]
for (j=0;i<res.lenth ;j++){
if(compareString==res[j]){
count++
}
}
}
}
alert(findMostReaptedWord(str))
fiddle
http://jsfiddle.net/omjg9v0q/

I gave the idea in a comment. Here it is in code :
function findMostReaptedWord(str){
var counts = {}, mr, mc;
str.match(/\w+/g).forEach(function(w){ counts[w]=(counts[w]||0)+1 });
for (var w in counts) {
if (!(counts[w]<mc)) {
mc = counts[w];
mr = w;
}
}
return mr;
}
A few details :
I use str.match(/\w+/g) for a better decomposition in words. Yours would take anything not a space as a word or part of a word.
counts is a map giving the number of occurrences of each words (i.e. counts["do"] is 2)
using a map avoids doing two levels of loop, which is very slow

Here is my approach
First, separate the words from the string using Regular Expression.
Declare an object as a Map which will help you to find the occurrences of each word. (You can use Map Data Structure!)
Find the most repeated word from that object.
let str = 'How do you do?';
console.log(findMostRepeatedWord(str)); // Result: "do"
function findMostRepeatedWord(str) {
let words = str.match(/\w+/g);
console.log(words); // [ 'How', 'do', 'you', 'do' ]
let occurances = {};
for (let word of words) {
if (occurances[word]) {
occurances[word]++;
} else {
occurances[word] = 1;
}
}
console.log(occurances); // { How: 1, do: 2, you: 1 }
let max = 0;
let mostRepeatedWord = '';
for (let word of words) {
if (occurances[word] > max) {
max = occurances[word];
mostRepeatedWord = word;
}
}
return mostRepeatedWord;
}

Here I give you an approach,
Sort the words first. That way "how do you do" becomes "do do how you".
Iterate the string to count the words that repeat, keep the maximum number of times repeating word in memory while iterating.
-
Mebin

This function may help you
function maxWord (str)
{
var max = 0;
var maxword = '';
var words = str.split(' ');
for(i=0;i<words.length;i++)
{
var count = 0;
var word = '';
for(j=0;j<words.length;j++)
{
if(j !== i && words[i] === words[j])
{
count++;
word = words[i];
}
}
if(count>maxword)
{
max = count;
maxword = word;
}
}
return maxword;
}
maxWord('how do you do'); // returns do

Related

How to find the longest sequence of "broken" characters using Regex in JS?

I'm trying to find the longest sequence of "broken"(different from letter, digit, space) characters in this sentence:
'Tempera####&&#^ na ##$ata 23 grad#%&.'
I really want to do it using Regex, but I'm not that familiar with the usage of Regex in JS. This is the description of the problem: https://pastebin.com/U6Uukc4b
I watched a lot of tutorials, also read bunch of articles and this is what I came up with:
let input = [
'Tempera####&&#^ na ##$ata 23 grad#%&.'
];
let print = this.print || console.log;
let gets = this.gets || ((arr, index) => () => arr[index++])(input, 0);
let message = gets();
//different from letter, digit, space
let counter = 1;
let allWords = /[a-z1-9\s]/gi;
for (let i = 0; i < message.length; i++) {
let current = message[i];
// allWords.lastIndex = 0;
let isExisting = allWords.test(current);
if (current === '.') {
break;
}
if (isExisting) {
counter = 1;
} else {
counter++;
}
}
print(counter)
Here the answer should be 8 , because we have 8 consecutive symbols inside the word "Tempera####&&#^" , which are not letter, digit or space.
Unfortunately this doesn't work. I'm still trying to understand where is my mistake, so I'll be very thankful if someone can "show me the way".
Use a regular expression that matches the opposite ([^.....]) and as many times as possible (+). Then check the size of all matches and pick the longest length. As there is a special role for the point (which apparently is always at the end), consider it as not broken.
let allWords = /[^a-z1-9\s.]+/gi;
let input = [
'Tempera####&&#^ na ##$ata 23 grad#%&.'
];
for (let message of input) {
let results = message.match(allWords) ?? [];
let counter = Math.max(0, ...results.map(({length}) => length));
console.log("longest", counter);
}
const input = 'Tempera####&&#^ na ##$ata 23 grad#%&.';
function findLongestSubstring(input) {
let longest = '';
let current = '';
for (let i = 0; i < input.length; i++) {
if (input[i].match(/[^a-zA-Z\d\s]/)) {
current += input[i];
} else {
if (current.length > longest.length) {
longest = current;
}
current = '';
}
}
return longest.length;
}
console.log(findLongestSubstring(input));

counting the same letters in a string but not in all lenght

I'm starting my adventure with javascript and i got one of first tasks.
I must create function that count letter that most occur in string and write this in console.
For example:
var string = "assssssadaaaAAAasadaaab";
and in console.log should be (7,a) <---
the longest string is 7 consecutive identical characters (yes, before count i use .toLowerCase();, because the task requires it)
So far I have it and I don't know what to do next.
Someone want to help?
var string = "assssssadaaaAAAasadaaab";
var string = string.toLowerCase();
function writeInConsole(){
console.log(string);
var count = (string.match(/a/g) || []).length;
console.log(count);
}
writeInConsole();
One option could be matching all consecutive characters using (.)\1* and sort the result by character length.
Then return an array with the length of the string and the character.
Note that this will take the first longest occurrence in case of multiple characters with the same length.
function writeInConsole(s) {
var m = s.match(/(.)\1*/g);
if (m) {
var res = m.reduce(function(a, b) {
return b.length > a.length ? b : a;
})
return [res.length, res.charAt(0)];
}
return [];
}
["assssssadaaaAAAasadaaab", "a", ""].forEach(s => {
s = s.toLowerCase();
console.log(writeInConsole(s))
});
Another example when you have multiple consecutive characters with the same length
function writeInConsole(s) {
let m = s.match(/(.)\1*/g);
if (m) {
let sorted = m.sort((a, b) => b.length - a.length)
let maxLength = sorted[0].length;
let result = [];
for (let i = 0; i < sorted.length; i++) {
if (sorted[i].length === maxLength) {
result.push([maxLength, sorted[i].charAt(0)]);
continue;
}
break;
}
return result;
}
return [];
}
[
"assssssadaaaAAAasadaaab",
"aaabccc",
"abc",
"yyzzz",
"aa",
""
].forEach(s => {
s = s.toLowerCase();
console.log(writeInConsole(s))
});
I'm no sure if this works for you:
string source = "/once/upon/a/time/";
int count = 0;
foreach (char c in source)
if (c == '/') count++;
The answer given by using regular expressions is more succinct, but since you say you are just starting out with programming, I will offer a verbose one that might be easier to follow.
var string = "assssssadaaaAAAasadaaab";
var string = string.toLowerCase();
function computeLongestRun(s) {
// we set up for the computation at the first character in the string
var longestRunLetter = currentLetter = string[0]
var longestRunLength = currentRunLength = 1
// loop through the string considering one character at a time
for (i = 1; i < s.length; i++) {
if (s[i] == currentLetter) { // is this letter the same as the last one?
currentRunLength++ // if yes, reflect that
} else { // otherwise, check if the current run
// is the longest
if (currentRunLength > longestRunLength) {
longestRunLetter = currentLetter
longestRunLength = currentRunLength
}
// reset to start counting a new run
currentRunLength = 1
currentLetter = s[i]
}
}
return [longestRunLetter, longestRunLength]
}
console.log(computeLongestRun(string))

JavaScript - Function that Splits String into Words, Identifies Word With The Most Vowels - Using For Loop

I've checked some similar questions but I don't feel like the answers apply directly to what I'm looking for.
I'm trying to find the word with the most vowels in a given string. I know how to split a string into words like this:
let words = string.split(" ");
And so far I have:
function mostVowels(string) {
let vowels = ["aeiouAEIOU"];
let words = string.split(" ");
//initiate vowel count at 0
let counter = 0;
//loop through words
for (let i = 0; i < words.length; i++) {
//if there are vowels in the word, add vowels to counter
if (vowels.includes(i)) {
counter++
}
}
return counter;
}
console.log(mostVowels("I went to the park today."));
So obviously I'm pretty far from reaching a solution.
Right now this is returning 0.
There's 1 vowel in each of the first five words in that string, and there are two vowels in "today", so ultimately we want for this function to return "today" as the word with the most vowels.
At this point I'm just trying to get a vowel count for the first word in the string - it should be 1.
Then I figure I'll be able to compare the counts of the different words to determine which count is the greatest.
Define your vowels to be an array of characters, rather than an array containing a single string. Then, inside the loop over words, initialize the counter to 0, and iterate over each character in the word. If the character is included in the vowels array, increment the counter. At the end of iterating over the word, if the counter for this word is better than the best counter so far, assign the counter and the word to outer variables, indicating the best word / counter so far. At the end of the function, return the best word:
function mostVowels(string) {
let vowels = [..."aeiouAEIOU"];
let words = string.split(" ");
let bestCounter = 0;
let bestWord;
for (let i = 0; i < words.length; i++) {
const word = words[i];
//initiate vowel count at 0
let counter = 0;
for (let i = 0; i < word.length; i++) {
const char = word[i];
//if there are vowels in the word, add vowels to counter
if (vowels.includes(char)) {
counter++
}
}
// finished iterating through loop,
// now check to see if it's better than the best word so far:
if (counter > bestCounter) {
bestCounter = counter;
bestWord = word;
}
}
return bestWord;
}
console.log(mostVowels("I went to the park today."));
console.log(mostVowels("I went to the fooaeuiubar park today."));
Or, perhaps more elegantly, using array methods instead:
const vowels = [..."aeiouAEIOU"];
const getVowelCount = word => [...word].reduce((a, char) => a + Boolean(vowels.includes(char)), 0);
function mostVowels(string) {
let bestCounter = 0;
return string.split(' ')
.reduce((bestWordSoFar, thisWord) => {
const thisVowelCount = getVowelCount(thisWord);
if (thisVowelCount > bestCounter) {
bestCounter = thisVowelCount;
return thisWord;
} else {
return bestWordSoFar;
}
});
}
console.log(mostVowels("I went to the park today."));
console.log(mostVowels("I went to the fooaeuiubar park today."));
I tried to approach this through map-reduce trying to keep things pure and clean. But I had to set mostVowels in reduce, making it a bit stupid.
But here's my shot:
const handleSentence = (sentence = '') => {
const vowels = /[a|e|i|o|u]+/gi;
const words = sentence.split(' ');
let mostVowels = '';
const getVowels = (str = '') => {
try {
return str.match(vowels).join('').length
} catch (err) {
return 0;
}
};
const getMostVowels = (a, b, i) => {
if (a < b) {
mostVowels = words[i];
return b;
}
return a;
}
words.map(getVowels).reduce(getMostVowels);
return mostVowels;
}
console.log(handleSentence('this is an example string for demonstrating the function'));
console.log(handleSentence('yet another example of the effectiveness of function'));
console.log(handleSentence('gypsy rhythm'));
One alternate is to use regex
let mostVowels = (input) =>{
let max = 0;
let splited = input.split(' ')
splited.forEach((e, index) => {
let count = (e.match(/[aeiou]/gi)||[]).length
max = count > max ? index : max
})
return splited[max]
}
console.log(mostVowels("I went to the park today."));
console.log(mostVowels("I went to the fooaeuiubar park today. xyz"));
A bit shorter alternative with sorting :
const vowels = s => s.split(/[aeiou]/i).length - 1;
const mostVowels = s => s.split(/\W/).sort((a, b) => vowels(b) - vowels(a))[0];
console.log( mostVowels("I went to the park today.") );
and without sorting :
const vowels = s => s.replace(/[^aeiou]/gi, '').length;
const mostVowels = s => s.split(/\W/).reduce((a, b) => vowels(a) > vowels(b) ? a : b);
console.log( mostVowels("I went to the park today.") );

Word frequency counter on specific words using javascript

I need to count number of predetermined words (wordlist) in a text. This is what I have done so far:
function frequencies(text, wordlist){
var words = text.split(/\s/);
var freqMap = {};
words.forEach(function(w){
if (!freqMap[w] && wordlist){
freqMap[w] = 0;
}
freqMap[w] += 1;
});
return freqMap;
}
At the moment it counts all the words in given text, how do I make it count only words given in wordlist?
Check word is in given list using Array#indexOf method( or Array#includes method).
function frequencies(text, wordlist) {
var words = text.split(/\s/);
var freqMap = {};
words.forEach(function(w) {
if (wordlist && wordlist.indexOf(w) > -1) { // or wordlist.includes(w)
if (!freqMap[w]) {
freqMap[w] = 0;
}
freqMap[w] += 1;
}
});
return freqMap;
}
This example accounts for some basic punctuation in the text. It will remove said punctuation, split on spaces, then uses reduce to build the object you're wanting.
let wordlist = ['hello', 'bob', 'you', 'later'];
let text = 'hello bob, how are you doing? i hope you are doing well. see you later.';
function frequencies(text, wordlist) {
return text.replace(/(\.|\?|,)/g, '').split(' ').reduce(function(prev, curr) {
if (wordlist.includes(curr)) {
if (prev[curr])
prev[curr]++;
else
prev[curr] = 1;
}
return prev;
}, {});
}
console.log(frequencies(text, wordlist))

How can I find if ALL of string2 letters are also contained within string1 somewhere?

I am trying to compare two strings to see if ALL of one of the string's input is also within another string, regardless of order.
So far I have the following code...
What am I doing wrong?
var str1= "rkqodlw"
var str2= "world"
StringScrambler(str1, str2);
function StringScrambler(str1, str2) {
var string1= str1.split("").sort();
console.log(string1);
var string2 = str2.split("").sort();
console.log(string2);
matches = [];
for (i=0; i< string1.length; i++) {
for (j=0; j<string2.length; i++) {
while (j === i) {
matches.push(j);
console.log(matches);
var matchSort = matches.sort();
console.log(matchSort);
if (matchSort === string2) {
return true;
}else {
return false;
}
}
}
}
}
All the answers this far work fine but they will not work for words with double letters in the second string but not in the first (for eg. 'worlld' - notice the double L). The trick is to affect the first word such that it removes the found character(s) so that the same letter is not checked again. Something like this would do the trick:
// Check if the second string's characters are
// found in the first string
function StringScrambler(str1, str2) {
var arr1 = str1.split(''),
arr2 = str2.split(''),
isATrueSubset = true,
indexOfChar;
arr2.forEach(function(char) {
indexOfChar = arr1.indexOf(char);
if (indexOfChar > -1) {
// Remove the character that was found
// to avoid matching against it again
arr1.splice(indexOfChar, 1);
} else {
isATrueSubset = false;
// No need to continue
return;
}
});
console.log(isATrueSubset);
return isATrueSubset;
}
StringScrambler('rkqodlw ', 'world '); // outputs true
StringScrambler('rkqodlw ', 'worlld '); // outputs false
var one = "dlrow";
var two = "world";
var allCharsFound = true;
one.split("").map(function(char) {
if (two.indexOf(char) < 0) {
allCharsFound = false;
}
});
console.log(allCharsFound);
var str1= "rkqodlw";
var str2= "world";
function test($str1, $str2) {
var string2 = str2.split("");
for(var i=0; i<string2.length; i++) {
if (str1.indexOf(string2[i]) == -1) {
return false;
}
}
return true;
}
You can use the following code to do this task:
alert (AllFirstInSecond("world", "rkqodlw"));
alert (AllFirstInSecond("worldz", "rkqodlw"));
function AllFirstInSecond(str1, str2) {
var pos = str1.length - 1;
while (pos >= 0) {
if (str2.indexOf(str1.substr(pos--,1)) == -1) {
return false;
}
}
return true;
}
It simply checks every single character in the first string to see if it's in the second. If not, it returns false.
Only once all have been found does it return true.
There are possibilities for optimisation (every character is checked even if it's a duplicate that's already been checked) but, unless your strings are particularly large, there's probably not much absolute gain to be had.
If str2 is always a subset of str1, then this answer can be used
Compute intersection of two arrays in JavaScript
var arr1 = "rkqodlw".split("");
var arr2 = "world".split("");
var commonValues = arr2.filter(function(value) {
return arr1.indexOf(value) > -1;
});
alert(commonValues.join(""))
This will compare each words of the second string in the first one and if its present it will be added in the mathes array.
var str1= "rkqodlw";
var str2= "world2";
StringScrambler(str1, str2);
function StringScrambler(str1, str2) {
var string2 = str2.split("").sort();
console.log(string2);
matches = [];
for (j=0; j<string2.length; j++) {
if(str1.indexOf(string2[j]) > -1){
matches.push(string2[j]);
console.log(string2[j]);
}
}
console.log(matches);
}
try this:
var str1= "rkqodlw"
var str2= "world"
StringScrambler(str1, str2);
function StringScrambler(str1, str2) {
var string1 = str1.split("").sort();
var string2 = str2.split("").sort();
matches = [];
for (i = 0; i < string1.length; i++) {
if (string2.indexOf(string1[i]) > -1) matches.push(string1[i]);
}
return matches
}

Categories