Compresión RLE Independiente

Iniciado por Tiruliki, 1 Enero 2017, 11:32 AM

0 Miembros y 1 Visitante están viendo este tema.

Tiruliki

Buenos días.

Venía a ver si alguno me podría ayudar con un programa en C++ que tengo confuso. Me explico. El ejercicio consiste en hacer un programa de compresión RLE pero totalmente independiente, es decir, introduzcas caracteres o números, debe funcionar el método.

Es decir;

A A B B --> 2 A 2 B.
1 1 2 2 --> 2 1 2 2.

Tengo una clase RLE, que la dejo por aquí:
Código (cpp) [Seleccionar]
class RLE
{

// La clase RLE no tiene campos.
// Los objetos de la clase sieven para ejecutar los métodos "Codifica"
// y "Descodifica" (esta implementación se diferencia muy poco de escribir
// los dos métodos como funciones globales).

private:

public:

/***********************************************************************/
// Codifica una secuencia de enteros según el código RLE y devuelve
// otra secuencia de enteros codificada.
//
// Recibe: secuencia_descodificada, la secuencia que se va a codificar.
// Devuelve: una nueva secuencia, resultado de codificar según RLE
// la secuencia recibida "secuencia_descodificada".

SecuenciaEnteros Codifica (SecuenciaEnteros secuencia_descodificada)
{
// Secuencia resultado de la codificación
SecuenciaEnteros secuencia_codificada;

int tope, actual, anterior, iguales_hasta_ahora;

// Registrar la longitud de la secuencia
tope = secuencia_descodificada.TotalUtilizados();

// Guardar el primer valor de la secuencia
actual = secuencia_descodificada.Elemento(0);

iguales_hasta_ahora = 1;

for (int pos=1; pos<tope; pos++) {

anterior = actual;
actual = secuencia_descodificada.Elemento(pos);

if (anterior == actual)

iguales_hasta_ahora++; // Continua la serie

else {

// Añade la pareja (valor, num.repeticiones)
secuencia_codificada.Aniade(iguales_hasta_ahora);
secuencia_codificada.Aniade(anterior);

iguales_hasta_ahora = 1; // empezar una nueva serie
}
} // for (int pos=1; pos<tope; pos++)

// Añade la última pareja (valor, num.repeticiones)
secuencia_codificada.Aniade(iguales_hasta_ahora);
secuencia_codificada.Aniade(actual);

return (secuencia_codificada);
}   

/***********************************************************************/
// Descodifica una secuencia de enteros según el código RLE y devuelve
// otra secuencia de enteros descodificada.
//
// Recibe: secuencia_codificada, la secuencia que se va a descodificar.
// Devuelve: una nueva secuencia, resultado de descodificar según RLE
// la secuencia recibida "secuencia_codificada".

SecuenciaEnteros Descodifica (SecuenciaEnteros secuencia_codificada)
{
// Secuencia resultado de la descodificación

SecuenciaEnteros secuencia_descodificada;

// Registrar el número de elementos de la secuencia codificada.

int tope = secuencia_codificada.TotalUtilizados();

// Ciclo que recorre la secuencia codificada.
// La longitud de la secuencia es par (está formada por parejas) así
// que el número de parejas es justo la mitad del número de elementos.
// Observad que el salto se realiza de 2 en 2 porque en cada iteración
// se procesa una pareja.

for (int pos=0; pos<tope; pos+=2) {

int num_repeticiones = secuencia_codificada.Elemento(pos);
int valor = secuencia_codificada.Elemento(pos+1);

// Cada pareja es (num_repeticiones, valor). Se trata de escribir
// "valor" en la secuencia descodificada "num_repeticiones" veces. 

for (int i=0; i<num_repeticiones; i++)
secuencia_descodificada.Aniade(valor);
}

return (secuencia_descodificada);
}

/***********************************************************************/

};



Esa implementación funciona perfectamente con números enteros, pero a la hora de tener que tener en cuenta que también pueden introducirse caracteres, me confunde. Se me ocurre hacer una clase SecuenciaParejas y la clase SecuenciaEnteros (ya implementada)

Código (cpp) [Seleccionar]
class SecuenciaEnteros
{

private:

static const int TAMANIO = 200; // Número de casillas disponibles

int vector_privado[TAMANIO];

//PRE: 0 <= total_utilizados <= TAMANIO
int total_utilizados; // Número de casillas ocupadas

public:

/***********************************************************************/
// Constructor sin argumentos

SecuenciaEnteros() : total_utilizados(0) {}

/***********************************************************************/
// Métodos de lectura (Get) de los datos individuales

// Devuelve el número de casillas ocupadas
int TotalUtilizados (void)
{
return (total_utilizados);
}

// Devuelve el número de casillas disponibles
int Capacidad (void)
{
return (TAMANIO);
}

/***********************************************************************/
// Añade un elemento al vector.
// Recibe: nuevo, el elemento que se va a añadir.
//
// PRE: total_utilizados < TAMANIO
// La adición se realiza si hay espacio para el nuevo elemento.
// El nuevo elemento se coloca al final del vector.
// Si no hay espacio, no se hace nada.

void Aniade (int nuevo)
{
if (total_utilizados < TAMANIO) {
vector_privado[total_utilizados] = nuevo;
total_utilizados++;
}
}

/***********************************************************************/
// Devuelve el elemento de la casilla "indice"
//
// PRE: 0 <= indice < total_utilizados

int Elemento (int indice)
{
return vector_privado[indice];
}

/***********************************************************************/
// Calcula si dos objetos son iguales: serán iguales si contienen el
// mismo número de elementos, son iguales uno a uno y están en el mismo
// orden.
//
// Recibe: otro, la secuencia con la que se compara el objeto implícito.
// Devuelve: true, si las dos secuencias son iguales; false, en otro caso.

bool EsIgualA (SecuenciaEnteros otro)
{
bool son_iguales;

if (total_utilizados == otro.total_utilizados) {

son_iguales = true;

int pos = 0;
bool sigo_comparando = true;

// Mientras queden por comparar y sigan siendo iguales

while ((pos<total_utilizados) && (sigo_comparando)) {

if (vector_privado[pos] == otro.vector_privado[pos]) {
pos++;
}
else {
sigo_comparando = false;
son_iguales = false;
}

} // while (sigo_comparando)

}
else son_iguales = false; // tienen distinto tamaño

return (son_iguales);
}

/***********************************************************************/
};

/////////////////////////////////////////////////////////////////////////////



Una vez teniendo SecuenciaEnteros y SecuenciaParejas, a la hora de que el usuario vaya a introducir los valores, hacer un if para comprobar si está metiendo letras o números.


¿Alguna ayuda?

¡Gracias!

fran800m

Hace mucho que no toco C, pero si solo se trata de almacenar o leer una secuencia de pares caracter -> número de repeticiones, ¿por qué no creas una estructura y rellenas un array dinámico con instancias de esa estructura? Los números son caracteres, no deberías tener problema.