I'm trying to solve a question to create a new compressed string. Each character has a count next to it and I was supposed to come with up a new string in alphabetical order followed by the total count of that character within the string.
For eg:
Input: "a10b1a5c1" Output: "a15b1c1"
Input: "b10a1b5c1" Output: "a1b15c1"
How I approached this question?
- Have an object with key as char and value as count
- Convert the object to string
function stringCompression(s) {
const object={}
for(var i=0; i<s.length-1; i ) {
if(s[i].match(/[0-9]/)!==null && s[i 1].match(/[a-zA-Z]/) === null) {
if(object.hasOwnProperty("s[i]")){
// Add previous and current value
} else {
object[s[i-1]]=parseInt(s[i] s[i 1])
}
}
}
return object
}
// output should be a15b1c1
const output= stringCompression("a10b1a5c1");
const final = Object.keys(output).map(key => `${key}${output[key]}`).join("");
console.log(final)
Question:
- Can't think of a way to sort alphabetically
- The function I wrote doesn't handle if the character has a single digit count
- Is there any other way I can optimise the solution?
CodePudding user response:
You could reduce()
everything to a single "counter" object, and then use Object.entries()
to convert that object to an array and perform sorting, flattening and joining on that array:
const compress = (s) => Object.entries(
[...s.matchAll(/([A-Za-z])(\d )/g)].reduce((a, [_, char, number]) => ({
...a,
[char]: (a[char] || 0) number
}), {})
).sort(([a], [b]) => a.localeCompare(b)).flat().join('');
console.log(compress('b10a1b5c1'));
CodePudding user response:
const STRING = 'a10c8b3a4'
const isDigit = (charCode) => {
return charCode >= 48 && charCode <=57
}
const isAlphabet = (charCode) => {
return charCode >= 97 && charCode <= 122
}
const getSortedObject = (obj) => {
return Object.keys(obj).sort().reduce(
(object, key) => {
object[key] = obj[key];
return object;
}, {}
);
}
const getCompressedString = (string) => {
let obj = {}
let alphabet = ''
let digit = ''
let i = 0
while(i<string.length) {
const char = string[i]
const charCode = string.charCodeAt(i)
if(isAlphabet(charCode)) {
alphabet = char
if(!obj[alphabet]) {
obj[alphabet] = '0'
}
i
} else if(isDigit(charCode)) {
digit = '0'
while(isDigit(string.charCodeAt(i)) && i<string.length) {
digit = string[i]
i
}
obj[alphabet] = parseInt(obj[alphabet]) parseInt(digit)
}
}
let compressedString = ''
Object.keys(getSortedObject(obj)).forEach(key => {compressedString = key obj[key]})
return compressedString
}
console.log(getCompressedString(STRING))