String compression
Implemente uma função para executar a compactação de uma string simples usando um contador para os caracteres repetidos.
Por exemplo, a string aabcccccaaa
deve retornar a2b1c5a3
.
A compactação deve sempre retornar uma string com tamanho menor do que ao valor da entrada. Se não for, sua função deve retornar a string original.
Você pode assumir que a string tem apenas letras maísculas e minúsculas (az-AZ)
Dicas
- Faça o simples primeiro. Realiza a compreensão e depois compare os tamanhos.
- Tenha cuidado para não concatenar strings repetidamente. Isso pode ser muito ineficiente.
Solução 1:
Eu comecei resolvendo o exercício pensando em iterar sob a string e comparar com o anterior.
Inicialmente, eu pensei em guardar a soma em uma Hash Table. No final, a lógica de comparar com o anterior ficou mais complexa, se comparada com as demaos soluções.
Segue solução:
function stringCompression (input) {
const inputSize = input.length
const tempObj = {}
let result = ""
let previous = ""
for (let index = 0; index < inputSize; index++) {
const currentCharacter = input[index];
if (!tempObj[currentCharacter]) {
tempObj[currentCharacter] = 1
} else {
tempObj[currentCharacter]++
}
if (previous && previous !== currentCharacter) {
result = `${result}${previous}${tempObj[previous]}`
tempObj[previous] = 0
}
previous = currentCharacter
if (index === (inputSize - 1)) {
result = `${result}${currentCharacter}${tempObj[currentCharacter]}`
if (result.length > inputSize) {
result = input
}
}
}
return result
}
Solução 2:
Já a solução comparando o atual caracter com o próximo é bem mais simples.
Toda vez que o próximo caracter é diferente, fazemos a concatenação e resetamos o contador:
function stringCompression (input) {
const inputLength = input.length
let result = ""
let count = 0
for (let index = 0; index < inputLength; index++) {
const currentCharacter = input[index];
count++
if (input[index + 1] !== currentCharacter) {
result = `${result}${currentCharacter}${count}`
count = 0
}
}
return result.length > inputLength
? input
: result
}
Solução 3:
Como a concatenação de strings pode ficar "cara" computacionalmente falando,
então pode ser melhor adicionar o resultado em um array push()
e, no final,
transformá-lo em string join()
:
function stringCompression (input) {
const resultArray = []
let count = 0
for (let index = 0; index < input.length; index++) {
const currentCharacter = input[index];
count++
if (input[index + 1] !== currentCharacter) {
resultArray.push(currentCharacter)
resultArray.push(count)
count = 0
}
}
const resultStr = resultArray.join("")
return resultStr.length > input.length
? input
: resultStr
}