Jump to content
Knot

Lista de espera com prioridades

Recommended Posts

Knot

Boas!

Tenho um trabalho de estruturas de dados para fazer, em que temos de criar um sistema do género que há nos CTT, lojas do cidadão, etc, em que tiramos uma senha para determinado balcão de atendimento e esperamos a nossa vez.

A minha duvida e principal problema é que temos os utentes prioritários (idosos, grávidas,etc) que passam à frente dos utentes normais.

A ideia seria criar uma fila de espera com este aspecto:

utente1 prioritário

utente2 prioritário

utente1 normal

utente2 normal

Ou seja eu aqui uso os nomes utentes prioritarios e normais apenas para se perceber melhor, mas é o valor 1 ou 2 guardado em v->prioridade que vai determinar se o utente é normal ou prioritario.

Estrutura

typedef struct utente {
int prioridade; /* a */
char utente[30];
time_t tempo_entrada; /* e */
time_t tempo_saida; /* f */
int tempo_atendimento; /* g */
struct utente *seg;
} UTENTE, *UUTENTE;

Função para indicar se o utente é prioritario ou normal (1=normal, 2= prioritário)

void ler_utente(UUTENTE v) {
printf("\n[Dados do utente]\n");
fflush(stdin);
printf("\nutente:");
gets(v->utente);
fflush(stdin);
printf("\nPrioridade:");
scanf("%d",&v->prioridade);
}

Função para inserir o utente na fila:

void inserir_utente(UUTENTE v, UUTENTE *cabeca, UUTENTE *cauda) 
{
if(v->prioridade==1)//se for utente normal
{
            v->seg = NULL; // elemento a inserir será sempre o novo último

          if (!*cabeca) // se fila vazia
             *cabeca = *cauda = v;
         else {
                (*cauda)->seg = v; //o ex-ultimo aponta para novo ultimo
               *cauda = v; // cauda aponta para novo ultimo
               }
/* Registar tempo de entrada */
v->tempo_entrada = time(NULL);
}
else//Se for utente prioritário
	{	
		printf("Ola estou no else!");
		if (!*cabeca) // se fila vazia
		{*cabeca = v;
		v->seg = NULL;
		v->tempo_entrada = time(NULL);}
		else{
		v->seg=*cabeca;
*cabeca=v;
v->tempo_entrada = time(NULL);}
	}
}

- Se inserir apenas utentes normais o código de inserir_utente funciona ok.

- Se inserir utentes normais e depois prioritários, os prioritários ficam em primeiro mas da seguinte ordem:

utente2 prioritario

utente1 prioritário

utente1 normal

utente2normal

- Se inserir prioritários apenas eles são inseridos, mas tal como atrás ficam com a ordem inversa.

- Se inserir prioritários e depois tentar inserir normais o programa crasha.

Alguém me pode ajudar?

É que depois o chamar o utente é sempre chamar o primeiro da fila e remover também é sempre o primeiro da fila, logo nestas duas questões já não há grande problema, não consigo é organizar a lista de espera ficando os prioritários à frente e os normais depois.

Share this post


Link to post
Share on other sites
luis7

Faz todo o sentido quando inseres o 2 prioritário ele ficar no topo da lista de espera, porque é o que estás a fazer. Ao inserir um prioritário tens de o colocar no fim de todos os prioritários e não no início!

Share this post


Link to post
Share on other sites
Knot

Sim é isso mesmo, mas não sei como fazer isso...

Eu queria que chegasse à cabeça e se não houvesse nenhum prioritario inseria, senao percorria todos até encontrar o primeiro normal e inseria antes do normal.

Share this post


Link to post
Share on other sites
RSFalcon7

porque não fazes duas listas (First In First Out) , uma de prioritários e outra dos normais?

só removes dos normais quando a lista dos prioritários esta vazia

Share this post


Link to post
Share on other sites
Knot

porque não fazes duas listas (First In First Out) , uma de prioritários e outra dos normais?

só removes dos normais quando a lista dos prioritários esta vazia

É uma boa ideia, também já tinha pensado nisso assim por alto...

Mas assim preciso de 2 estruturas, 2 funções para inserir e alocar as 2 listas, certo?

Share this post


Link to post
Share on other sites
luis7

Acho que só precisas de um estrutura e de uma função.

Na função para inserir, consoante a prioridade inseres na lista pretendida!

Share this post


Link to post
Share on other sites
RSFalcon7

sim, eu fazia qqr coisa como isso:

typedef struct _list {
    time_t horaChegada;
    time_t horaInicioAtendimento;
    char * nomeUtente;

    struct _list *prox;
} ListNodo,*List;

typedef struct _priorityList {
    List filaPrioritaria;
    List filaNormal;
}PriorityList;

int pListAdd(PriorityList l,char *nomeUtente, int prioridade)    {
    if(prioridade == 0)    {
        List *aux = &(l.filaPrioritaria);
        for(; (*aux)->prox != NULL ; aux = (*aux)->prox);
        (*aux)->prox = (List) malloc(sizeof(ListNodo));
        (*aux)->prox->nomeUtente = nomeUtente;
        (*aux)->prox->horaChegada = time(NULL);
        (*aux)->prox->prox = NULL;

    }else if(prioridade == 1) {
        // add na lista prioritaria
    }
}

ListNodo pListPop(PriorityList l) {
    if (l.filaPrioritaria != NULL) {
        //remove da lista prioritaria
    } else {
        // remove da lista prioritaria
    }
    result->horaInicioAtendimento = time(NULL);

    return result;
}

acho q me alonguei  🤔

Share this post


Link to post
Share on other sites
Knot

Alongaste nada, obrigado pela ajuda, mas está alguma coisa mal naquele for da função pListAdd, acho que em vez de aux = (*aux)->prox é (*aux) = (*aux)->prox.

Já tentei correr isto mas não estou a conseguir.

Fiz a função main (básica, só mesmo para testar o funcionamento):

void main()
{
PriorityList l;
char nomeUtente;
int prioridade=0;

printf("\nintroduza a prioridade\n");
scanf("%d",prioridade);
printf("\nintroduza o nome do utente\n");//depois será atribuído um numero de senha automático em vez de nome!
scanf("%s",nomeUtente);
pListAdd(l,&nomeUtente, prioridade);
}

Mas dá-me sempre erro que o "l" e "nomeUtente" não foram inicializados e que a função pListAdd devia retornar um valor...

Share this post


Link to post
Share on other sites
Knot

Fiz umas pequenas alterações mas não me parece funcionar...

int pListAdd(PriorityList l,char *nomeUtente, int prioridade)    {
    printf("passei aqui 1");//imprime
if(prioridade == 0)    {
        List *aux = &(l.filaPrioritaria);
	for(; (*aux)->prox != NULL ; *aux = (*aux)->prox);
	(*aux)->prox = (List) malloc(sizeof(ListNodo));
        (*aux)->prox->nomeUtente = nomeUtente;
        (*aux)->prox->horaChegada = time(NULL);
        (*aux)->prox->prox = NULL;
	printf("Sou normal");//nunca imprime
    }else if(prioridade == 1) {
     List *aux = &(l.filaNormal);
        for(;(*aux)->prox != NULL ; *aux = (*aux)->prox);
	(*aux)->prox = (List) malloc(sizeof(ListNodo));
        (*aux)->prox->nomeUtente = nomeUtente;
        (*aux)->prox->horaChegada = time(NULL);
        (*aux)->prox->prox = NULL;
	printf("Sou prioritário");//nunca imprime
    }
printf("passei aqui 2");//imprime
return 0;//meti só mesmo para o programa ''rolar''
}

void main()
{
PriorityList *a=(PriorityList*) malloc (sizeof(PriorityList));
char nomeUtente[10];
int prioridade=(int) malloc(10);

fflush(stdin);
printf("\nintroduza o nome do utente\n");
scanf("%s",nomeUtente);

fflush(stdin);
printf("\nintroduza a prioridade\n");
scanf("%d",prioridade);

pListAdd(*a,nomeUtente, prioridade);

printf("passei aqui 3");//imprime
system("pause");
}

Share this post


Link to post
Share on other sites
RSFalcon7

Onde tem isso:

for(; (*aux)->prox != NULL ; *aux = (*aux)->prox);

ao colocares o * aí estás a apagar/perder a lista, não a percorre-la.

se te faz confusão percorrer a lista com duplo apontador, usa apontador para o seguinte...

ele só não imprime o "Sou normal" ou "Sou prioritário" quando não dás a prioridade 0 ou 1

acho q ao invés de perguntar ao utilizador a prioridade devias ter tipo "retirar senha prioritária" e "retirar senha normal"

Share this post


Link to post
Share on other sites
Knot

Pois, mas como tu dizes não funciona e dá-me logo erro :

error C2440: '=' : cannot convert from '_list *' to 'List *'

Eu estive foi a ver o seguinte código:

http://www.indiastudychannel.com/resources/13012-C-Program-priority-queue-using-linked-list.aspx

Só que neste código não consigo inicializar ''utentes_a_frente" e "utentes_totais", pois o utentes_totais em cada fila ia dar-me os numeros das senhas.  :P

Share this post


Link to post
Share on other sites
RSFalcon7

sobre este código, não me lembro de nada com tantos bugs desde o meu exame de Programação Imperativa :wallbash:

sobre o erro, há aí uma confusão nos apontadores...

o aux é um apontador para lista

a lista é um apontador para nodo

o que deveria estar lá é: o aux toma valor do endereço do campo prox do valor apontado por ele, ou seja:

aux = &((*aux)->prox) 

porque:

*aux             :: Lista
(*aux)->prox     :: Lista (strcut _list *)
&((*aux)->prox)  :: Lista * 
aux              :: Lista *

Share this post


Link to post
Share on other sites
Knot

Continuo a não conseguir correr isto. Já testei com int prioridade, char prioridade, mas os ciclos for nunca são corridos, nunca é imprimido nada que esteja dentro dos "ifs"

E faço tipo printf("%s",prioridade) (usando char) e imprime-me os valores 0 e 1 conforme eu os coloque e mesmo tendo if(prioridade=='0') ou if(prioridade=="0") ou if (prioridade==0) nada me funciona.

Já meti na função main directamente int prioritario=0; em vez de pedir para ser introduzido o valor 0 ou 1 e nunca funciona...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.