I have two inputs (original and comprimida). The original one is like this one "bbbddef" which in a compressed form would be "b3d2e1f1" (Three times b, two times d, one for e and one for f). However, when I have a original like this one: "aaaaaaaaaaabcdda" that should be "a11b1c1d2a1" it only counts till 9 because the for cannot go above 9 (two digits). How can I solve this? Thanks in advance.
Here's the code
var original = "aaaaaaaaaaabcdda";
var comprimida = "a11b1c1d2a1";
var res = "";
for(var i = 0; i < comprimida.length; i =2){
let letra = comprimida.charAt(i);
let numero = comprimida.charAt(i 1);
for(let j=0; j<numero; j ){
res = letra;
}
}
if(original == res){
alert("SI");
} else {
alert("NO");
}
The code should do 'a' 11 times and it's not doing so since it only takes the first 1 from 11. But I can't make it count two digits only because then every other solution for 'a' being less than 10 would be wrong.
CodePudding user response:
This solution reads char by char. If it's a letter it is being remembered, if it's a digit it's being calculated to be a number. Then, if it's a letter again we repeat number of times the last remembered letter.
var comprimida = "a11b1c1d2a1";
var result = "";
var current = "";
var number = 0;
comprimida.split("").forEach(function(char) {
if (char >= 'a' && char <= 'z') {
result = current.repeat(number)
number = 0;
current = char;
} else {
number = number * 10 char
}
})
result = current.repeat(number)
console.log(result)
CodePudding user response:
A RegExp alternative
As an alternative, you could also use RegExp to compress and uncompress the string. The functions for doing both are shown below.
Compress
The regex for the compress function simply captures groups of matching letters. The [a-zA-Z]
is the regex for matching letters and the \1
instructs it to compare the current and previous letters when doing the match. You can read more about backward references here. And from the matched characters it generates a string with letters followed by the number of times it repeats.
Uncompress
The uncompress function uses regex to break the string into an array. Each element of the array starts with a letter and is followed by the number of times it repeats. And from this it is easy to recreate the original string.
Note that the regex is made to be case insensitive using the /i
suffix. Yet, you can remove that if you want to do strict case sensitive conversions. Additional code would be required to make it handle special characters not in A-Z.
Try the code snippet to see how it works:
var original = "aaaaaaaaaaabcdda";
var comprimida = "a11b1c1d2a1";
const compress = (text) =>
text.match(/([a-zA-Z])\1{0,100}/gi).map(s => s[0] s.length).join("");
const uncompress = (text) =>
text.match(/([a-zA-Z]\d )/gi).reduce((p, c) =>
p c[0].repeat(c.substr(1)), "");
console.log(original === uncompress(comprimida) ? "SI" : "NO");
console.log("Compress: " original " --> " compress(original));
console.log("Uncompress: " comprimida " --> " uncompress(comprimida));
// console.log(original.match(/(\w)\1{0,100}/gi));
// OUTPUT: ["aaaaaaaaaaa", "b", "c", "dd", "a" ]