semi-space copy allocation failed, javascript heap out of memory - javascript

I was wondering why the below code returns a memory allocation error?
var countValidWords = function(sentence) {
let words = [];
for(let i = 0; i < sentence.length; ++i){
let word = '';
while(sentence[i] !== ' '){
word += sentence[i];
++i;
}
if(word !== '')
words.push(word);
}
console.log(words);
};
I'm simply trying to build an array of words from the inputted sentence (words can be separated by more than one space).

If the sentence doesn't end with a space, the while loop never ends, because it doesn't check if it has gone past the end of the string. As a result, you go into an infinite loop appending undefined to word, until you run out of memory.
Add a check that i is within the string length there.
var countValidWords = function(sentence) {
let words = [];
for(let i = 0; i < sentence.length; ++i){
let word = '';
while(i < sentence.length && sentence[i] !== ' '){
word += sentence[i];
++i;
}
if(word !== '')
words.push(word);
}
console.log(words);
};

The while clause needs to check for i getting out of bounds:
while(i < sentence.length && sentence[i] !== ' ')

How about this? It's not the most optimized version you might find but it works.
You had an infinite loop on the while.
var countValidWords = function(sentence) {
let words = [];
let word = ''
for(let i = 0; i < sentence.length; ++i){
if(sentence[i] != '' && sentence[i] != ' '){
word += sentence[i];
}
if(sentence[i] == ' ' || sentence[i + 1] === undefined){
words.push(word);
word = '';
}
}
console.log(words);
};

Related

How to get multiple sub strings from string with delimiter # in angular

I have a string with multiple delimiters to change the string further.
How can I get those substrings?
Here is the string:
let string = 'Dear user,
Due to #userinput-reason#, your ward client will travel on #userinput-newtransit#
instead of the regular transit #userinput-regulartransit#.';
From the above string, I need set of all substrings in between # s.
Required output:
let substring = [ 'userinput-reason', 'userinput-newtransit', 'userinput-regulartransit' ]
Thank you.
let str = 'Dear user, Due to #userinput-reason#, your ward client will travel on #userinput-newtransit# instead of the regular transit #userinput-regulartransit#.';
let strings = [];
let indexStart;
let indexEnd;
for (let i = 0; i < str.length; i++) {
if (str[i] == '#') {
indexStart = i + 1;
if (indexStart >= 0) {
for (let j = i + 1; j < str.length; j++) {
if (str[j] == '#') {
indexEnd = j ;
let stringExtracted = str.substring(indexStart, indexEnd);
strings.push(stringExtracted); }
}
}
}
}
console.log(strings);
Do it with regex:
let a = 'Dear user, Due to #userinput-reason#, your ward client will travel on #userinput-newtransit# instead of the regular transit #userinput-regulartransit#.';
let arr = a.match(/(?!#)(\w|-)+(?=#)/g);
console.log(arr);
let str = 'Dear user, Due to #userinput-reason#, your ward client will travel on #userinput-newtransit# instead of the regular transit #userinput-regulartransit#.';
let strings = [];
let temp = "";
let append = false;
for(let i = 0; i< str.length; i++){
if(append == true && str[i] != '#'){
temp += str[i];
}
if(str[i] == '#' && append == false){
// mark the starting of the token
append = true;
}
else if (append == true && str[i] == "#"){
// mark the end of the token
append = false;
strings.push(temp);
temp = "";
}
}
console.log(strings)

Longest chain of letters in word JavaScript

I need to write a program that is find longest chain of letters in a word and displays it in a console.log with their length. Example aaaAAAAdddeess - console.log( 'AAAA' ,4 ). Program must be in JavaScript and must distinguish capital letters. I`ve tried something like
const word = 'aaadddAAAwwwweee'
let newWord = ' '
for (let i = 0; i < word.length; i++) {
if (word[i] === word[i + 1]) {
newWord += word[i] + word[i + 1]
i++
}
}
console.log(newWord, newWord.lenght)
You can split the word to letters and check each letter with next one. Then push current sequence in an array, it will be current max sequence. Each iteration check the size of current longest sequnece with max sequence.
const word = 'aaadddAAAwwwweee'
let lettersArr = word.split('');
let currentSequence = [];
let maxSequence = [];
for (let index = 0; index < lettersArr.length; index++) {
let element = lettersArr[index];
currentSequence = [element];
for (let i = index + 1; i < lettersArr.length; i++) {
if (lettersArr[index] == lettersArr[i]) {
currentSequence.push(lettersArr[index]);
} else {
break;
}
}
if (currentSequence.length > maxSequence.length) {
maxSequence = currentSequence;
}
}
let newWord = maxSequence.join('');
console.log(newWord, newWord.length);

Trying to create a palindrome function that accounts for spaces

Okay so palindrome is a word that is the same spelled backwards. What if we want to take a phrase that is also the same backwards? So kook is one. race car is another one.
So I made one that doesn't account for spaces.
function isPal(string){
var l = string.length;
for (var i = 0; i < (l/2); ++i) {
if (string.charAt(i) != string.charAt(l - i - 1)){
return false;
}
}
return true;
}
This one works fine for words.
Now I'm thinking, push the string into an array, and split up each character into it's own string, then remove any spaces, and then run if (string.charAt(i) != string.charAt(string.length - i - 1)). So here's what I wrote but failed at..
function isPalindrome(string){
var arr = [];
arr.push(string.split(''));
for (i = 0; i < arr.length; i++){
if (arr[i] === ' '){
arr.splice(i, 1);
if I return arr, it still gives me the string with the space in it. How do I accomplish this? Thanks!
EDIT: Used the solution but still getting false on 'race car'
Here's what I got:
function isPalindrome(string){
var arr = string.split('');
for (i = 0; i < arr.length; i++){
if (arr[i] === ' '){
arr.splice(i, 1);
} else if (arr[i] != arr[arr.length - i - 1]){
return false;
}
}
return true;
}
where's my error?
Your problem is in the following line:
arr.push(string.split(''));
string.split('') returns an array. So, arr is actually an array with one entry it in (another array that contains your characters). Replace:
var arr = [];
arr.push(string.split(''));
with
var arr = string.split('');
and it should work as expected
Just check check the string without spaces:
function isPal(string){
string = string.split(" ").join(""); // remove all spaces
var l = string.length;
for (var i = 0; i < (l/2); ++i) {
if (string.charAt(i) != string.charAt(l - i - 1)){
return false;
}
}
return true;
}
isPal("a man a plan a canal panama"); // true
It seems much easier to just split into an array, reverse and join again to check if a word is a palindrome. If you want to ignore spaces, just remove all instances of spaces:
let word = 'race car';
let isPalindrome = (word) => {
let nospaces = word.replace(/\s/g, '');
return [...nospaces].reverse().join('') === nospaces;
}
Or non-es6:
var word = 'race car';
var isPalindrome = function(word) {
var nospaces = word.replace(/\s/g, '');
return nospaces.split('').reverse().join('') === nospaces;
}

Javascript How to reverse space separated strings

The code below should reverse all the characters in a sentence, but it is unable to do so. This is child's play to me but at this moment it's not compiling. Can anyone figure out the issue?
Let's say:
"Smart geeks are fast coders".
The below code should reverse the above string as follows:
"trams skeeg era tsaf sredoc"
function solution(S){
var result = false;
if(S.length === 1){
result = S;
}
if(S.length > 1 && S.length < 100){
var wordsArray = S.split(" "),
wordsCount = wordsAray.length,
reverseWordsString = '';
for(var i = 0; i< wordsCount; i++){
if(i > 0){
reverseWordsString = reverseWordsString + ' ';
}
reverseWordsString = reverseWordsString + wordsAray[i].split("").reverse().join("");
}
result = reverseWordsString;
}
return result;
}
This should give you the result you're looking for.
function reverseWords(s) {
return s.replace(/[a-z]+/ig, function(w){return w.split('').reverse().join('')});
}
function reverseWords(s) {
var arr = s.split(" ");
s = '';
for(i = 0; i < arr.length; i++) {
s += arr[i].split('').reverse().join('').toLowerCase() + " ";
}
return s;
}
Wouldn't that do the job for you? Basically it just converts the string into an array, by splitting it on space. Then it loops over the array, adds every string reversed to a new string, and then it converts it to lowercase. For faster speed (nothing you would notice), you can just call newStr.toLowerCase() after the loop, so it will do it once instead of every time.

function is returning numbers instead of letters

I am trying to make a function that will return the last letter of each word in a string, and think I am close, but whenever I invoke the function, I get a series of numbers instead of the letters I am looking for.
This is the code:
function lastLetter(str){
var arr = [];
for(var i = 0; i < str.length; i++){
if(str[i] === " " || str[i] === "."){
arr.push((i) - 1);
}
}
return arr;
}
lastLetter("I love bacon and eggs.");
Any advice would be appreciated. Thanks!!
You push the value i - 1 onto the array. You meant to push str.charAt(i-1):
arr.push(str.charAt(i - 1));
See: String charAt().
Note that your code isn't really defensive. If there is a space or period at the first character in the string, you are referencing the character at position -1, which is not valid. You could solve this by looping from 1 instead of 0. In that case you would still get a space in the result if the string starts with two spaces, but at least you won't get an error. A slightly better version of the algorithm would test if i-1 is a valid index, and if there is a character at that position that is not a space or a period.
Below is a possible solution, which I think solves those cases, while still retaining the structure of the code as you set it up.
function lastLetter(str){
var arr = [];
for(var i = 1; i < str.length; i++){
var p = str.charAt(i-1);
var c = str.charAt(i);
if ( (c === " " || c === ".") &&
!(p === " " || p === ".") ) {
arr.push(p);
}
}
return arr;
}
console.log(lastLetter("... Do you love bacon and eggs..."));
Try:
arr.push(str[i - 1]);
This will have problems with multi-byte characters, however.
You're pushing the integer value i-1 rather than the character str[i-1].
You are pushing the index into your array. You still need to access i-1 of your string
`
` function lastLetter(str){
var arr = [];
for(var i = 0; i < str.length; i++){
if(str[i] === " " || str[i] === "."){
arr.push(str[(i) - 1]);
}
}
return arr;
}
lastLetter("I love bacon and eggs.");
Solution and Improved version below:
use arr.push(str.charAt(i - 1)) instead of arr.push((i) - 1)
(You where saving the position of the last letter, but not it's value - charAt(position) does give you the latter at the given position
charAt(): http://www.w3schools.com/jsref/jsref_charat.asp
Demo:
function lastLetter(str){
var arr = [];
for(var i = 0; i < str.length; i++){
if(str[i] === " " || str[i] === "."){
arr.push(str.charAt(i - 1));
}
}
return arr;
}
document.body.innerHTML = lastLetter("I love bacon and eggs.");
Improved Version:
function lastLetter(str) {
var arr = [];
var words = str.split(/[\s\.?!:]+/)
for (var i = 0; i < words.length; ++i) {
if (words[i].length > 0) {
var lastLetter = words[i].charAt(words[i].length - 1)
arr.push(lastLetter);
}
}
return arr;
}
document.body.innerHTML = lastLetter("... Is this: correct?! I love bacon and eggs.");

Categories