counting specific number of characters in a string - javascript

I'm trying to count the number of specific characters in a string, but am getting "0" instead of the correct output. I know there are easier ways to get the solution, but I want to know how to do it this way and what I'm doing wrong.
function countCharacter(str, char) {
var count = 0;
for(var i = 0; i < str.length; i++){
if(str.charAt(i) === char){
count++;
}
return count;
}
}
countCharacter("My cat is driving my crazy", "a");

Youre returning in the for loop, so the forloop just iterates once:
function countCharacter(str, char) {
var count = 0;
for(var i = 0; i < str.length; i++){
if(str.charAt(i) === char){
count++;
}
}
return count;
}
countCharacter("My cat is driving my crazy", "a");
By the way, shorter:
countCharacter=(str,char)=>str.split("").reduce((count,letter)=>letter===char?count+1:count,0);

Return count should be in a place out of the loop

You can try split and filter. The length of the resulting Array is the number of found characters:
const aFound = "My cat is driving my crazy"
.split("") // split per character
.filter( chr => chr === "a" ); // filter on character 'a'
const numberOfz = findCharacterInString("I'm driving my cat crazy", "z");
document.querySelector("pre").textContent = `
There is/are ${aFound.length} a('s) in "My cat is driving my crazy"
There is/are ${numberOfz} z('s) in "I'm driving my cat crazy"`;
// As method (case insensitive)
function findCharacterInString(string2Search, character) {
return string2Search
.split("")
.filter( chr => chr.toLowerCase() === character.toLowerCase() )
.length;
}
<pre></pre>

You accidentally put your return statement inside your for loop, so it returns after the first time it runs through the loop. Fixed below:
function countCharacter(str, char) {
var count = 0;
for(var i = 0; i < str.length; i++){
if(str.charAt(i) === char){
count++;
}
}
return count;
}
countCharacter("My cat is driving my crazy", "a");

Related

Why do i get nothing back when i add more than one char to the end of this string?

I am trying to get a list of consonants. However with this code, I get nothing back when i have a string longer then 1.
I have tried toString and concat, converting to an array
function solve(s) {
let subStrList = [];
let tm = "";
for(let i = 0; i < s.length; i++){
if(!"aeiou".includes(s[i])){
tm += s[i];
}else{
subStrList.push(tm);
tm = "";
}
}// For End
return subStrList;
}
OUTPUT: [ 'z', 'd', '' ]
You're using tm as an accumulator to collect a sequence of consonants, then adding the the collected consonants to the result array and resetting the accumulator once you find a vowel. One problem with this kind of algorithm is you have to handle the case where the end of the string is a consonant and now you have add whatever is in the accumulator (tm) to the list. For example:
function solve(s) {
let subStrList = [];
let tm = "";
for (let i = 0; i < s.length; i++) {
if (!"aeiou".includes(s[i])) {
tm += s[i];
} else {
subStrList.push(tm);
tm = "";
}
} // For End
if (tm !== "") {
subStrList.push(tm);
}
return subStrList;
}
console.log(solve("zadacs"));
Note however, a much cleaner solution to this would be a simple regex:
function solve(s) {
return s.split(/[aeiou]/g);
}
console.log(solve("zadacs"));
Note: You can also use s.split(...).filter(Boolean) to remove empty substrings, if that's a requirement.
This comes because you do not add the last collection of consonants at the end.
Try this:
function solve(s) {
let subStrList = [];
let tm = "";
for(let i = 0; i < s.length; i++){
if(!"aeiou".includes(s[i])){
tm += s[i];
}else{
subStrList.push(tm);
tm = "";
}
}// For End
subStrList.push(tm);
return subStrList;
}
Well it's because you only add to the array if there is a following consonant. So just after your function is finished you have:
s: "zodacs"
subStrList: (2) ["z", "d"]
tm: "cs"
You can you add a check just before the return:
...
if(tm.length > 0) {
subStrList.push(tm);
tm = "";
}
return subStrList;
This is my solution, i had missed two cases. 1. What happens when the last letter is not a vowel and 2. what happens when the first letter is not a vowel.
I am aware this isn't the cleanest code but its the solution i could come up with. Thank you for all of your help.
function solve(s) {
let subStrList = [];
let subStr = "";
for (let i = 0; i < s.length; i++) {
if (!"aeiou".includes(s[i])) {
subStr += s[i];
}
else if(subStr !== ""){
subStrList.push(subStr);
subStr = "";}
} // FOR END
if (subStr.length > 0) {
subStrList.push(subStr);
}
return subStrList;
}

Find substring in string without includes/indexOf/Regex in Javascript

I'd like to figure out if a substring is within a string without using the Javascript built in methods of includes, indexOf, (any similar to those), or regular expressions. Basically just looking to learn an algorithm approach.
This is what I have so far
function isSubstring(string, substring){
substringIndex = 0;
// loop through string
for(let i = 0; i< string.length; i++){
//check the current substring index if it matches
if(string[i] === substring[substringIndex]){
substringIndex++
//continue searching... Would i then have to call another function recursively?
}
}
}
I'm having trouble understanding how to build the algorithm. Once it finds that first character that matches, I would just go to the next one and if it matches continue to the next index of the string? Would I then need a recursive function that is separate from the looping I am currently doing? I'm trying to get better at algorithmic thinking. Thanks.
Many approaches are possible. Here is one: Create a simpler function which will check if a first string is at concrete specified position, let's call it start, in a second string. It is quite simple: You compare first[i] with second[start+i] for all i in range 0 to length of first - 1.
Then the second step will be to repeat this function for all start positions from 0 to length of second string, while checking the boundaries (you cannot read after end of a string).
You can also do some optimizations later, when the first version will work. :-)
Here is an optimized example of the algorythm isSubstring. It iterates only through the minimum number of characters required.
For example, if the string is 20 characters long and the substring is only 5 characters long, when we get to the 16th position of the string we can assume that the substring doesn't exist within the string (16 + 5 = 21 > 20)
function isSubstring(str, sub){
if(sub.length > str.length) return false;
for(let i = 0; i < str.length - sub.length + 1; i++){
if(str[i] !== sub[0]) continue;
let exists = true;
for(let j = 1; j < sub.length && exists; j++){
if(str[i+j] === sub[j]) continue;
exists = false;
}
if(exists) return true;
}
return false;
}
//expected true
console.log(isSubstring("hello world", "hello"));
console.log(isSubstring("hello world", "world"));
console.log(isSubstring("hello world", "d"));
console.log(isSubstring("hello world", "o w"));
console.log(isSubstring("hello world", "rl"));
console.log(isSubstring("hello world", ""));
//expected false
console.log(isSubstring("hello world", "hello world 1"));
console.log(isSubstring("hello world", "helloo"));
On each iteration over the length of the haystack, use slice to extract the characters from that index to (the index plus the length of the needle). If the sliced string matches the needle, return true:
function isSubstring(string, substring) {
for (let i = 0; i < string.length; i++) {
const sliced = string.slice(i, i + substring.length);
if (sliced === substring) {
return true;
}
}
return false;
}
console.log(isSubstring('foobar', 'oob'));
console.log(isSubstring('foobar', 'baz'));
Since you expressed interest in a recursive method, here's something to consider. Clicking on the yellow markdown parts reveal the spoilers.
function f(str, sub, i=0, j=0){
if (j && j == sub.length)
return true;
if (i == str.length)
return false;
if (str[i] == sub[j])
return f(str, sub,
i+1, j+1);
return f(str, sub,
i+1, 0);
}
function isSubstring(str, sub) {
return str.split(sub).length > 1
}
No includes, no .indexOf, no RegExp. Just strings.
using only one loop pseudo code :
const containSubstr = (str, substr) => {
let count = 0;
let i = 0;
let startIndex = 0;
while (i < str.length) {
if (substr[count] === str[i]) {
if (count === substr.length - 1) {
return true;
}
count++;
} else {
count = 0;
i = startIndex;
startIndex++;
}
i++;
}
return false;
};
console.log(containSubstr("ababad", "abad"));

How to find characters in a string in JavaScript?

I am doing JavaScript courses and got stuck at this question.
Define a function named countLetters that receives two parameters:
1) sentence - type: string
2) character - type: string
The function should return a count of every character present in sentence.
HINT: You can access a single character in a string just like accessing an element in an array - myString[3] would access the third character
Here is what I have done so far.
function countLetters(sentence, character) {
for(let i=0; i <= sentence.length; i++) {
let count = character[i];
return sentence.match(count).length;
}
}
Thank you!
function countLetters(sentence, character) {
var count = 0;
for(let i=0; i <= sentence.length; i++) {
if(character == sentence[i]){
count++;
}
}
return count;
}
console.log(countLetters("The quick brown fox jumps over the lazy dog","o"));
You can access a single character in a string just like accessing an element in an array
It means you can use access each character of string like "sentence[i]" and then compare with the desired character like character == sentence[i].
The algorithm is simple. Maintain a local variable to count the number of occurrences of a letter. As you loop through each character in the sentence, if it matches character, increment the counter. Lastly, return the value of the counter
function countLetters(sentence, character) {
let count = 0;
for (let i = 0; i < sentence.length; i++) {
if (sentence[i] === character) {
count++;
}
}
return count;
}
console.log(countLetters('apple', 'p')); // 2
console.log(countLetters('watermelon', 'e')); // 2
console.log(countLetters('mississippi', 's')); // 4
Here's a one-liner just for fun:
function countLetters(sentence, character) {
return sentence.split('').reduce((acc, char) => acc + Number(char === character), 0);
}
console.log(countLetters('apple', 'p')); // 2
console.log(countLetters('watermelon', 'e')); // 2
console.log(countLetters('mississippi', 's')); // 4
Traverse through the sentence and increase the counter if the character is found
function countLetters(sentence, character) {
var count = 0
for(let i=0; i < sentence.length; i++) {
if (sentence.charAt(i) === character)
counter++;
}
return counter
}
Considering that only one character needed to be checked for count in a string.
This code can help.
var mstring = My name is jhone doe;
var mchar = o;
function countLetters(string, char){
var count = 0;
if(string[i] == char){
count++;
}
return count;
}
console.log(countLetters(mstring, mchar));
It will output 2. As o appears 2 times in the given string.

Whats wrong with my palindrome? (javascript)

I have written this js code for palindrome, I know there are better and more efficient palindrome methods online but I want to know why I am unable to get my palindrome function to work properly?
CODE:
var pal = function(str) {
var len = str.length;
for (var i = 0; i < len; i++) {
var comp1 = str.substring(i, i + 1);
for (var j = len; j > 0; j--) {
var comp2 = str.substring(j - 1, j);
}
if (comp1 != comp2) {
console.log("not palindrome")
break;
} else {
console.log('palindrome')
}
}
}
pal('maddog');
OUTPUT :
palindrome
not palindrome
There are lot of better algorithms to check Palindrome. Let use the similar algorithm that you are using.
We basically use two pointers - left and right, and move to middle at the same time. In the original question, left pointer and right pointer doesn't move at the same time.
Pointers should move like this -
a b c b a
^ ^
a b c b a
^ ^
a b c b a
^
var isPalindrome = function (str) {
for (var i = 0, j = str.length-1; i < j; i++ , j--) {
if (str[i] != str[j]) {
return false;
}
}
return true;
}
console.log('maddog : ' + isPalindrome('maddog'));
console.log('abcba : ' + isPalindrome('abcba'));
console.log('deed : ' + isPalindrome('deed'));
console.log('a : ' + isPalindrome('a'));
Try the following code. It works by dividing the string length by 2, and then iterating up, checking mirroring characters against each other:
var pal = function(str){
var len = str.length;
for(var i = 0; i < Math.floor(len/2); i++){
if(str[i] != str[(len-1)-i]){
return false;
}
}
return true;
}
console.log(pal("bunny"));
console.log(pal("amoreroma"));
The inner loop is totally unnecessary. It does the same thing every time -- it loops through the whole string, starting from the end, repeatedly setting comp2 to the character; when it's done, comp2 always contains the first character. So your function just tests whether every character in the string is the same as the first character.
To test if something is a palindrome, you need to compare each character with the corresponding character from the other end of the string. You don't need two loops for this. You also only need to loop through the first half of the string, not the whole string.
Finally, you should only echo Palindrome at the end of the loop. Inside the loop you only know that one character matches, not all of them.
var pal = function(str) {
var len = str.length;
var half = Math.floor(len / 2);
var isPal = true;
for (var i = 0; i < half; i++) {
var comp1 = str[i];
var comp2 = str[len - i - 1];
if (comp1 != comp2) {
console.log("not palindrome")
isPal = false;
break;
}
}
if (isPal) {
console.log('palindrome')
}
}
pal('maddog');
pal('maddam');
You don't really need the nested loops, you can just loop backwards through the string to invert the string and then compare it to the original string. I updated the Snippet to work.
Before, your code was not inverting the string but rather just iterating through the characters and assigning them to the comp1 and comp1 variables. You need to concatenate the strings in order to build the new string backwards comp = comp + str.substring(j-1, j);
var pal = function(str) {
var len = str.length;
var comp = '';
for (var j = len; j > 0; j--) {
comp = comp + str.substring(j - 1, j);
}
if (str !== comp) {
console.log("not palindrome")
return;
}
console.log('palindrome')
}
pal('arepera');

Return the first word with the greatest number of repeated letters

This is a question from coderbyte’s easy set. Many people asked about it already, but I’m really curious about what’s wrong with my particular solution (I know it’s a pretty dumb and inefficient one..)
Original question:
Have the function LetterCountI(str) take the str parameter being passed and return the first word with the greatest number of repeated letters. For example: "Today, is the greatest day ever!" should return greatest because it has 2 e's (and 2 t's) and it comes before ever which also has 2 e's. If there are no words with repeating letters return -1. Words will be separated by spaces.
My solution works most of the time. But if it seems the last word of the input isn’t valued by my code. For example, for “a bb ccc”, “bb” will be returned instead of “ccc”. But the funny thing here is if the string only contains one word, the result is correct. For example, “ccc” returns “ccc”.
Please tell me where I was wrong. Thank you in advance!
function LetterCountI(str) {
str.toLowerCase();
var arr = str.split(" ");
var count = 0;
var word = "-1";
for (var i = 0; i < arr.length; i++) {
for (var a = 0; a < arr[i].length; a++) {
var countNew = 0;
for (var b = a + 1; b < arr[i].length; b++) {
if(arr[i][a] === arr[i][b])
countNew += 1;
}
if (countNew > count) {
count = countNew;
word = arr[i];
}
}
return word;
}
}
Please find below the workable version of your code:
function LetterCountI(str) {
str = str.toLowerCase();
var arr = str.split(" ");
var count = 0;
var word = "-1";
for (var i = 0; i < arr.length; i++) {
for (var a = 0; a < arr[i].length; a++) {
var countNew = 0;
for (var b = a + 1; b < arr[i].length; b++) {
if (arr[i][a] === arr[i][b])
countNew += 1;
}
if (countNew > count) {
count = countNew;
word = arr[i];
}
}
}
return word;
}
Here is the Java code soln for your problem.
You have returned your answer incorrectly. You should have returned word/Answer/res out of "for loops".
Check my chode here.
public static String StringChallenge( String str) {
String[] arr = str.split(" ");
int count = 0; String res = "-1";
for (int i = 0; i < arr.length ; i++) {
for (int j = 0; j < arr[i].length() ; j++) {
int counter = 0;
for (int k = j + 1; k < arr[i].length() ; k++) {
if(arr[i].charAt(j) === arr[i].charAt(k) )
counter ++;
}
if (counter > count) {
count = counter; res = arr[i];
}
}
return res;
}
}
I think the problem is that you're placing the return statement inside your outermost loop. It should be inside your inner loop.
So you have to place the return statement within the inner loop.
Correct use of return
if (countNew > count) {
count = countNew;
word = arr[i];
}
return word;
}
}
}
You need to move the return word; statement outside of the loop to fix your version.
I also put together another take on the algorithm that relies on a few built in javascript methods like Array.map and Math.max, just for reference. I ran a few tests and it seems to be a few milliseconds faster, but not by much.
function LetterCountI(str) {
var maxCount = 0;
var word = '-1';
//split string into words based on spaces and count repeated characters
str.toLowerCase().split(" ").forEach(function(currentWord){
var hash = {};
//split word into characters and increment a hash map for repeated values
currentWord.split('').forEach(function(letter){
if (hash.hasOwnProperty(letter)) {
hash[letter]++;
} else {
hash[letter] = 1;
}
});
//covert the hash map to an array of character counts
var characterCounts = Object.keys(hash).map(function(key){ return hash[key]; });
//find the maximum value in the squashed array
var currentMaxRepeatedCount = Math.max.apply(null, characterCounts);
//if the current word has a higher repeat count than previous max, replace it
if (currentMaxRepeatedCount > maxCount) {
maxCount = currentMaxRepeatedCount;
word = currentWord;
}
});
return word;
}
Yet another solution in a more functional programming style:
JavaScript
function LetterCountI(str) {
return ((str = str.split(' ').map(function(word) {
var letters = word.split('').reduce(function(map, letter) {
map[letter] = map.hasOwnProperty(letter) ? map[letter] + 1 : 1;
return map;
}, {}); // map of letters to number of occurrences in the word
return {
word: word,
count: Object.keys(letters).filter(function(letter) {
return letters[letter] > 1;
}).length // number of repeated letters
};
}).sort(function(a, b) { // Sort words by number of repeated letters
return b.count - a.count;
}).shift()) && str.count && str.word) || -1; // return first word with maximum repeated letters or -1
}
console.log(LetterCountI('Today, is the greatest day ever!')); // => greatest
Plunker
http://plnkr.co/edit/BRywasUkQ3KYdhRpBfU2?p=preview
I recommend use regular expression: /a+/g to find a list of letter with a key word a.
My example :
var str = aa yyyyy bb cccc cc dd bbb;
Fist, find a list of different word :
>>> ["a", "y", "b", "c", "d"]
Use regular expression for each word in list of different word :
var word = lstDiffWord[1];
var
wordcount = str.match(new RegExp(word+'+','g'));
console.log(wordcount);
>>>>["yyyyy"]
Here is full example: http://jsfiddle.net/sxro0sLq/4/

Categories

Resources