Departamento de Ciência da Computação - IME - USP

MAC0122 Princípios de Desenvolvimento de Algoritmos

Segundo Semestre de 2012

Quinto Exercício Programa     

Consulta de Filmes

   Listas encadeadas são as estruturas de dados mais importantes do universo
[nada como exagerar um pouco para chamar atenção].

Paulo Feofiloff

 


Objetivos e motivação

    O objetivo desse segundo exercício-programa (EP) é treinar (mais) Recursão, (mais) Registros e structs, (mais) Alocação dinâmica de memória, (mais) Listas encadeadas, Ordenação (algoritmo Quicksort) e um pouco de Busca de palavras em um texto.

    Quem assina TV a cabo tem várias opções para assistir filmes. Porém, poucos são os filmes que realmente valem a pena serem vistos. As sinopses oferecidos pelas empresas pouco ajudam.

    Pois bem, seus problemas acabaram. Neste EP vamos fazer um programa que imprime notas para filmes usando informações disponíveis na Internet!

    Para isso vamos implementar um programa que lê de um (ou mais) arquivo(s) informações sobre filmes e permite fazer operações como consulta, ordenação, inserção e remoção de filmes, etc.

    Um esqueleto para você utilizar como ponto de partida para o EP5 está disponível aqui. Essencialmente, o esqueleto tem a funções de entrada e saída do EP5, inclusive uma função de nome leString que pode ser usada para ler cadeias de caracteres como, por exemplo, nomes de filmes.

 

Arquivo do IMDB com avaliações

    Seu programa irá ler as notas dos filmes de arquivos. Esses arquivos estão no formato utilizado pela The Internet Movie Database (IMDB). O IMDB coleta essas informações a partir da participação de vários espectadores que se dispuseram a dar notas aos filmes.

    Como exemplo, mostramos duas linhas do arquivo:

      0000000133  279506   8.7  Cidade de Deus (2002)
      700000.000     201   1.8  Xuxa Abracadabra (2003)

    A primeira linha indica que 279506 pessoas votaram no filme, a média das notas foi 8,7, o nome do filme é Cidade de Deus e o ano do filme é 2002. Cada nota de um votante é um inteiro de 1 até 10. O string 0000000133 indica a distribuição de votos. Cada caractere representa a porcentagem de votos para cada possível nota, de acordo com a seguinte descrição.

     "." nenhum voto        "3" 30-39% dos votos   "7" 70-79% dos votos
     "0"  1-9%  dos votos   "4" 40-49% dos votos   "8" 80-89% dos votos
     "1" 10-19% dos votos   "5" 50-59% dos votos   "9" 90-99% dos votos
     "2" 20-29% dos votos   "6" 60-69% dos votos   "*" 100%   dos votos
Portanto, no caso de Cidade de Deus, entre 30 a 39% dos votos foram 10, enquanto que entre 70 a 79% dos votos da Xuxa foram 1. Mas como o filme da Xuxa recebeu apenas 201 votos, fica a seu critério confiar ou não nessa nota.

 

Formato do arquivo de entrada

    O arquivo com os dados de entrada tem, além dos dados a serem lidos, várias linhas com comentários que devem ser ignorados. As linhas que devem ser lidas começam com 6 espaços em branco (' ') seguidos de um dígito ('0'..'9') ou do caractere ponto ('.').

    Cada linha com uma avaliação de um filme contém, na ordem,

  1. 6 espaços em branco,
  2. 10 caracteres representando a distribuição dos votos do filme (por exemplo, 0000000133),
  3. um inteiro com o número de votantes (por exemplo, 279506),
  4. um float representa a nota do filme (por exemplo, 8.7),
  5. um string com o nome do filme e (por exemplo, Cidade de Deus),
  6. um inteiro entre parênteses, que é o ano do filme (por exemplo, 2002).

    Para complicar um pouco a vida, às vezes a linha termina com outro par de parênteses com uma das palavras: mini, TV ou V, ou com comentários entre chaves (caracteres '{' e '}'). Essa parte deve ser ignorada.

    Outro problema: às vezes o ano é desconhecido e é representado por "????", como mostra o exemplo abaixo.

      2000001002     107   4.3  "Gigolos" (????)
Vocês não precisam se preocupar muito com isto, já que a função para a leitura desse arquivo é totalmente fornecida a você no já famoso esqueleto.c.

 

Lista de filmes

    Os dados de cada filme devem ser armazenados em uma lista duplamente encadeada tendo a seguinte estrutura.

#define TAMNOME 80

typedef struct filme {
  char  dist[11];
  int   votos;
  float nota;
  char  nome[TAMNOME+1];
  int   ano;
  struct filme *prox; /* ponteiro para a proxima celula */
  struct filme *ant;  /* ponteiro para a celula  anterior */
} Filme;

typedef struct lista {
  Filme *ini; /* ponteiro para a primeira celula da lista de filmes */
  Filme *fim; /* ponteiro para a ultima celula da lista de filmes */
} Lista;

    Os nomes dos filmes devem ser lidos com no máximo 80 caracteres. Nomes mais longos serão truncados. Para manter ponteiros para o início e o fim da lista, usamos uma estrutura do tipo Lista.

    Podem aparecer filmes duplicados no arquivo de entrada. Por exemplo, a seguinte entrada aparece duplicada.

      0000000124   72392   8.8  Casablanca (1942)
      0000000124   72392   8.8  Casablanca (1942)
Somente uma entrada para cada filme deve ser inserida na lista pela função de leitura. Para isto considerarmos que dois filmes são iguais se eles têm a mesma nota, nome e ano.

Assim, devemos observar que os seguintes filmes são diferentes.

      0000000124   72392   8.8  Casablanca (1942)
      4....0..03      11   5.5  Casablanca (1961)
      1.000.0015      36   4.9  Casablanca (2002)
      0.0.021210      60   7.0  Casablanca 50th Anniversary Special: You Must Remember This (1992) (V)
      0000212000      71   5.6  Casablanca Driver (2004)
      2121000000      84   3.4  Casablanca Express (1989)
      3...11.1.2       8   5.4  Casablanca revisitada (1992)
      ...021310.      25   5.9  Casablanca, Casablanca (1985)
      2..111..02      13   5.2  Casablanca, nid d'espions (1963)
      .1...133.1       9   6.3  Casablancais, Les (1999)
      00.1023000      55   6.2  Cirkus Casablanca (1981)
      4.....1..4       7   5.3  Juego sucio en Casablanca (1985)
      0000012211     802   7.0  Night in Casablanca, A (1946)

 

Comportamento do programa

    Nos exemplos, tudo que aparece em vermelho foi digitado pelo usuário. A descrição abaixo serve apenas para você formar uma ideia do comportamento do programa. Para entender melhor, rode o programa executável.

Opções iniciais

    Inicialmente o programa apresenta a seguinte lista de opções ao usuário e pede que digite uma das opções:

======================================================================
  (c) Carregar um arquivo de dados
  (g) Gravar a lista atual em um arquivo
  (i) Inserir um filme
  (m) Mostrar todos os filmes
  (o) Ordenar a lista de filmes
  (p) Procurar a nota de um filme
  (r) Remover um filme
  (t) Mostrar N filmes com nota menor que X e pelo menos V votos
  (u) Mostrar N filmes com nota maior que X e pelo menos V votos
  (x) Sair do programa

Digite uma opcao: 

A leitura de dados pode ser feita várias vezes. A lista de filmes deve conter os filmes de todos os arquivos lidos, sem duplicação.

Carregar um arquivo de dados

    Pergunta ao usuário o nome de uma arquivo de filmes no formato do IMDB descrito anteriormente e carrega esse arquivo e armazena os dados os filmes em uma lista.

======================================================================
  (c) Carregar um arquivo de dados
  (g) Gravar a lista atual em um arquivo
  (i) Inserir um filme
  (m) Mostrar todos os filmes
  (o) Ordenar a lista de filmes
  (p) Procurar a nota de um filme
  (r) Remover um filme
  (t) Mostrar N filmes com nota menor que X e pelo menos V votos
  (u) Mostrar N filmes com nota maior que X e pelo menos V votos
  (x) Sair do programa

Digite uma opcao: c
Digite o nome do arquivo: 03-filmes.list
Nome do arquivo de entrada: 03-filmes.list

======================================================================
  (c) Carregar um arquivo de dados
  (g) Gravar a lista atual em um arquivo
  (i) Inserir um filme
  (m) Mostrar todos os filmes
  (o) Ordenar a lista de filmes
  (p) Procurar a nota de um filme
  (r) Remover um filme
  (t) Mostrar N filmes com nota menor que X e pelo menos V votos
  (u) Mostrar N filmes com nota maior que X e pelo menos V votos
  (x) Sair do programa

Digite uma opcao: m
--------------------------------------------------------------------------------
Adrienne Clarkson Presents: A Tribute to Peppiatt & Aylesworth: Canada's First T (ano 1996):
	 nota  8.7 	      6 votos 	 distribuicao [.....3...6] 
--------------------------------------------------------------------------------
Night of the Day of the Dawn of the Son of the Bride of the Return of the Reveng (ano 2005):
	 nota  2.8 	      5 votos 	 distribuicao [8........2] 
--------------------------------------------------------------------------------
"Alsaciens - ou les deux Mathilde, Les" (ano 1996):
	 nota  4.7 	     19 votos 	 distribuicao [1..0..2103] 
--------------------------------------------------------------------------------
Total de filmes: 3

Gravar a lista atual em um arquivo

    Neste caso é pedido o nome do arquivo em que a lista atual de filmes deve ser gravada.

======================================================================
  (c) Carregar um arquivo de dados
  (g) Gravar a lista atual em um arquivo
  (i) Inserir um filme
  (m) Mostrar todos os filmes
  (o) Ordenar a lista de filmes
  (p) Procurar a nota de um filme
  (r) Remover um filme
  (t) Mostrar N filmes com nota menor que X e pelo menos V votos
  (u) Mostrar N filmes com nota maior que X e pelo menos V votos
  (x) Sair do programa

Digite uma opcao: g
Digite o nome do arquivo: meus-3-filmes-preferidos.txt
Nome do arquivo de saida: meus-3-filmes-preferidos.txt

Inserir um filme

    Pergunta ao usuário informações sobre o novo filme, e o insere na lista.

======================================================================
  (c) Carregar um arquivo de dados
  (g) Gravar a lista atual em um arquivo
  (i) Inserir um filme
  (m) Mostrar todos os filmes
  (o) Ordenar a lista de filmes
  (p) Procurar a nota de um filme
  (r) Remover um filme
  (t) Mostrar N filmes com nota menor que X e pelo menos V votos
  (u) Mostrar N filmes com nota maior que X e pelo menos V votos
  (x) Sair do programa

Digite uma opcao: i       
Digite o nome do filme: The Avengers
Digite o ano: 2012
Digite a nota: 8.4
Digite o numero de votos:  393892         
Digite a distribuicao: 0..0000124 

Filme inserido: 
--------------------------------------------------------------------------------
The Avengers (ano 2012):
	 nota  8.4 	 393892 votos 	 distribuicao [0..0000124] 

Mostrar todos os filmes

    Imprime na tela do computador a lista corrente de filmes. Atenção, essa opção será muuiiittooo útil durante o desenvolvimento do seu programa.

======================================================================
  (c) Carregar um arquivo de dados
  (g) Gravar a lista atual em um arquivo
  (i) Inserir um filme
  (m) Mostrar todos os filmes
  (o) Ordenar a lista de filmes
  (p) Procurar a nota de um filme
  (r) Remover um filme
  (t) Mostrar N filmes com nota menor que X e pelo menos V votos
  (u) Mostrar N filmes com nota maior que X e pelo menos V votos
  (x) Sair do programa

Digite uma opcao: m
--------------------------------------------------------------------------------
Adrienne Clarkson Presents: A Tribute to Peppiatt & Aylesworth: Canada's First T (ano 1996):
	 nota  8.7 	      6 votos 	 distribuicao [.....3...6] 
--------------------------------------------------------------------------------
Night of the Day of the Dawn of the Son of the Bride of the Return of the Reveng (ano 2005):
	 nota  2.8 	      5 votos 	 distribuicao [8........2] 
--------------------------------------------------------------------------------
"Alsaciens - ou les deux Mathilde, Les" (ano 1996):
	 nota  4.7 	     19 votos 	 distribuicao [1..0..2103] 
--------------------------------------------------------------------------------
The Avengers (ano 2012):
	 nota  8.4 	 393892 votos 	 distribuicao [0..0000124] 
--------------------------------------------------------------------------------
Total de filmes: 4

Ordenar a lista de filmes

    Ordena a lista filmes em ordem de nota. Para isto, você deverá escrever no seu programa uma versão do Quicksort para listas encadeadas.

======================================================================
  (c) Carregar um arquivo de dados
  (g) Gravar a lista atual em um arquivo
  (i) Inserir um filme
  (m) Mostrar todos os filmes
  (o) Ordenar a lista de filmes
  (p) Procurar a nota de um filme
  (r) Remover um filme
  (t) Mostrar N filmes com nota menor que X e pelo menos V votos
  (u) Mostrar N filmes com nota maior que X e pelo menos V votos
  (x) Sair do programa

Digite uma opcao: o
======================================================================
  (c) Carregar um arquivo de dados
  (g) Gravar a lista atual em um arquivo
  (i) Inserir um filme
  (m) Mostrar todos os filmes
  (o) Ordenar a lista de filmes
  (p) Procurar a nota de um filme
  (r) Remover um filme
  (t) Mostrar N filmes com nota menor que X e pelo menos V votos
  (u) Mostrar N filmes com nota maior que X e pelo menos V votos
  (x) Sair do programa

Digite uma opcao: m
--------------------------------------------------------------------------------
Adrienne Clarkson Presents: A Tribute to Peppiatt & Aylesworth: Canada's First T (ano 1996):
	 nota  8.7 	      6 votos 	 distribuicao [.....3...6] 
--------------------------------------------------------------------------------
The Avengers (ano 2012):
	 nota  8.4 	 393892 votos 	 distribuicao [0..0000124] 
--------------------------------------------------------------------------------
"Alsaciens - ou les deux Mathilde, Les" (ano 1996):
	 nota  4.7 	     19 votos 	 distribuicao [1..0..2103] 
--------------------------------------------------------------------------------
Night of the Day of the Dawn of the Son of the Bride of the Return of the Reveng (ano 2005):
	 nota  2.8 	      5 votos 	 distribuicao [8........2] 
--------------------------------------------------------------------------------
Total de filmes: 4

Procurar a nota de um filme

    Pergunta ao usuário uma parte do nome ("string"), e exibe um filme de cada vez até que o usuário confirme que encontrou o filme, ou que não haja mais filmes contendo aquela "string".

======================================================================
  (c) Carregar um arquivo de dados
  (g) Gravar a lista atual em um arquivo
  (i) Inserir um filme
  (m) Mostrar todos os filmes
  (o) Ordenar a lista de filmes
  (p) Procurar a nota de um filme
  (r) Remover um filme
  (t) Mostrar N filmes com nota menor que X e pelo menos V votos
  (u) Mostrar N filmes com nota maior que X e pelo menos V votos
  (x) Sair do programa

Digite uma opcao: p
Digite parte do nome a ser procurado: Avengers
--------------------------------------------------------------------------------
The Avengers (ano 2012):
	 nota  8.4 	 393892 votos 	 distribuicao [0..0000124] 
Esse eh o filme procurado? [s/n]: s

Remover um filme

    Faz a procura de um filme e, após a confirmação do usuário, remove o filme da lista.

======================================================================
  (c) Carregar um arquivo de dados
  (g) Gravar a lista atual em um arquivo
  (i) Inserir um filme
  (m) Mostrar todos os filmes
  (o) Ordenar a lista de filmes
  (p) Procurar a nota de um filme
  (r) Remover um filme
  (t) Mostrar N filmes com nota menor que X e pelo menos V votos
  (u) Mostrar N filmes com nota maior que X e pelo menos V votos
  (x) Sair do programa

Digite uma opcao: r
Digite parte do nome a ser procurado: Avengers
--------------------------------------------------------------------------------
The Avengers (ano 2012):
	 nota  8.4 	 393892 votos 	 distribuicao [0..0000124] 
Esse eh o filme procurado? [s/n]: s
======================================================================
  (c) Carregar um arquivo de dados
  (g) Gravar a lista atual em um arquivo
  (i) Inserir um filme
  (m) Mostrar todos os filmes
  (o) Ordenar a lista de filmes
  (p) Procurar a nota de um filme
  (r) Remover um filme
  (t) Mostrar N filmes com nota menor que X e pelo menos V votos
  (u) Mostrar N filmes com nota maior que X e pelo menos V votos
  (x) Sair do programa

Digite uma opcao: m
--------------------------------------------------------------------------------
Adrienne Clarkson Presents: A Tribute to Peppiatt & Aylesworth: Canada's First T (ano 1996):
	 nota  8.7 	      6 votos 	 distribuicao [.....3...6] 
--------------------------------------------------------------------------------
"Alsaciens - ou les deux Mathilde, Les" (ano 1996):
	 nota  4.7 	     19 votos 	 distribuicao [1..0..2103] 
--------------------------------------------------------------------------------
Night of the Day of the Dawn of the Son of the Bride of the Return of the Reveng (ano 2005):
	 nota  2.8 	      5 votos 	 distribuicao [8........2] 
--------------------------------------------------------------------------------
Total de filmes: 3

Mostrar N filmes com nota menor que X e pelo menos V votos

    Pergunta ao usuário uma nota máxima X, uma quantidade N, de filmes e um número V de votos e exibe na tela os N melhores filmes com nota menor ou igual X e com pelo menos V votos. Essa opção só deve ser utilizada quando a lista estiver ordenada.

======================================================================
  (c) Carregar um arquivo de dados
  (g) Gravar a lista atual em um arquivo
  (i) Inserir um filme
  (m) Mostrar todos os filmes
  (o) Ordenar a lista de filmes
  (p) Procurar a nota de um filme
  (r) Remover um filme
  (t) Mostrar N filmes com nota menor que X e pelo menos V votos
  (u) Mostrar N filmes com nota maior que X e pelo menos V votos
  (x) Sair do programa

Digite uma opcao: t
Qual o numero de filmes a ser mostrado: 3
Qual a nota maxima: 4.6
Qual o numero minimo de votos: 3
--------------------------------------------------------------------------------
Night of the Day of the Dawn of the Son of the Bride of the Return of the Reveng (ano 2005):
	 nota  2.8 	      5 votos 	 distribuicao [8........2] 
--------------------------------------------------------------------------------
Esses sao os 1 melhores filmes com nota menor que  4.6 e pelo menos 3 votos.

Mostrar N filmes com nota maior que X e pelo menos V votos

    Pergunta ao usuário uma nota mínima X, uma quantidade N de filmes e um número V de votos e exibe na tela os N piores filmes com nota maior ou igual a X e com pelo menos V votos. Essa opção só deve ser utilizada quando a lista estiver ordenada.

======================================================================
  (c) Carregar um arquivo de dados
  (g) Gravar a lista atual em um arquivo
  (i) Inserir um filme
  (m) Mostrar todos os filmes
  (o) Ordenar a lista de filmes
  (p) Procurar a nota de um filme
  (r) Remover um filme
  (t) Mostrar N filmes com nota menor que X e pelo menos V votos
  (u) Mostrar N filmes com nota maior que X e pelo menos V votos
  (x) Sair do programa

Digite uma opcao: u
Qual o numero de filmes a ser mostrado: 3
Qual a nota minima: 4.5
Qual o numero minimo de votos: 4
--------------------------------------------------------------------------------
"Alsaciens - ou les deux Mathilde, Les" (ano 1996):
	 nota  4.7 	     19 votos 	 distribuicao [1..0..2103] 
--------------------------------------------------------------------------------
Adrienne Clarkson Presents: A Tribute to Peppiatt & Aylesworth: Canada's First T (ano 1996):
	 nota  8.7 	      6 votos 	 distribuicao [.....3...6] 
--------------------------------------------------------------------------------
Esses sao os 2 piores filmes com nota maior que  4.5 e pelo menos 4 votos.

Sair do programa

    Termina a execução do programa.

======================================================================
  (c) Carregar um arquivo de dados
  (g) Gravar a lista atual em um arquivo
  (i) Inserir um filme
  (m) Mostrar todos os filmes
  (o) Ordenar a lista de filmes
  (p) Procurar a nota de um filme
  (r) Remover um filme
  (t) Mostrar N filmes com nota menor que X e pelo menos V votos
  (u) Mostrar N filmes com nota maior que X e pelo menos V votos
  (x) Sair do programa

Digite uma opcao: x

Mensagem dos nossos patrocinadores:

Would you *______really* want to get on a non-stop flight?
		-- George Carlin

 

Arquivos Fornecidos

    Arquivos de entrada no formato do IMDB, com extensão .list, podem ser obtidos deste diretório. Inclusive o arquivo imdb-ratings.list com as notas de mais de 380 mil filmes. O executável gasta um tempo razoável para carregar essa lista de filmes. Recomendamos que você não use o arquivo imdb-ratings.list para testar o seu programa. Os demais arquivos .list fornecidos podem ajudar você durante o desenvolvimento, mas recomendamos que você monte outros arquivos para teste (contendo os seus filmes favoritos, ou desfavoritos, ou com nomes iguais ou bizarros etc). Caso o tamanho dos arquivos permitir, compartilhe eles conosco via fórum.

    Os arquivos ep5.exe e ep5-linux são exemplos de executáveis fornecidos para o Windows e Linux. Muitas dúvidas de como deve ser o comportamento do programa em algumas situações podem ser resolvidas experimentando esses programas.

    O arquivo esqueleto.c inclui, entre outras, funções para fazer a leitura do arquivo e construção da lista duplamente encadeada Você pode utilizar o que quiser do arquivo esqueleto.c. Você pode modificar o que quiser, apenas os protótipos das funções pedidas a seguir não podem ser modificados e precisam ser, obrigatoriamente, utilizadas no seu programa.

 

Funções que você deve implementar

    Além da função main, você deve implementar as três funções descritas a seguir.

    A função

int achaFilme(Lista *lista, Filme *f);
recebe um ponteiro lista de uma lista de filmes e um ponteito f para um filme. A função devolve TRUE se o filme está na lista e devolve FALSE em caso contrário. Para isto considerarmos que dois filmes são iguais se eles têm a mesma nota, nome e ano. O ponteito lista contém o endereço de para uma célula do tipo Lista que contém os endereços ini e fim do início e fim de uma lista duplamente encadeada de filmes.

    A função achaFilme precisa ser implementada para que a função insereFilme passe a funcionar corretamente.

    A opção (o) permite a ordenação da lista de filmes, que ao final deve ficar em ordem decrescentes de notas. Para a ordenação você deve implementar o algoritmo Quicksort adaptado para listas encadeadas. O protótipo da função deve ser o seguinte:

void quickSort(Lista *lista);

    A opção (p) e (r) permitem a procura de um filme usando parte do nome. Para isso, seu programa deve perguntar ao usuário a parte do nome a ser procurada e, como é possível encontrar vários filmes contendo uma certa palavra, o usuário deve confirmar se o filme foi achado ou não. Rode o executável para entender melhor esse procedimento.

    Para achar um filme com nome contendo o "string" definido pelo usuário, você deve implementar a função achaPalavra com o seguinte protótipo:

int achaPalavra(unsigned char *pal, int tPal, unsigned char *texto, int codeexto);
que recebe um string pal com tamanho tPal, e outro string texto com tamanho codeexto. A função deve devolver TRUE caso a sequência pal occorra em texto, e FALSE em caso contrário.

    As opções (t) e (u) podem ser utilizadas para mostrar o N melhores ou piores filmes em relação a uma nota X e com pelo menos V votos. Por exemplo, para um filme entrar na lista dos 250 melhores filmes do IMDB, além de uma boa nota, ele precisa receber pelo menos 25.000 votos. Você pode definir o protótipo que desejar para essas funções, desde que o seu comportamento seja compatível com o do executável. Recomendamos que ela seja baseada na função mostraLista contida no esqueleto.

 

 


Last modified: Fri Nov 9 09:33:07 BRST 2012