Why does my code not work out well replacing strings characters? - javascript

The exercise:
The goal of this exercise is to convert a string to a new string where each character in the new string is "(" if that character appears only once in the original string, or ")" if that character appears more than once in the original string. Ignore capitalization when determining if a character is a duplicate.
Examples
"din" => "((("
"recede" => "()()()"
"Success" => ")())())"
"(( #" => "))(("
My code was like that:
function duplicateEncode(word) {
let str = "";
for (let i = 0; i < word.length; i++) { //This iteration is to examine every character in the string;
for (let j = 0; j < word.length; j++) { //This iteration is to compare every character to every other inside the string, in order to check if there is any repetition
if (j === i) { //This first conditon was selected because a character is not supposed to be compared to itself
continue;
} else if (word[i] === word[j]) {
str = str + ")";
break;
} else if (j !== word.length - 1) {
continue;
} else if (j === word.length - 1) {
str = str + "(";
}
}
}
return str;
}
Does anyone can help me figure out why it doesn't work for all cases?
For example:
console.log(duplicateEncode("abc"));
It should return ((( instead of ((
But,
console.log(duplicateEncode("mulherm"));
returns exacly what it supposed to: )((((()
Apparently, whenever a string does not have a character that repeats,the function returns a string without the first element. But whenerver the string has at least one element that repeats it returns exacly what it's supposed to.
What is going on with my code?

I think the issue is that when you use your snippet below, you prevent yourself from entering the last loop.
if (j === i) {
continue;
}
The issue is present whenever a word with a non duplicated letter is last. i.e.
This works
console.log(duplicateEncode("aba")); //returns )()
This does not
console.log(duplicateEncode("aab")); //returns ))
What you could do is add a statement that when
i === word.length - 1
and no
"(" are in your
str variable, you can append another ")" to your str.
In other words, if you have found no duplicated characters after checking the before last position while iterating over your entire word, the last is guaranteed to be unique as well.
Console logs below
function duplicateEncode(word) {
let str = "";
for (let i = 0; i < word.length; i++) { //This iteration is to examine every character in the string;
for (let j = 0; j < word.length; j++) { //This iteration is to compare every character to every other inside the string, in order to check if there is any repetition
console.log(i);
console.log(j);
console.log(str);
if (j === i) { //This first conditon was selected because a character is not supposed to be compared to itself
console.log("continue")
continue;
} else if (word[i] === word[j]) {
console.log("append )")
str = str + ")";
break;
} else if (j !== word.length - 1) {
console.log("j !== length")
continue;
} else if (j === word.length - 1) {
console.log("append (")
str = str + "(";
}
}
}
return str;
}

Use a debugger to step through your code line by line. There are cases where the inner loop completes without ever meeting one of the conditions for a adding a character to the string.
Instead, use a boolean flag to denote whether the letter is duplicated, set that inside the loop (much simpler logic), then after the loop do str += (found ? ')' : '(');. This ensures you add exactly one character to the output string per iteration of the outer loop.

Related

What is the fastest way to count the number of lines in a string in JavaScript?

I'm looking for the most performant way to count the number of lines in a string in JavaScript for a string of any length. I have tested three approaches, but I feel like there may be a faster way that one of you is aware of.
Method 1:
// Split the string on newlines into an array and measure the array length
return string.split(/\r|\r\n|\n/g).length;
Method 2:
// Use match instead of split
return (string.match(/\r|\r\n|\n/g) || '').length + 1;
Method 3:
// Replace all of the newlines with empty space and compare line lengths
return string.length - string.replace(/\r|\r\n|\n/g, '').length + 1;
Find the first occurrence of a possible line break character and count this character:
function countLines(string) {
let count = 1;
let chr;
let i = 0, end = string.length;
for (; i < end; ++i) {
if (string[i] == '\n' || string[i] == '\r') {
count = 2;
chr = string[i];
break;
}
}
for (++i; i < end; ++i) {
if (string[i] == chr) {
++count;
}
}
return count;
}
const linuxString = 'Some\ntext\nwith\nfive\nlines';
const windowsString = 'Some\r\ntext\r\nwith\r\nfive\r\nlines';
const classicMacString = 'Some\rtext\rwith\rfive\rlines';
console.log(countLines(linuxString));
console.log(countLines(windowsString));
console.log(countLines(classicMacString));

I want to return undefined but instead got "{"

In this code I want to return the alphabet that's missing in a string of continuous alphabets, and if all alphabets are present I want to return undefined.
However, instead returning defined, it returns "{" and I can't find similar cases anywhere online.
function fearNotLetter(str) {
for (let i = 0; i < str.length; i++) {
if (str.charCodeAt(i) !== str.charCodeAt(i + 1) - 1) {
return String.fromCharCode(str.charCodeAt(i) + 1)
}
}
return undefined
}
console.log(fearNotLetter("abcdefghijklmnopqrstuvwxyz"))
Your code compares each letter with the letter following it in the string
You can't test the last letter, since nothing comes after it
simply change the loop so it only iterates to the second last letter
function fearNotLetter(str) {
for (let i = 0; i < str.length - 1; i++) {
if (str.charCodeAt(i) !== str.charCodeAt(i + 1) - 1) {
return String.fromCharCode(str.charCodeAt(i) + 1)
}
}
return undefined
}
console.log(fearNotLetter("abcdefghijklmnopqrstuvwxyz"))
here in your example inside for loop you are returning
String.fromCharCode(str.charCodeAt(i)+1)
in this return value when charecter is z , where has ascii value of 'z' is 122 and you are returning 122+1 that is asci value of '{'
thats why you are getting '{' in your example
you can test by removing 'z' from passed string in your function

Remove consecutive characters from string until it doesn't have any consecutive characters

If you see two consecutive characters that are the same, you pop them from left to right, until you cannot pop any more characters. Return the resulting string.
let str = "abba"
"abba" - pop the two b's -> "aa"
"aa" - pop the two a's -> ""
return ""
Here's what i have tried so far:
function match(str){
for (let i = 0; i< str.length; i++){
if (str[i] === str[i+1]){
return str.replace(str[i], "");
}
}
};
match('abba');
But it replaces one character only.The problem is if any two consecutive characters matches it needs to remove both of those and console (Like 'abba' to 'aa'). Then it needs to go over the updated string to do the same thing again (Like 'aa' to '')and console until the return string can't be changed anymore.
Here's another solution i found:
function removeAdjacentDuplicates(str) {
let newStr = '';
for (let i = 0; i < str.length; i++) {
if (str[i] !== str[i + 1])
if (str[i - 1] !== str[i])
newStr += str[i];
}
return newStr;
};
removeAdjacentDuplicates('abba');
But this iterates one time only. I need this to go on until there's no more consecutive characters. Also It would be great if good time complexity is maintained.
You can use a while loop to continuously loop until the result is equal to the previous result.
function removeAdjacentDuplicates(str) {
let newStr = '';
for (let i = 0; i < str.length; i++) {
if (str[i] !== str[i + 1])
if (str[i - 1] !== str[i])
newStr += str[i];
}
return newStr;
};
let before = 'abba';
let result = removeAdjacentDuplicates(before);
while(result != before){
before = result;
result = removeAdjacentDuplicates(before);
}
console.log(result);
If you want to add a limit to the number of pops, you can store the maximum pops in a variable and the number of pops in another (incremented in the loop), then add an expression to the while loop that instructs it not to execute when the number of pops is no longer smaller than the maximum number of pops permitted.
E.g:
function removeAdjacentDuplicates(str) {
let newStr = '';
for (let i = 0; i < str.length; i++) {
if (str[i] !== str[i + 1])
if (str[i - 1] !== str[i])
newStr += str[i];
}
return newStr;
};
let before = 'cabbac';
let result = removeAdjacentDuplicates(before);
const maxPop = 2;
var pops = 1; //It's 1 because we already removed the duplicates once on line 11
while (result != before && pops < maxPop) {
before = result;
result = removeAdjacentDuplicates(before);
pops++;
}
console.log(result);
You can use a regular expression to match consecutive characters and keep replacing until the string is unchanged.
function f(s) {
while (s != (s = s.replace(/(.)\1+/g, '')));
return s;
}
console.log(f("abba"))

Assistance with javascript palindrome

I am trying to solve a palindrome using a for loop in JavaScript (my code is below).
I cannot figure out what I am doing wrong. If someone can please correct and explain, it will be much appreciated. I am fairly new to coding.
var word = window.prompt("Enter a word");
function palindrome(a) {
var reversed = '';
for (i = 0; i <= a.length; i++) {
reversed = reversed + a[a.length - 1 - i];
}
if (a == reversed) {
return "true";
} else {
return "false";
}
}
document.write(palindrome(word));
On for loop inside palindrome, you have looped from 0 ~ a.length and the item on length index in a string is undefined so reversed will always be undefined.
You need to loop from 0 ~ a.length - 1 as follows.
var word = window.prompt("Enter a word");
function palindrome(a) {
var reversed = '';
for (i = 0; i < a.length; i++) {
reversed = reversed + a[a.length - 1 - i];
}
console.log(reversed);
if (a == reversed) {
return "true";
} else {
return "false";
}
}
document.write(palindrome(word));
You can reverse string simply as follows.
var word = window.prompt("Enter a word");
function palindrome(a) {
const reversed = a.split('').reverse().join('');
if (a == reversed) {
return "true";
} else {
return "false";
}
}
document.write(palindrome(word));
your loop:
for (i = 0; i <= a.length; i++) {
reversed = reversed + a[a.length - 1 - i];
}
you just need remove -1 and start the loop with 1 because when you reached the end of the iteration you will have the length of the word -1 and this will try to access a negative position.
after changing:
for (let i = 1; i <= a.length; i++) {
// you can use reversed += a[a.length - i] instead of;
reversed = reversed + a[a.length - i];
}
You can also reverse a string using the reverse method like this:
reversed = a.split('').reverse().join('');
Finally if you want to validata sentences you need to remove blank spaces and convert it in lower or upper case(usually converted in lowercase) because compare is case sensitive ("Party trap" != "part ytraP").
This code compares the first character to the last character, then advances to compare the second character to the next to last character until it runs out of characters.
As soon as it finds an inequality, it returns false because there is no reason to continue comparing.
let word = window.prompt("Enter a word");
const palindrome = a => {
let last = a.length - 1;
// loop, comparing the values until you find something that doesn't match
for (let first = 0; first <= last; first++, last--) {
if (a[first] !== a[last]) {
return "false";
}
}
// everything matched
return "true";
}
document.getElementById("output").textContent = palindrome(word);
<output id="output"></output>

CoderByte Letter Changes Java Script

The question is :
Using the JavaScript, have the function LetterChanges(str) take the str parameter being passed and modify it using the following algorithm. Replace every letter in the string with the letter following it in the alphabet (ie. c becomes d, z becomes a). Then capitalize every vowel in this new string (a, e, i, o, u) and finally return this modified string.
function LetterChanges(str){
var result = "";
for(var i = 0; i < str.length; i++) {
var letters = str[i];
if (letters == "a"|| letters == "e"|| letters == "i"|| letters == "o"|| letters =="u") {
letters = letters.toUpperCase();
result+=letters;
} else if (letters == "z") {
letters = "a";
} else {
var answer = "";
var realanswer="";
for (var i =0;i<str.length;i++) {
answer += (String.fromCharCode(str.charCodeAt(i)+1));
}
realanswer += answer
}
}
return realanswer;
return result;
}
LetterChanges();
basically, if return realanswer is placed before return result and LetterChanges is called with "o" i get the output undefined. But if it is called with a non vowel such as "b" it will output "c" which is correct.
now if i place return result before return realanswer it will work properly for vowels but not for other letters. thanks for the help
function LetterChanges(str) {
return str
.replace(/[a-zA-Z]/g, (x) => String.fromCharCode(x.charCodeAt(0)+1))
.replace(/[aeiou]/g, (v) => v.toUpperCase());
}
The first part modifies the consonants by an increment of 1.
Regex is isolating the characters with [] versus no brackets at all. g ensures that the regex is applied anywhere in the string, as opposed to not putting g which gives you the first occurrence of the search.
You have to convert the characters in the string to their Unicode because incrementing is a math operation. x.charCodeAt(0) is saying at the index of 0 of the string in the argument. The increment of 1 is not within the parentheses but outside.
The second part modifies the vowels to upper case.
This is pretty straightforward, the regex only finds the individual characters because [] are used, g for anywhere in the string. and the modifier is to make the characters become upper case.
function LetterChanges(str) {
var lstr = "";// Took a variable to store after changing alphabet//
for(var i=0;i<str.length;i++){
var asVal = (str.charCodeAt(i)+1);// To convert string to Ascii value and 1 to it//
lstr += (String.fromCharCode(asVal));// To convert back to string from Asii value//
}
console.log("Before converting vowels :"+lstr); //Printing in console changed alphabet//
var neword =""; // variable to store word after changing vowels to uppercase//
for(i=0;i<lstr.length;i++){
var strng = lstr[i]; // Storing every letter in strng variable while running loop //
if(strng=="a"||strng=="e"||strng=="i"||strng=="o"||strng=="u"){
neword += strng.toUpperCase(); // If it a vowel it gets uppercased and added //
}
else{
neword += strng; // If not vowel , it just gets added without Uppercase //
}
}
console.log("After converting vowels :"+neword); //Printing in console the word after captilising the vowels //
}
LetterChanges("Goutham"); // Calling a function with string Goutham //
function letterChanges(str) {
let res = '';
let arr = str.toLowerCase().split('');
// Iterate through loop
for(let i = 0; i < str.length; i++) {
// Convert String into ASCII value and add 1
let temp = str.charCodeAt(i) + 1;
// Convert ASCII value back into String to the result
res += (String.fromCharCode(temp));
}
console.log(res);
// Replace only vowel characters to Uppercase using callback in the replace function
return res.replace(/[aeiou]/g, (letters) {
return letters.toUpperCase();
});
}
function LetterChanges(str) {
return str
.split('')
.map((c) => String.fromCharCode((c >= 'a' && c <= 'z') ? (c.charCodeAt(0)-97+1)%26+97 : (c >= 'A' && c <= 'Z') ? (c.charCodeAt(0)+1-65)%26+65 : c.charCodeAt(0)))
.join('').replace(/[aeiou]/g, (letters) => letters.toUpperCase());
}
export const letterChange=(str)=>{
let newStr = str.toLowerCase().replace(/[a-z]/gi, (char)=>{
if(char==="z"){
return "a"
}else{
return String.fromCharCode(char.charCodeAt()+1)
}
})
let wordCap = newStr.replace(/a|e|i|o|u/gi, char => char.toUpperCase())
return wordCap
}
function changeLetters(str) {
var result = "";
for (var i = 0; i < str.length; i++) {
var item = str[i];
if (
item == "a" ||
item == "e" ||
item == "i" ||
item == "o" ||
item == "u"
) {
item = item.toUpperCase();
result += item;
} else if (item == "z") {
letters = "a";
result += item;
} else {
result += String.fromCharCode(str.charCodeAt(i) + 1);
}
}
return result;
}

Categories

Resources