Jump to content

Lista de espera com prioridades


Knot
 Share

Recommended Posts

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.

Link to comment
Share on other sites

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  ?

Link to comment
Share on other sites

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...

Link to comment
Share on other sites

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");
}
Link to comment
Share on other sites

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"

Link to comment
Share on other sites

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.  😛

Link to comment
Share on other sites

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 *
Link to comment
Share on other sites

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...

Link to comment
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
 Share

×
×
  • 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.