Mudanças entre as edições de "PRG29003: Introdução a Filas"

De MediaWiki do Campus São José
Ir para navegação Ir para pesquisar
 
(11 revisões intermediárias pelo mesmo usuário não estão sendo mostradas)
Linha 30: Linha 30:
  
  
Nesta primeira etapa da disciplina, o estudo de filas se dará com o uso de uma fila já implementada. A [http://tele.sj.ifsc.edu.br/~msobral/prg2/Prg2.zip biblioteca Prglib] oferece implementações para as estruturas de dados que são o assunto da disciplina.  A declaração da Fila nessa biblioteca é esta (note que ela é declarada como um [[Introdução_C++#Templates|template]]):
+
Nesta primeira etapa da disciplina, o estudo de filas se dará com o uso de uma fila já implementada. A [https://pt.wikipedia.org/wiki/Standard_Template_Library biblioteca STL (Standard Template Library)] oferece implementações para as estruturas de dados que são o assunto da disciplina.  A fila disponibilizada nessa biblioteca se chama [http://www.cplusplus.com/reference/queue/queue/ queue] (que significa ''fila'' em inglẽs), e suas operações básicas são estas:
 
+
* [http://www.cplusplus.com/reference/queue/queue/push/ push]: enfileira um dado
<syntaxhighlight lang=c>
+
* [http://www.cplusplus.com/reference/queue/queue/pop/ pop]: desenfileira um dado (descarta-o)
template <typename T> class fila {
+
* [http://www.cplusplus.com/reference/queue/queue/front/ front]: retorna o dado que está na frente da fila
public:
+
* [http://www.cplusplus.com/reference/queue/queue/back/ back]: retorna o dado que está no fim da fila (último dado enfileirado)
    // construtor: cria fila com capacidade N
+
* [http://www.cplusplus.com/reference/queue/queue/size/ size]: retorna o comprimento da fila (quantos dados estão armazenados)
    fila(unsigned int N);
+
* [http://www.cplusplus.com/reference/queue/queue/empty/ empty]: retorna true se fila estiver vazia, e false caso contrário
   
 
    // construtor: cria fila que é cópia da fila "orig"
 
    fila(const fila<T>& orig);
 
   
 
    // destrutor
 
    virtual ~fila();
 
   
 
    // operador de atribuição: torna esta fila uma cópia da "outra" fila
 
    fila<T>& operator=(const fila<T> & outra);
 
   
 
    // enfileira um dado
 
    void enfileira(const T & algo);
 
   
 
    // desenfileira um dado
 
    T desenfileira();
 
   
 
    // retorna uma referência ao dado que está no início da fila
 
    const T & frente() const;
 
   
 
    // testa se fila está vazia
 
    bool vazia() const;
 
 
 
    // testa se fila está cheia
 
    bool cheia() const;
 
   
 
    // retorna a quantidade de dados armazenados
 
    unsigned int comprimento() const;
 
   
 
    // retorna a capacidade da fila (quantos dados cabem)
 
    unsigned int capacidade() const;
 
   
 
    // expande a capacidade da fila para o novo valor "N"
 
    void expande(unsigned int N);
 
   
 
    // remove todos os dados da fila
 
    void esvazia();
 
};
 
</syntaxhighlight>''Arquivo libs/fila.h''
 
  
  
Linha 82: Linha 44:
 
#include <iostream>
 
#include <iostream>
 
#include <string>
 
#include <string>
#include "prglib.h"
+
#include <queue>
  
 
using namespace std;
 
using namespace std;
  
 
int main() {
 
int main() {
   // uma fila com capacidade de armazenar 20 inteiros
+
   // uma fila que armazena números inteiros
   prglib::fila<int> numeros(20);
+
   queue<int> numeros;
  
   // uma fila com capacidade de armazenar 20 string
+
   // uma fila que armazena string
   prglib::fila<string> coisas(20);
+
   queue<string> coisas;
  
   numeros.enfileira(6);
+
  // push_back adiciona um dado no fim da fila
   numeros.enfileira(8);
+
   numeros.push(6);
   numeros.enfileira(10);
+
   numeros.push(8);
   numeros.enfileira(12);
+
   numeros.push(10);
 +
   numeros.push(12);
  
   coisas.enfileira("banana");
+
   coisas.push("banana");
   coisas.enfileira("graviola");
+
   coisas.push("graviola");
   coisas.enfileira("sapoti");
+
   coisas.push("sapoti");
   coisas.enfileira("siriguela");
+
   coisas.push("siriguela");
   coisas.enfileira("caju");
+
   coisas.push("caju");
  
   cout << "Fila de numeros tem comprimento=" << numeros.comprimento() << endl;
+
   cout << "Fila de numeros tem comprimento=" << numeros.size() << endl;
   cout << "Fila de string tem comprimento=" << coisas.comprimento() << endl;
+
   cout << "Fila de string tem comprimento=" << coisas.size() << endl;
  
   while (not numeros.vazia()) {
+
   while (! numeros.empty()) {
     cout << "Numero: " << numeros.desenfileira() << endl;
+
     cout << "Numero: " << numeros.front() << endl;
 +
    numeros.pop(); // desenfileira um número
 
   }
 
   }
  
   while (not coisas.vazia()) {
+
   while (! coisas.empty()) {
     cout << "String: " << coisas.desenfileira() << endl;
+
     cout << "String: " << coisas.front() << endl;
 +
    coisas.pop(); // desenfileira uma string
 
   }
 
   }
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 +
 +
= Repositório de exercícios =
 +
 +
Todos os exercícios estão disponíveis no [http://github.com GitHub], um serviço de armazenamento e compartilhamento de projetos de software. Cada exercício está no formato de um projeto CLion, e pode ser obtido com este procedimento:
 +
# Execute o CLion e siga uma destas duas instruções:
 +
## Se aparecer uma tela de abertura com opções de criação de um novo projeto, clique na opção ''Check out from Version Control''.
 +
## Se o CLion abrir com um projeto já existente (ou se ele já estava em execução com algum outro projeto), clique no menu ''VCS->Git->Clone''.
 +
# Em ambos os casos, aparecerá uma pequena janela com título ''Clone Repository''
 +
# Copie a URL (link) do exercício para a caixa de texto ''URL'', e em seguida clique em ''Clone''
 +
# O projeto CLion será baixado do GitHub e criado em seu CLion
  
 
= Exercícios =
 
= Exercícios =
 
* [[Introdução_C%2B%2B]]
 
* [[Introdução_C%2B%2B]]
 +
 +
O seguinte programa ilustra o uso de fila para armazenar dados que estão em espera por processamento.
 +
 +
* '''Objetivo:''' Escrever um programa que copie um conjunto de arquivos para dentro de um determinado diretório.
 +
** ''Descrição:'' O programa a ser escrito deve receber como dados de entrada o diretório de destino e os nomes dos arquivos a serem copiados. O diretório de destino deve ser lido do teclado, seguido então dos nomes dos arquivos. Quando o usuário digitar uma linha vazia (pressionar somente ENTER), então o programa faz a cópia dos arquivos.
  
  
# Resolva os seguintes exercícios sobre filas:
+
Antes de escrever esse programa, resolva estes exercícios para se familiarizar com filas. Observe que eles estão disponibilizados no [http://github.com GitHub] (ver [[PRG29003:_Introdu%C3%A7%C3%A3o_a_Filas#Reposit.C3.B3rio_de_exerc.C3.ADcios|instruções de acesso]]):
#* [https://moodle.sj.ifsc.edu.br/mod/vpl/view.php?id=3160 Enfileirador de caracteres]
+
# [https://github.com/IFSC-Engtelecom-Prg2/Fila_Enfileira_Caracteres Enfileirador de caracteres]
#* [https://moodle.sj.ifsc.edu.br/mod/vpl/view.php?id=3161 Fila de substrings]
+
# [https://github.com/IFSC-Engtelecom-Prg2/Fila_Separa_Substrings Fila de substrings]
#* [https://moodle.sj.ifsc.edu.br/mod/vpl/view.php?id=3214 Filtro de fila]
+
# [https://github.com/IFSC-Engtelecom-Prg2/Fila_Separador_Maiusculas_Minusculas Separador de maiúsculas e minúsculas]
#* [https://moodle.sj.ifsc.edu.br/mod/vpl/view.php?id=3163 Concatenador de filas]
+
<!--# [https://moodle.sj.ifsc.edu.br/mod/vpl/view.php?id=5570 Enfileirador de caracteres]
 +
# [https://moodle.sj.ifsc.edu.br/mod/vpl/view.php?id=5571 Fila de substrings]
 +
# [https://moodle.sj.ifsc.edu.br/mod/vpl/view.php?id=5573 Filtro de fila]
 +
# [https://moodle.sj.ifsc.edu.br/mod/vpl/view.php?id=5572 Concatenador de filas]
 +
-->

Edição atual tal como às 18h32min de 26 de fevereiro de 2020

Próxima aula


Uma fila é uma estrutura de dados linear. Os dados nela armazenados são dispostos por ordem de entrada, formando uma sequência. A retirada de dados também respeita a ordem de chegada, assim os dados saem de uma fila na mesma ordem em que entraram. Esse comportamento é denominado FIFO (First In First Out).


PRG2-Queueof.gif
Uma fila real ... (fonte da imagem)

Existem várias aplicações para filas em programas. Tipicamente, quando algum dado precisa esperar para ser processado, ele pode ser armazenado em uma fila. Alguns exemplos:

  • Eventos em um ambiente gráfico de um sistema operacional, tais como clique de mouse, tecla pressionada, e apresentação de elementos gráficos, são processados na ordem em que ocorrem. Esses eventos são armazenados em uma fila de espera.
  • Sistemas operacionais costumam manter uma fila de processos que estão aptos a executar, ou que estão em espera pela ocorrência de um evento (lembrem disso lá na disciplina de Sistemas Operacionais).
  • Programas de computador, incluindo o sistema operacional, precisam usualmente oferecer uma área de espera para mensagens entre processos, subsistemas ou mesmo aplicações de rede. Essa área de espera, por vezes chamada de buffer, costuma ser implementada na forma de uma fila.
  • Existem algoritmos específicos que dependem de filas para funcionarem. Um exemplo é o algoritmo de busca em largura (breadth-first).


No caso mais geral, uma fila funciona como mostrado na figura a seguir:

Prg-queue.png


Uma fila é acessada com três operações principais (existem outras):

  • enfileiramento: usada para acrescentar um dado ao final da fila
  • desenfileiramento: usada para retirar um dado do início da fila
  • frente: usada para acessar o dado que está no início da fila, porém sem retirá-lo


Nesta primeira etapa da disciplina, o estudo de filas se dará com o uso de uma fila já implementada. A biblioteca STL (Standard Template Library) oferece implementações para as estruturas de dados que são o assunto da disciplina. A fila disponibilizada nessa biblioteca se chama queue (que significa fila em inglẽs), e suas operações básicas são estas:

  • push: enfileira um dado
  • pop: desenfileira um dado (descarta-o)
  • front: retorna o dado que está na frente da fila
  • back: retorna o dado que está no fim da fila (último dado enfileirado)
  • size: retorna o comprimento da fila (quantos dados estão armazenados)
  • empty: retorna true se fila estiver vazia, e false caso contrário


... e um exemplo de uso é mostrado a seguir:

#include <iostream>
#include <string>
#include <queue>

using namespace std;

int main() {
  // uma fila que armazena números inteiros
  queue<int> numeros;

  // uma fila que armazena string
  queue<string> coisas;

  // push_back adiciona um dado no fim da fila
  numeros.push(6);
  numeros.push(8);
  numeros.push(10);
  numeros.push(12);

  coisas.push("banana");
  coisas.push("graviola");
  coisas.push("sapoti");
  coisas.push("siriguela");
  coisas.push("caju");

  cout << "Fila de numeros tem comprimento=" << numeros.size() << endl;
  cout << "Fila de string tem comprimento=" << coisas.size() << endl;

  while (! numeros.empty()) {
    cout << "Numero: " << numeros.front() << endl;
    numeros.pop(); // desenfileira um número
  }

  while (! coisas.empty()) {
    cout << "String: " << coisas.front() << endl;
    coisas.pop(); // desenfileira uma string
  }
}


Repositório de exercícios

Todos os exercícios estão disponíveis no GitHub, um serviço de armazenamento e compartilhamento de projetos de software. Cada exercício está no formato de um projeto CLion, e pode ser obtido com este procedimento:

  1. Execute o CLion e siga uma destas duas instruções:
    1. Se aparecer uma tela de abertura com opções de criação de um novo projeto, clique na opção Check out from Version Control.
    2. Se o CLion abrir com um projeto já existente (ou se ele já estava em execução com algum outro projeto), clique no menu VCS->Git->Clone.
  2. Em ambos os casos, aparecerá uma pequena janela com título Clone Repository
  3. Copie a URL (link) do exercício para a caixa de texto URL, e em seguida clique em Clone
  4. O projeto CLion será baixado do GitHub e criado em seu CLion

Exercícios

O seguinte programa ilustra o uso de fila para armazenar dados que estão em espera por processamento.

  • Objetivo: Escrever um programa que copie um conjunto de arquivos para dentro de um determinado diretório.
    • Descrição: O programa a ser escrito deve receber como dados de entrada o diretório de destino e os nomes dos arquivos a serem copiados. O diretório de destino deve ser lido do teclado, seguido então dos nomes dos arquivos. Quando o usuário digitar uma linha vazia (pressionar somente ENTER), então o programa faz a cópia dos arquivos.


Antes de escrever esse programa, resolva estes exercícios para se familiarizar com filas. Observe que eles estão disponibilizados no GitHub (ver instruções de acesso):

  1. Enfileirador de caracteres
  2. Fila de substrings
  3. Separador de maiúsculas e minúsculas