Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #59 da revista programar. Faz já o download aqui!

ruisousa27

Lista Ligada Dentro De outra

Mensagens Recomendadas

ruisousa27    0
ruisousa27

Boas pessoal, tenho uma duvida num programa que consiste em gerir um parque de estacionamento. Se alguém me conseguir ajudar ficarei muito grato.

Vou tentar ser o mais preciso possível na minha duvida.

Como podem ver no código, a lista "Fila" tem um ponteiro para a lista "linha" (pelo menos era essa a minha intenção).

o objetivo da função "void Fila::ocupa_lugar_fila(char fila, int linha)" é percorrer a lista "fila" até chegar à fila dada por parâmetro e depois de a encontrar, percorrer a lista "linha" até encontrar a lista passada por parâmetro. Assim que encontrar a fila e a linha ocupa esse lugar através da função "void ocupa_lugar_linha(void);"

O que não estou a conseguir fazer, é percorrer a lista "linhas" a partir da lista "filas" visto que esta tem um ponteiro para a lista "linhas" devia ser possivel eu percorrer-la.

As duvidas estão também comentadas no código.

Desde já muito obrigado a todos.

class NoLinha{
public:
NoLinha *next;
string matricula;
tempo entrada;
bool ocupacao;
int linhaindex;

};
class Linha{
NoLinha *init;
public:
//Linha(void);
//~Linha(void);
void ocupa_lugar_linha(void);
void desocupa_lugar_linha(void);
bool mostra_ocupacao_linha(void);
};
//================================================
//
//========== FILA ===============================
class NoFila{
public:
NoFila *next;
Linha *linha; //ponteiro para a lista linha
char filaindex;
};

class Fila{
NoFila *init;
public:
void ocupa_lugar_fila(char,int);

};


void Fila::ocupa_lugar_fila(char fila, int linha){
NoFila *current = this->init;

while (current->filaindex != fila){
current = current->next;
}

while (current->linha != linha){
current->linha.next; // DUVIDA:::como avancar na lista linhas a	 partir da lista filas?
}
current->linha.ocupa_lugar_linha(); //DUVIDA::: como charmar a funcao da lista linhas?

}

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
seuqram    8
seuqram

Fazes o mesmo do que quando percorreste as filas:

NoLinha current_Linha = current->linha;
while (current->linha != linha){
  current_linha = current_linha->next;
}
current_Linha->ocupa_lugar_linha();

Mas isso não vai funcionar a menos que tenhas feito uma função (que não está ai) para inicializares todos os ponteiros "next".

Uma sugestão, e já que estamos em c++. Aprende o que é um vetor e faz tudo de novo.

Editado por seuqram

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
ruisousa27    0
ruisousa27

Fazes o mesmo do que quando percorreste as filas:

NoLinha current_Linha = current->linha;

while (current->linha != linha){

current_linha = current_linha->next;

}

current_Linha->ocupa_lugar_linha();

Mas isso não vai funcionar a menos que tenhas feito uma função (que não está ai) para inicializares todos os ponteiros "next".

Uma sugestão, e já que estamos em c++. Aprende o que é um vetor e faz tudo de novo.

Este programa devido a outros problemas do enunciado é recomendável fazer através de listas ligadas.

Se pudesse ser um bocado mais preciso em relação à função para inicializar os ponteiros "next" eu agradecia, pq não estou a ver muito bem o que é necessário...

Desde já obrigado pela resposta

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
seuqram    8
seuqram

Quando crias isto: Linha *linha_m;

não crias uma bloco de dados que representa essa mesma class mas sim um ponteiro vazio que poderá enventualmente apontar para um bloco desse tipo.

Tens necessáriamente de alocar memória. Podes fazer assim:

linha_m = new Linha;

Mais tarde vais ter que eliminar:

delete linha_m;

Eu não sei como está o resto do teu código, mas se eventualmente não fizeste algo para alocares, como eu disse anteriormente, tens de fazer algo deste genero:

void alocar_Memoria(Fila *fila_p, int Filas, int Linhas)
{
 if(!Filas || !Linhas)return;

 if(fila_p) delete fila_p;
 fila_p = new Fila;

 NoFila **fila = &fila_p->init;
 for(int f = 0; f < Filas; f++)
 {
    *fila = new NoFila;
    *fila->linha = new Linha;

    NoLinha **linha = &(*fila->linha->init);
    for(int l = 0; l < Linhas; l++)
    {
       *linha = new NoLinha;
       linha = &(*linha->next)
    }

    fila = &(*fila->next);
 }
}

(Eu estou a acessar um membro privado da classe Linha e Fila (o ponteiro "init"), o que vai trazer problemas de compilação. Podes meter a função: No(Linha ou Fila) get_Init(void){return init;} nas duas classes para obter esse membro.

Quando o programa acaba, tens de fazer uma função para eliminar o que criaste com o "delete", que se faz de forma semelhante. Percorres os ponteiros todos no range que dizes á função, e depois eleminas.

Ou podes ir a outro leque de alternativas e implementares o "unique_ptr" ou "shared_ptr", que elimina por ti, quando o bloco alocado não estiver a ser apontado por nenhum pointer.

Em alternativa á função de alocar que eu te sugeri, podes no entanto alocar a memória no construtor de cada class NoLinha e NoFila, passando um numero como argumento (o tamanho da fila ou linha), e parar de alocar quando esse numero chegar a 0 (vai diminuindo 1 ao longo de cada construtor).

Para tornar o código mais legivel, podias no entanto meter essas classes (NoFila e NoLinha) como structs, já que os membros são todos públicos.

Editado por seuqram

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
ruisousa27    0
ruisousa27

Quando crias isto: Linha *linha_m;

não crias uma bloco de dados que representa essa mesma class mas sim um ponteiro vazio que poderá enventualmente apontar para um bloco desse tipo.

Tens necessáriamente de alocar memória. Podes fazer assim:

linha_m = new Linha;

Mais tarde vais ter que eliminar:

delete linha_m;

Eu não sei como está o resto do teu código, mas se eventualmente não fizeste algo para alocares, como eu disse anteriormente, tens de fazer algo deste genero:

void alocar_Memoria(Fila *fila_p, int Filas, int Linhas)

{

if(!Filas || !Linhas)return;

if(fila_p) delete fila_p;

fila_p = new Fila;

NoFila **fila = &fila_p->init;

for(int f = 0; f < Filas; f++)

{

*fila = new NoFila;

*fila->linha = new Linha;

NoLinha **linha = &(*fila->linha->init);

for(int l = 0; l < Linhas; l++)

{

*linha = new NoLinha;

linha = &(*linha->next)

}

fila = &(*fila->next);

}

}

(Eu estou a acessar um membro privado da classe Linha e Fila (o ponteiro "init"), o que vai trazer problemas de compilação. Podes meter a função: No(Linha ou Fila) get_Init(void){return init;} nas duas classes para obter esse membro.

Quando o programa acaba, tens de fazer uma função para eliminar o que criaste com o "delete", que se faz de forma semelhante. Percorres os ponteiros todos no range que dizes á função, e depois eleminas.

Ou podes ir a outro leque de alternativas e implementares o "unique_ptr" ou "shared_ptr", que elimina por ti, quando o bloco alocado não estiver a ser apontado por nenhum pointer.

Em alternativa á função de alocar que eu te sugeri, podes no entanto alocar a memória no construtor de cada class NoLinha e NoFila, passando um numero como argumento (o tamanho da fila ou linha), e parar de alocar quando esse numero chegar a 0 (vai diminuindo 1 ao longo de cada construtor).

Para tornar o código mais legivel, podias no entanto meter essas classes (NoFila e NoLinha) como structs, já que os membros são todos públicos.

Já consegui perceber o que preciso de fazer, obrigado pela ajuda prestada ;)

Cumprimentos

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo    1153
HappyHippyHippo

epa .. tanta coisa e a solução bastaria colocar um construtor na classe ...

exemplo

class NoLinha {
 NoLinha() : next(nullptr) {};
}


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
ruisousa27    0
ruisousa27

Boas pessoal,

Ainda no seguimento deste tópico decidi refazer o meu trabalho pois uma das sugestões que aqui me foi dada é muito melhor que a minha maneira anterior de fazer as coisas

Posto isto,o meu código é o seguinte:

class Parque
{
int numero_pisos;
vector <Piso*> pisos;
Piso *primeiro;

public:
Parque(int);
~Parque(void);
bool devolve_ocupacao(int, char, int);

};


Parque::Parque(int a){
numero_pisos = a;
primeiro = pisos[0];
for (int i = 0; i < a; i++){
pisos[i] = new Piso(i, 10, 10); //i e o indice piso
}
}

Parque::~Parque(void){
for (int i = 0; i < numero_pisos; i++){
delete pisos[i];
}
}

bool Parque ::devolve_ocupacao(int piso, char fila, int linha){
Piso aux;
while (true){
if (aux.get_piso() == piso){
aux.devolve_ocupacao_pisos(f,l);
}
//como avançar no vetor aux até chegar ao piso com o índice certo;
}

}

//classe piso:
class Piso{
vector <estacionamento*> lugares;
int id_piso;
Piso *proximo;
public:
Piso();
Piso(int n, int n_linhas, int n_filas);
~Piso();
int get_piso();
bool devolve_ocupacao_pisos(char, int);
};

A minha duvida é: o construtor da classe e o respetivo destrutor está bem feito?

E como é que eu faço para percorrer os vetores? (duvida comentada no código)

cumps,

Editado por ruisousa27

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
seuqram    8
seuqram

Piso *primeiro; /*.........*/ Piso *proximo;

Não faz sentido estares a criar isto na class.

pisos[i] = new Piso(i, 10, 10);

Não existe nenhum espaço reservado para o vetor, por isso, o que tens ai é incorreto.

Tens de fazer uma coisa deste genero

pisos.push_back(new  Piso(i, 10, 10));

Não podes eliminar os elementos do vetor assim

delete pisos[i];

Forma correta:

pisos.erase(pisos.begin())

assim ele vai te eliminar o primeiro membro as vezes que forem necessarias até que o vetor esvazie. (Se eliminares o elemento 0, o elemento 1 passa para o lugar do 0)

//como avançar no vetor aux até chegar ao piso com o índice certo;

Podes fazer um for loop:

for(int i = 0; i < pisos.size(); i++)

e vais verificando os elementos como se faz numa array de pointers:

if(pisos[i]->get_piso() == piso)

Editado por seuqram

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.