#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
typedef int bool;
enum { false, true };
// elemento da lista
typedef struct estr {
char letra;
struct estr *prox;
} NO;
typedef struct {
NO *inicio;
} LISTA;
void inicializarLista(LISTA *l) {
l->inicio = NULL;
}
//início das funções de teste
void criarLista(LISTA *l, char plvr[]) {
NO *ult = NULL;
int i;
for (i
= 0; i
< strlen(plvr
); i
++) { NO
*novo
= (NO
*) malloc(sizeof(NO
)); novo->letra = plvr[i];
novo->prox = NULL;
if (ult) {
ult->prox = novo;
} else {
l->inicio = novo;
}
ult = novo;
}
}
void imprimirLista(LISTA *l) {
NO *p = l->inicio;
while(p) {
p = p->prox;
}
}
LISTA* clonarLista(LISTA* l){
LISTA
* resp
= malloc(sizeof(LISTA
));
NO *corrente = l->inicio;
NO *anterior = NULL; //utilizar um nó anterior para ligar os vários elementos
while(corrente){ //agora com corrente em vez de l
NO
*novo
= (NO
*) malloc(sizeof(NO
)); novo->letra = corrente->letra;
novo->prox = NULL;
if (anterior == NULL){ //se é o primeiro fica no inicio da nova lista
resp->inicio = novo;
}
else { //se não é o primeiro liga o anterior a este pelo prox
anterior->prox = corrente;
}
anterior = novo;
corrente = corrente->prox;
}
return resp;
}
void inverter(LISTA* resp){
NO* atual = resp->inicio;
/*redefinir a lista para começar vazia, sendo que o ponteiro atual ainda
aponta para os seus elementos*/
resp->inicio = NULL;
while (atual->prox != NULL){ //enquanto houver nós
NO* corrente = atual; //guardar nó corrente
atual = atual->prox; //avançar nó atual
corrente->prox = resp->inicio; //fazer o prox do corrente ser o 1 da lista invertida
resp->inicio = corrente; //o inicio passa a ser este ultimo nó
}
}
//fim das funções de teste
void inverterNvs(NO* elemento, NO* anteriorAoElemento, NO* fim) {
if (elemento != fim) {
inverterNvs(elemento->prox, elemento, fim);
}
elemento->prox = anteriorAoElemento;
}
bool verificaSequencia(NO* dado) {
if (dado->letra != 'a' && dado->letra != 'e' && dado->letra != 'i' && dado->letra != 'o' && dado->letra != 'u'){
return true;
}
else{
return false;
}
}
void decodificar(LISTA* resp) {
NO* pNv = NULL; // Primeira não-vogal encontrada.
NO* ultNv = NULL; // Última não-vogal encontrada.
NO* atual = resp->inicio; // Ponteiro para percorrer a lista.
NO* anterior = NULL;
/* Laço para percorrer toda lista. */
while (atual != NULL) {
/* Enquanto atual apontar para uma não-vogal. */
if (verificaSequencia(atual)) {
/* Salva o primeiro caso encontrado de não-vogal. */
pNv = atual;
/* Procura na lista o último caso de não-vogal. */
while (atual->prox != NULL && verificaSequencia(atual->prox)) {
atual = atual->prox;
}
/* Quando a próxima letra for uma vogal, então foi atingido o fim da sequência de não-vogais. */
ultNv = atual;
/* Se existir uma sequência de não-vogais, ou seja, pNv e ultNv não apontarem para o mesmo elemento, então a troca de posições deve ser efetuada. */
if (pNv != ultNv) {
/* Chama uma função recursiva para efetuar a troca de posições sem precisar criar uma nova lista. */
NO* proximoOriginal = ultNv->prox;
inverterNvs(pNv->prox, pNv, ultNv);
pNv->prox = proximoOriginal;
if (anterior == NULL){
resp->inicio = ultNv;
}
else {
anterior->prox = ultNv;
}
atual = pNv;
}
}
/* Move para o próximo elemento. */
anterior = atual;
atual = atual->prox;
}
}
int main() {
LISTA l;
inicializarLista(&l);
//A partir de um vetor de char uma lista foi gerada para testes
char palavra[] = "monstros legais"; //Resultado esperado: "mortsnol segais"
criarLista(&l, palavra);
LISTA* resp = clonarLista(&l); //obter o clonado
//inverter(resp); //inverter o clonado
//imprimirLista(resp); //imprimir o clonado
decodificar(resp);
imprimirLista(resp);
return 0;
}