Advertisement
Guest User

Untitled

a guest
May 31st, 2016
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.69 KB | None | 0 0
  1. /*
  2.  ============================================================================
  3. Curso: Ciência da Computação
  4. Turma: 4NA - 4º Período
  5. Disciplina: Estrutura de Dados II
  6. Professor: Rafael Nunes
  7. Alunos: Vitor Iyomassa, João Gouveia, Frederico Perpétuo
  8.  ============================================================================
  9.  */
  10.  
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <time.h>
  14. #include <math.h>
  15. #include <string.h>
  16. #define TAMANHO_MAXIMO_NOME_SOLDADOS 20
  17.  
  18. typedef struct lista TLista;
  19.  
  20. struct lista {
  21.     char nomeSoldado[TAMANHO_MAXIMO_NOME_SOLDADOS];
  22.     TLista* prox;
  23. };
  24.  
  25. //protótipos
  26. TLista* inicializaListaSoldados();
  27. TLista* insereSoldadoNoCirc(TLista*, char*);
  28. void imprimeSoldadosCirc(TLista*);
  29. int verificaCircVazio(TLista*);
  30. int verificaNumeroSoldados(TLista*);
  31. TLista* sorteiaSoldado(TLista*);
  32. TLista* excluiSoldadoDoCirc(TLista*, char*);
  33. int sorteiaN(void);
  34. void executaJosephus(TLista*, TLista*, int);
  35.  
  36. //funções de entrada de dados
  37.  
  38. TLista* lerNomeSoldadosArquivoTxt(TLista*, char*);
  39. TLista* lerNome20Soldados(TLista*);
  40. TLista* lerNomeUsuariosPeloUsuario(TLista*);
  41.  
  42. int main(void) {
  43.     setbuf(stdout, NULL);
  44.  
  45.     TLista* listaSoldados = inicializaListaSoldados();
  46.     TLista* soldadoSorteado = inicializaListaSoldados();
  47.     int n = sorteiaN();
  48.     int op;
  49.  
  50.     do{
  51.         printf("#*#*#*#*#*#*#*#*#* O Problema de Josephus (Tenenbaum, 1989) #*#*#*#*#*#*#*#*#*\n");
  52.         printf("Escolha uma opcao abaixo para a entrada de dados: \n");
  53.         printf("1 - Ler os nomes do arquivo nomes.txt\n");
  54.         printf("2 - Ler os nomes de 20 soldados por uma funcao\n");
  55.         printf("3 - Entrar com os nomes dos soldados manualmente\n");
  56.  
  57.         printf("opcao: ");
  58.         scanf("%d", &op);
  59.         if(op < 1 || op > 3){
  60.             printf("\nOpcao invalida!\n");
  61.         }
  62.     }while(op < 1 || op > 3);
  63.  
  64.     if(op == 1){
  65.         printf("AVISO: Essa funcao deve ser usada somente no linux,\n"
  66.                 " pois em nossos testes ela nao se comportou bem no\n"
  67.                 " windows caso esteja testando no linux, favor ir no\n "
  68.                 "codigo e descomentar a linha 69 e excluir a 70!!!\n");
  69.         //listaSoldados = lerNomeSoldadosArquivoTxt(listaSoldados, "nomes.txt");
  70.         exit(1);
  71.     }else if(op == 2){
  72.         listaSoldados = lerNome20Soldados(listaSoldados);
  73.     }else{
  74.         fflush(stdin);
  75.         listaSoldados = lerNomeUsuariosPeloUsuario(listaSoldados);
  76.     }
  77.  
  78.     soldadoSorteado = sorteiaSoldado(listaSoldados);
  79.  
  80.     executaJosephus(listaSoldados, soldadoSorteado, n);
  81.  
  82.     printf("\nExecucao finalizada!\n");
  83.     return EXIT_SUCCESS;
  84. }
  85.  
  86. /**
  87.  * Função que inicializa a lista para que a mesma nao seja um ponteiro apontando pro nada
  88.  */
  89. TLista* inicializaListaSoldados(){
  90.     return NULL;
  91. }
  92.  
  93. /**
  94.  * Função que insere um soldado em uma lista
  95.  */
  96. TLista* insereSoldadoNoCirc(TLista* lista, char* nome){
  97.     TLista* aux, *aux2;
  98.     aux = (TLista*) malloc(sizeof(TLista));
  99.     strcpy(aux->nomeSoldado, nome);
  100.  
  101.     if (verificaCircVazio(lista)) {
  102.         aux->prox = aux;
  103.         lista = aux;
  104.     } else {
  105.         aux->prox = lista;
  106.         aux2 = lista;
  107.         do {
  108.             aux2 = aux2->prox;
  109.         } while (aux2->prox != lista);
  110.         aux2->prox = aux;
  111.     }
  112.     return lista;
  113. }
  114.  
  115. /**
  116.  * Função que imprime a lista de soldados no console
  117.  */
  118.  
  119. void imprimeSoldadosCirc(TLista* lista) {
  120.     TLista* aux;
  121.     if (verificaCircVazio(lista)) {
  122.         printf("\nLista vazia!\n");
  123.     } else {
  124.         aux = lista;
  125.         do {
  126.             if (aux->prox != lista) {
  127.                 TLista* excluiSoldadoDoCirc(TLista*, char*);
  128.                 printf("%s - ", aux->nomeSoldado);
  129.             } else {
  130.                 printf("%s", aux->nomeSoldado);
  131.             }
  132.             aux = aux->prox;
  133.         } while (aux != lista);
  134.     }
  135. }
  136.  
  137. /**
  138.  * Função que verifica se a lista de soldados esta vazia
  139.  */
  140.  
  141. int verificaCircVazio(TLista* lista){
  142.     return !lista;
  143. }
  144.  
  145. /**
  146.  * Função que verifica a quantidade de soldados na lista
  147.  */
  148. int verificaNumeroSoldados(TLista* lista){
  149.     TLista* aux = lista;
  150.     int cont = 0;
  151.  
  152.     if (aux){
  153.         do {
  154.             cont++;
  155.             aux = aux->prox;
  156.         } while (aux != lista);
  157.     }
  158.  
  159.     return cont;
  160. }
  161.  
  162. /*
  163.  * Função que sorteia um soldado na lista
  164.  */
  165.  
  166. TLista* sorteiaSoldado(TLista* lista) {
  167.     int tamanhoLista = verificaNumeroSoldados(lista);
  168.     int indiceSoldadoSorteado;
  169.     int aux = 0;
  170.     TLista* soldadoSorteado = lista;
  171.  
  172.     srand((unsigned) time(NULL));
  173.  
  174.     if (lista != NULL) {
  175.         do {
  176.             indiceSoldadoSorteado = rand()
  177.                     % (int) pow(10, ((int) log10(tamanhoLista)) + 1);
  178.         } while (indiceSoldadoSorteado >= tamanhoLista);
  179.  
  180.         do{
  181.             soldadoSorteado = soldadoSorteado->prox;
  182.             aux++;
  183.         }while(aux != indiceSoldadoSorteado);
  184.         return soldadoSorteado;
  185.     }
  186.     return NULL;
  187. }
  188.  
  189. /**
  190.  * Função que exclui um soldado da lista
  191.  */
  192.  
  193. TLista* excluiSoldadoDoCirc(TLista* lista, char* nomeMorto){
  194.     TLista* aux = lista;
  195.     TLista* soldadoExcluido = inicializaListaSoldados();
  196.     do{
  197.         aux = aux->prox;
  198.     }while(strcmp(aux->prox->nomeSoldado, nomeMorto) != 0);
  199.     soldadoExcluido = aux->prox;
  200.     aux->prox = aux->prox->prox;
  201.     if(soldadoExcluido == lista){
  202.         lista = aux;
  203.     }
  204.     free(soldadoExcluido);
  205.     return lista;
  206. }
  207.  
  208. /**
  209.  * Função que sorteia um n, que por sua vez discrimina de quanto sera o numero de saltos do algoritimo
  210.  */
  211.  
  212. int sorteiaN(void){
  213.     srand((unsigned) time(NULL));
  214.     int n;
  215.     do{
  216.         n = rand()%10;
  217.     }while(n < 2);
  218.     return n;
  219. }
  220.  
  221. /**
  222.  * Função que executa o algoritimo de Josephus
  223.  */
  224.  
  225. void executaJosephus(TLista* listaSoldados, TLista* soldadoSorteado, int n){
  226.     int iteracao = 0;
  227.     int aux = 1;
  228.     TLista* aux2 = NULL;
  229.     TLista* soldadoAtual = soldadoSorteado;
  230.     TLista* sobrevivente = inicializaListaSoldados();
  231.  
  232.     printf("Execucao do Algoritimo");
  233.     printf("\n=================================\n");
  234.     printf("\nDados recebidos:\n");
  235.     printf("Lista de soldados: ");
  236.     imprimeSoldadosCirc(listaSoldados);
  237.     printf("\nSoldado Sorteado = %s", soldadoSorteado->nomeSoldado);
  238.     printf("\nN: %i", n);
  239.     printf("\n=================================\n");
  240.     while(verificaNumeroSoldados(listaSoldados) != 1){
  241.         iteracao++;
  242.         printf("iteracao %i: \n", iteracao);
  243.         while(aux < n){
  244.             soldadoAtual = soldadoAtual->prox;
  245.             aux++;
  246.         }
  247.         aux = 1;
  248.         aux2 = soldadoAtual->prox;
  249.         printf("\nSoldado excluido: %s\n", soldadoAtual->nomeSoldado);
  250.         if(listaSoldados == soldadoAtual){
  251.             listaSoldados = listaSoldados->prox;
  252.         }
  253.         soldadoAtual = excluiSoldadoDoCirc(listaSoldados, soldadoAtual->nomeSoldado);
  254.         soldadoAtual = aux2;
  255.         printf("\nnum soldados = %i\n", verificaNumeroSoldados(listaSoldados));
  256.     }
  257.     printf("\nsoldado sobrevivente: %s", listaSoldados->nomeSoldado);
  258. }
  259.  
  260. /**
  261.  * Função que busca os nomes dos soldados no arquivo. Essa função funcionou
  262.  * bem no linux, no windows não apresentou estabilidade
  263.  */
  264.  
  265. TLista* lerNomeSoldadosArquivoTxt(TLista* lista, char* path){
  266.     char* nome;
  267.     FILE *file;
  268.     file = fopen(path, "rt");
  269.     if (file) {
  270.         while (fgets(nome,150, file)) {
  271.             nome[strlen(nome)-1] = '\0';
  272.             lista = insereSoldadoNoCirc(lista, nome);
  273.         }
  274.         fclose(file);
  275.     }else{
  276.         printf("\nAquivo nomes.txt nao encontrado\n");
  277.     }
  278.  
  279.     return lista;
  280. }
  281.  
  282. /**
  283.  * Função que coloca 20 soldados numa lista
  284.  */
  285. TLista* lerNome20Soldados(TLista* lista){
  286.     if(verificaCircVazio(lista)){
  287.         lista = insereSoldadoNoCirc(lista, "Joao");
  288.         lista = insereSoldadoNoCirc(lista, "Fred");
  289.         lista = insereSoldadoNoCirc(lista, "Vitor");
  290.         lista = insereSoldadoNoCirc(lista, "Xulambs");
  291.         lista = insereSoldadoNoCirc(lista, "Rafael");
  292.         lista = insereSoldadoNoCirc(lista, "Ze");
  293.         lista = insereSoldadoNoCirc(lista, "Dilma");
  294.         lista = insereSoldadoNoCirc(lista, "Aecio");
  295.         lista = insereSoldadoNoCirc(lista, "Renan");
  296.         lista = insereSoldadoNoCirc(lista, "Delcidio");
  297.         lista = insereSoldadoNoCirc(lista, "Faustao");
  298.         lista = insereSoldadoNoCirc(lista, "Hebe");
  299.         lista = insereSoldadoNoCirc(lista, "Gugu");
  300.         lista = insereSoldadoNoCirc(lista, "Silvio");
  301.         lista = insereSoldadoNoCirc(lista, "Santos");
  302.         lista = insereSoldadoNoCirc(lista, "Liminha");
  303.         lista = insereSoldadoNoCirc(lista, "Eneas");
  304.         lista = insereSoldadoNoCirc(lista, "Bolsonaro");
  305.         lista = insereSoldadoNoCirc(lista, "Jean");
  306.         lista = insereSoldadoNoCirc(lista, "Willys");
  307.     }
  308.     return lista;
  309. }
  310.  
  311. /**
  312.  * Função que le o nome dos soldados por teclado
  313.  */
  314.  
  315. TLista* lerNomeUsuariosPeloUsuario(TLista* listaSoldados){
  316.     char resp;
  317.     char nome[TAMANHO_MAXIMO_NOME_SOLDADOS];
  318.     if(verificaCircVazio(listaSoldados)){
  319.         do {
  320.             printf("Entre com o nome do soldado: ");
  321.             fflush(stdin);
  322.             scanf("%s", &nome);
  323.             listaSoldados = insereSoldadoNoCirc(listaSoldados, nome);
  324.             do {
  325.                 printf("Deseja inserir mais um soldado? (S/N): ");
  326.                 setbuf(stdin, NULL);
  327.                 scanf("%c", &resp);
  328.                 if (resp != 'S' && resp != 's' && resp != 'N' && resp != 'n') {
  329.                     printf("Resposta inválida\n");
  330.                 }
  331.  
  332.             } while (resp != 'S' && resp != 's' && resp != 'N' && resp != 'n');
  333.  
  334.         } while (resp != 'N' && resp != 'n');
  335.     }
  336.  
  337.     return listaSoldados;
  338. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement