Computação e Programação 2006/07 Aula Prática 1 (Laboratório 1) Introdução ao sistema MATLAB Esta aula prática tem como objectivo a apresentação do sistema MATLAB e algumas das suas capacidades. Começamos por ver o MATLAB como uma máquina de calcular gráfica com inúmeras funcionalidades. Para começar a utilizar o sistema MATLAB em ambiente Windows basta invocar o programa a partir do seu ícone. (no Desktop ou em StartPrograms) O espaço de trabalho do MATLAB divide-se em várias janelas. Para já concentramo-nos na janela de comandos. Nesta janela introduzimos as expressões a avaliar (input) e visualizamos os resultados (output). As expressões são introduzidas na janela de comandos na linha assinalada por >> e avaliados premindo enter. Comece por invocar o MATLAB Avalie a expressão 1+1 1+1 Começamos por utilizar o MATLAB como uma simples calculadora. Avalie as expressões 123+456*789 (123-456)*789 8/4 8\4 2^2*2 2^(2*2) O MATLAB possui também funções trigonométricas e reconhece números complexos. Avalie as expressões pi pi/4 Nota: As funções trigonométricas do MATLAB aceitam apenas valores em radianos. sin(pi/6)+cos(pi/3) tan(pi/4) cos(pi/4)\sin(4\pi) atan(1) cosh(0) asinh(0) Ao lidar com números complexos o MATLAB aceita indistintamente i e j como unidade imaginária. i j 1+3i + 3+ j i*i 3+4i * 1+2i (3+4i) * (1+2i) abs(3+4i) conj(1+2j) real(5+7i) imag(5+7i) 2*angle(i) Estão também disponíveis as funções exp, log e log10. exp(1) log(exp(3)) log10(10) Vamos ver agora como podemos utilizar o MATLAB para desenhar o gráfico de uma função. Para desenhar o gráfico precisamos de dois vectores, uma para as abcissas e outro para as ordenadas. No final invocamos o comando plot. O vector das abcissas é construido com a função linspace. Esta função gera um vector com 100 pontos igualmente espaçados entre os dois valores dados. A informação relativa a uma função pode ser obtida escrevendo help seguido do nome da função. Obtenha informação acerca da função linspace help linspace Desenhe o gráfico da função seno no intervalo [-10,10] x1=linspace(-10,10); y1=sin(x1); plot(x1,y1) Desenhe o gráfico da função arco tangente no intervalo [-10,10] x2=linspace(-10,10); y2=atan(x2); plot(x2,y2) Sobreponha os dois gráficos plot(x1,y1,x2,y2) É importante reparar que em alguns dos comandos anteriores usámos ";" no final. O ponto e vírgula no final de uma expressão diz ao MATLAB para avaliar a expressão e não apresentar o resultado. Vejamos o que acontecia se não usássemos o ponto e vírgula. linspace(-10,10) O MATLAB também desenha gráficos 3D. Experimente introduzir no MATLAB os seguintes exemplos x3=-10:.5:10; y3=x3; [u,v]=meshgrid(x3,y3); r=sqrt(u.^2+v.^2)+eps; z3=sin(r)./r; mesh(x3,y3,z3) surf(x3,y3,z3) Programar em MATLAB Agora vamos criar, editar e avaliar ficheiros MATLAB (M-Files ou guiões). Estes ficheiros permitem a submissão de uma sequência de comandos de uma só vez. O MATLAB avalia sequencialmente os comandos de um ficheiro como se tivessem sido introduzidos directamente na janela de comandos. À esquerda da janela de comandos encontra-se a janela Current Directory (caso não esteja, torne-a visível indo na barra de ferramentas a View Current Directory). A partir desta janela temos acesso a ficheiros .m que estejam na directoria indicada. O MATLAB só procura ficheiros em directorias que tenham sido previamente adicionadas à lista path. Por isso, é importante começar por acrescentar a directoria onde vamos trabalhar a esta lista. Tal é possível seleccionando File Set Path na barra de ferramentas. Para criar um ficheiro basta seleccionar na barra de ferramentas do MATLAB a opção FileNewM-file; em alternativa, carregar em Ctrl-N produz o mesmo efeito. Crie um novo ficheiro com os comandos que se seguem. % %Programa que soma os 50 primeiros naturais % I=1; R=0; while (I<=50) R=R+I; I=I+1; end R Grave o código acima com o nome soma.m e de seguida avalie-o escrevendo soma na janela de comandos. Qual o resultado? O que aconteceu? Adicione a pasta onde guardou o ficheiro ao path do MATLAB. Tente avaliar de novo o ficheiro soma.m. Nota: Para facilitar a leitura, o código deverá estar bem dividido e correctamente identado. É importante que consigamos ler o nosso código e que os outros também o consigam. É igualmente importante comentar o código. Modifique o programa de modo a somar os primeiros 25 naturais e avalie novamente. Experimente retirar o ";" do final do comando que incrementa a variável I (I=I+1;), grave e volte a avaliar, agora somando até 7. O que é que acontece? Não é cómodo estar sempre a alterar o ficheiro quando queremos alterar o valor de N; podemos tornar o programa interactivo. Recorra agora às funções input e fprintf e modifique o programa que soma os N primeiros naturais de modo a pedir interactivamente N e a devolver o resultado. Nota: O novo programa é de certo modo mais geral; uma vez que o comentário deve reflectir a funcionalidade do programa, altere-o. Desenvolva um programa que resolva equações de segundo grau. O programa deverá pedir ao utilizador os coeficientes do polinómio e devolver as soluções, caso existam, ou um aviso, caso não haja soluções. Expressões Booleanas Uma expressão booleana é uma expressão que quando avaliada retorna um valor lógico. Em MATLAB os valores lógicos true e false são representados por 1 e 0, respectivamente. Experimente os seguintes exemplos, tentando prever antecipadamente qual o resultado da avaliação de cada expressão. 2 < 3 (8+5) ~= 13 a= (1==1) & (2==2) & (3==4) b= (0 <= -10) | (sin(pi/2)==1) ~b ~b & ~a Os resultados obtidos estão de acordo com o esperado? Matrizes Crie duas matrizes M e N com dimensão 3x3. Por exemplo: M=[1 -1 0;1 1 0;0 0 1] N=[1 2 3;4 5 6;7 8 9] Calcule M+N, M-N e M*N M+N M-N Crie a matriz identidade ID de dimensão 3. Calcule ID*N e ID.*N. ID=[1 0 0;0 1 0;0 0 1] ID*N ID.*N Qual a diferença entre * e .* ? Por analogia, como deve proceder para dividir matrizes elemento a elemento? Como multiplicar uma matriz por um escalar? Experimente com as matrizes M e N e com outras matrizes à sua escolha. Tente multiplicar duas matrizes não compatíveis e observe o que acontece. O MATLAB também disponibiliza funções para resolver sistemas lineares. A solução do sistema linear Ax=b é dada por x=A-1b. Vejamos um exemplo: O sistema linear x + 2 y + 3 z = 366 4 x + 5 y + 6 z = 804 7 x + 8 y = 351 é representado através de uma matriz e um vector. A=[1 2 3;4 5 6;7 8 0] b=[366;804;351] Logo a solução do sistema é x=inv(A)*b Podemos verificar que x é realmente a solução: A*x Tente resolver os sistemas Mx=u e Ny=u onde u é o vector [1; 2; 3]. Verifique e comente os resultados que obteve. u=[1; 2; 3] x=inv(M)*u M*x y=inv(N)*u N*y Crie um ficheiro que quando avaliado gera uma matriz com n linhas e m colunas em que todos os elementos são x. Os parâmetros n, m e x devem ser pedidos interactivamente. Sugestão: use a função ones. Aula Prática 2 Programação imperativa sobre números 1. Defina a função Contadivisores que recebe como argumento um número natural e devolve o número de divisores desse número. 2. Defina a função PrimoQ que recebe como argumento um número natural e devolve verdadeiro se esse número é primo e falso caso contrário. 3. Defina a função Somaprimos que recebe como argumento um número natural N e devolve a soma dos números primos até N. 4. Defina a função Mdifpconsec que recebe como argumento um natural N e devolve a maior diferença entre dois números primos consecutivos até N. 5. Defina a função Mdc que recebe como argumento dois números naturais e que calcula o máximo divisor comum desses dois números, usando o algoritmo de Euclides. 6. Defina a função Contaperfeitos que recebe como argumento um número natural N e que devolve o número de números perfeitos até N. Um número perfeito é tal que a soma dos seus divisores próprios é igual ao próprio número. Por exemplo, 6 é um número perfeito: os divisores próprios de 6 são {3,2,1} e 3+2+1=6. 7. Defina a função Quadrados que recebe como argumento um número natural N e devolve um vector com os quadrados perfeitos que existem entre 1 e N. 8. Defina a função QuadradosInv que recebe como argumento um número natural N e devolve um vector com os quadrados perfeitos que existem entre N e 1. 9. *Defina a função PrimAlg que recebe como argumento um número natural N e devolve o primeiro algarismo da representação decimal de N. 10. *Defina a função Potencia que recebe como argumento um algarismo K (diferente de 0) e devolve o menor natural N tal que 2^N começa por K. Aula Prática 3 Programação imperativa sobre vectores 1. Programação imperativa sobre vectores 1.1 Defina a função MembroQ que dado um número N e um vector V de números devolve verdadeiro se N pertence a V e falso caso contrário. 1.2 Defina a função Ocorrencias que dado um número N e um vector V conta quantas vezes N ocorre em V. 1.3 Defina a função PosMax que dado um vector V devolve a soma dos índices das posições onde o máximo de V ocorre. 1.4 Defina uma função que dado um vector V e um número N devolve um triplo [A,B,C] tal que A é o número de elementos de V maiores que N, B é o número de elementos de V iguais a N e C é o número de elementos menores que N. 1.5 Defina a função Junta que recebe dois vectores V e W e devolve um vector com os elementos de V seguidos dos elementos de W. 1.6 Defina uma função CarPrimos que recebe um vector V e devolve um vector com 1 nas posições onde V contém um número primo e 0 nas restantes. 1.7 Defina a função Compmsuccresc que recebe como argumento um vector de inteiros e devolve o comprimento da maior sucessão estritamente crecente que ocorre no vector. 1.8 Desenvolva uma função f em MATLAB que recebe como argumento um vector de números inteiros, percorre elemento a elemento o vector dado recorrendo a um ciclo while e calcula o par [x,y] tal que x é o produto das posições pares em que ocorrem elementos pares e y é o menor desses elementos (o produto de 0 elementos é 1 e caso não ocorram números pares no vector y deve ser 0). 1.9 Desenvolva uma função f em MATLAB que recebe como argumento um vector de números inteiros, percorre elemento a elemento o vector dado recorrendo a um ciclo while e calcula o par [x,y] tal que x é o número de elementos que são iguais às posições onde ocorrem e y é a primeira dessas posições (caso não exista nenhum número igual à posição onde ocorre y deve ser 0). 1.10 Desenvolva uma função f em MATLAB que recebe como argumento um vector de números inteiros, percorre elemento a elemento o vector dado recorrendo a um ciclo while e calcula o vector do mesmo comprimento em que cada posição tem o elemento do vector dado, desde que o módulo da diferença para o elemento seguinte (caso exista) seja par, e 0 nas outras posições. 1.11 Desenvolva uma função f em MATLAB que recebe como argumento um vector de números inteiros, percorre elemento a elemento o vector dado recorrendo a um ciclo while e calcula o vector do mesmo comprimento com 1 nas posições onde ocorrem quadrados perfeitos e 0 nas outras posições. 2. Estudo de uma função Sejam X=[x1,...,xn] e Y=[y1,...,yn] dois vectores, tais que f(xi)=yi para alguma função f. Assuma que o vector X está ordenado. 2.1 Defina a função Maximo que calcula o máximo da função f, para a representação discreta da função. 2.2 Defina a função Monotonia que devolve 1 se a função f é crescente, –1 se é decrescente e 0 caso contrário, para a representação discreta da função. 2.3 Defina a função Tvm que calcula a taxa de variação média de f em cada intervalo. Esta função deverá devolver um vector de comprimento n-1 em que na i-ésima posição do vector ocorre a tvm de f no intervalo [xi,xi+1]. Aula Prática 4 Programação imperativa sobre matrizes 1. Defina a função Mediamatriz que recebe como argumento uma matriz e devolve a média dos seus elementos. No caso da matriz vazia devolve uma mensagem de erro. 2. Defina a função IgualmatrizQ que recebe como argumento duas matrizes de igual dimensão e devolve verdadeiro se ambas as matrizes são iguais elemento a elemento e falso caso contrário. 3. Defina a função MenormatrizQ que recebe como argumento duas matrizes M1 e M2 de igual dimensão e devolve verdadeiro se todos os elementos da primeira matriz são menores que os elementos na mesma posição da segunda matriz, i.e., M1<M2 se para todo i,j M1(i,j)<M2(i,j). 4. Defina a função Pimatriz que recebe como argumento duas matrizes M1 e M2 de igual dimensão e calcula a soma dos M1(i,j)*M2(i,j) para todo i e todo o j. 5. Defina a função Matrizdiagonal que recebe como argumento um vector V de comprimento L e devolve a matriz LxL em que na diagonal principal ocorrem os elementos de V e nas restantes posições ocorrem zeros. 6. Defina a função Colunasnm que recebe como argumento uma matriz NxM e devolve um vector de dimensão M em que na i-ésima posição ocorre 1 se na i-ésima coluna ocorre um elemento maior que N*M e 0 caso contrário. 7. Defina a função Linhapar que recebe como argumento um vector de inteiros e devolve verdadeiro se a soma dos elementos é par e falso caso contrário. Generalize esta função de modo a receber como argumento uma matriz e a devolver um vector em que na i-ésima posição ocorre 1 se a linha satisfizer Linhapar e 0 caso contrário. 8. Defina a função Triangsupinf que recebe como argumento uma matriz quadrada e devolve 1 se esta for triangular superior, 2 se for triangular inferior, 3 se for triangular superior e inferior (ou seja, se for matriz diagonal) e 0 caso contrário. Aula Prática 5 Programação recursiva 1. Defina a função SomaNatR que recebe como argumento um número natural N e devolve a soma de todos os naturais até N. 2. Defina a função MdcR que recebe como argumento dois números naturais e devolve o seu máximo divisor comum, calculado através do algoritmo de Euclides. 3. Defina a função ContaperfeitosR que recebe como argumento um número natural N e que devolve o número de números perfeitos até N. 4. Defina a função PrimAlgR que recebe como argumento um número natural e devolve o primeiro algarismo na sua representação decimal. 5. Defina a função TresNMaisUmR que recebe como argumento um número natural e devolve o número de iterações da função x if (x par) then x/2 else 3x+1 necessárias para atingir o valor 1. 6. Defina a função MembroQR que recebe como argumento um vector e um número e devolve verdadeiro se o número ocorre no vector e falso caso contrário. 7. Defina a função OcorrenciasR que dado um vector e um número conta quantas vezes o número ocorre no vector. 8. Defina a função MediamatrizR que recebe como argumento uma matriz e devolve a média dos seus elementos. 9. Defina a função PrefixoR que recebe como argumento dois vectores U e V e devolve verdadeiro se U é prefixo de V e falso caso contrário. 10. Defina a função Pesquisabin que recebe como argumento um vector V de números ordenado de forma crescente e um elemento X, e que retorna verdadeiro se X pertence a V e falso caso contrário. Aula Prática 6 Laboratório - Programação em F 3. Programação imperativa em F 3.1. Escreva um programa contadivisores que recebe interactivamente um número natural e apresenta no ecrã o número de divisores desse número. 3.2. Escreva um programa contaprimos que recebe do utilizador um número natural N e apresenta no ecrã o número de números primos até N. Comece por definir uma função auxiliar primoq que pode usar no programa principal. (Relembre a inclusão de funções auxiliares nos programas em F.) 3.3. Escreva um programa fresolve que recebe do utilizador os coeficientes de um polinómio do segundo grau e que apresenta no ecrã as raízes reais desse polinómio, caso existam; caso o polinómio não possua raízes reais, o programa deverá avisar o utilizador. 3.4. Escreva um programa mdc que recebe interactivamente dois números naturais e que calcula o máximo divisor comum desses dois números usando o algoritmo de Euclides, apresentando-o de seguida no ecrã. 4. Debugging de programas É indispensável que saibamos perceber porque é que o nosso programa não compila correctamente. Na grande maioria das vezes basta ler com atenção os erros gerados durante a compilação (mal sucedida). Devemos ter sempre atenção aos erros pela ordem em que são gerados, pois pode haver uma interdependência entre eles e apenas os primeiros serem realmente erros. 4.1. Copie para a pasta aula5 os ficheiros disponíveis a partir da página da cadeira, que contêm alguns erros típicos. Tente compilá-los e observe atentamente as mensagens de erro. Corrija os programas de modo a que compilem sem erros (só assim é que o executável é gerado). program erros1 integer :: x, i, y print *,"Introduza um numero" read *, x do i=1,x r=r+i end print *," A soma ate",x,"e:",r end erros1 program erros2 integer :: x, y, z print *,"Introduza um numero" read *,x print *,"O quadrado e",f(x) print *,"Introduza um numero" read *,y print *,"O cubo e",g(y,z) contains function f(x) result(y) integer :: x integer :: y y=X**2 end f subroutine g(x,y) integer, intent(in) :: x, y y=x**3 end g end program erros2 Aula Prática 7 Programação em F 5. Programação imperativa sobre vectores 1.12 Defina a função MembroQ que dado um número N e um vector V de números devolve verdadeiro se N pertence a V e falso caso contrário. 1.13 Defina a função Ocorrencias que dado um número N e um vector V conta quantas vezes N ocorre em V. 1.14 Defina a função PosMax que dado um vector V devolve a soma dos índices das posições onde o máximo de V ocorre. 1.15 Defina uma função que dado um vector V e um número N devolve um triplo [A,B,C] tal que A é o número de elementos de V maiores que N, B é o número de elementos de V iguais a N e C é o número de elementos menores que N. 1.16 Defina a função Junta que recebe dois vectores V e W e devolve um vector com os elementos de V seguidos dos elementos de W. 1.17 Defina uma função CarPrimos que recebe um vector V e devolve um vector com 1 nas posições onde V contém um número primo e 0 nas restantes. 1.18 Defina a função Compmsuccresc que recebe como argumento um vector de inteiros e devolve o comprimento da maior sucessão estritamente crecente que ocorre no vector. 6. Programação imperativa sobre matrizes 2.1 Defina a função Mediamatriz que recebe como argumento uma matriz e devolve a média dos seus elementos. 2.2 Defina uma função IgualmatrizQ que recebe como argumento duas matrizes de igual dimensão e devolve verdadeiro se ambas as matrizes são iguais elemento a elemento e falso caso contrário. 2.3 Defina a função MenormatrizQ que recebe como argumento duas matrizes M1 e M2 de igual dimensão e devolve verdadeiro se todos os elementos da primeira matriz são menores que os elementos na mesma posição da segunda matriz, i.e., M1<M2 se para todo i,j M1(i,j)<M2(i,j). 2.4 Defina a função Pimatriz que recebe como argumento duas matrizes M1 e M2 de igual dimensão e calcula a soma dos M1(i,j)*M2(i,j) para todo i e todo o j. 2.5 Defina a função Matrizdiagonal que recebe como argumento um vector V de comprimento L e devolve a matriz LxL em que na diagonal principal ocorrem os elementos de V e nas restantes posições ocorrem zeros. 2.6 Defina a função Colunasnm que recebe como argumento uma matriz NxM e devolve um vector de dimensão M em que na i-ésima posição ocorre 1 se na i-ésima coluna ocorre um elemento maior que N*M e 0 caso contrário. 2.7 Defina a função Linhapar que recebe como argumento um vector de inteiros e devolve verdadeiro se a soma dos elementos é par e falso caso contrário. Generalize esta função de modo a receber como argumento uma matriz e a devolver um vector em que na i-ésima posição ocorre 1 se a linha satisfizer Linhapar e 0 caso contrário. 2.8 Defina a função Triangsupinf que recebe como argumento uma matriz quadrada e devolve 1 se esta for triangular superior, 2 se for triangular inferior, 3 se for triangular superior e inferior (ou seja, se for matriz diagonal) e 0 caso contrário. 2.9 Defina a função ProdM que recebe como argumentos duas matrizes e calcula o respectivo produto. Sugestão: Comece por definir a função recorrendo a uma função auxiliar para calcular o produto interno de uma linha por uma coluna. Em seguida, desenvolva a função sem recorrer a funções auxiliares. 2.10 Defina uma subrotina Gauss que recebe como argumento uma matriz quadrada e devolve a matriz resultante da eliminação de Gauss. Pretende-se que a subrotina actue directamente sobre a matriz argumento. 7. Programação recursiva 3.1 Defina a função SomaNatR que recebe como argumento um número natural N e devolve a soma de todos os naturais até N. 3.2 Defina a função MdcR que recebe como argumento dois números naturais e devolve o seu máximo divisor comum, calculado através do algoritmo de Euclides. 3.3 Defina a função ContaperfeitosR que recebe como argumento um número natural N e que devolve o número de números perfeitos até N. 3.4 Defina a função PrimAlgR que recebe como argumento um número natural e devolve o primeiro algarismo na sua representação decimal. 3.5 Defina a função TresNMaisUmR que recebe como argumento um número natural e devolve o número de iterações da função x if (x par) then x/2 else 3x+1 necessárias para atingir o valor 1. 3.6 Defina uma função MembroQR que recebe como argumento um vector e um número e devolve verdadeiro se o número ocorre no vector e falso caso contrário. 3.7 Defina uma função OcorrenciasR que dado um vector e um número conta quantas vezes o número ocorre no vector. 3.8 Defina uma função Prefixo que recebe como argumento dois vectores U e V e devolve verdadeiro se U é prefixo de V e falso caso contrário. 3.9 Defina uma subrotina ProdEscalar que recebe como argumento um vector V e um escalar X e calcula o produto escalar de V por X, alterando directamente V. 3.10 Defina a função MediamatrizR que recebe como argumento uma matriz e devolve a média dos seus elementos. 3.11 Defina a função Pesquisabin que recebe como argumento um vector V de números ordenado de forma crescente e um elemento X, e que retorna verdadeiro se X pertence a V e falso caso contrário. Aula Prática 8 Tipos de dados em F 8. Pilhas Recorde o módulo das pilhas mbstacks. a) Desenvolva sobre esta camada as seguintes operações sobre pilhas: noc(x,s): devolve o número de ocorrências do número x na pilha s; inverte(s): devolve a pilha s invertida; prefixo(s1,s2): devolve .true. se a pilha s1 for prefixo da pilha s2 . Uma pilha s1 dizse prefixo de s2 se s2 é igual a s1 ou s2 pode ser obtida de s1 sobrepondo-lhe alguns elementos. b) Enriqueça o módulo mbstacks com funções ou subrotinas que implementem as operações anteriores, tirando partido da implementação das pilhas nesse módulo. 9. Pilhas navegáveis Uma pilha navegável é uma pilha enriquecida com um cursor e operações para aceder ao elemento apontado pelo cursor e para movimentar o cursor. Após a alteração do conteúdo da pilha, o cursor fica sempre no topo. a) Desenvolva em F um módulo que disponibilize as seguintes operações sobre pilhas navegáveis: new() é uma função sem parâmetros que devolve a pilha vazia; push(x,s) é uma subrotina que sobrepõe o elemento x na pilha s; pop(s) é uma subrotina que retira o elemento que está no topo de s; top(s) é uma função que devolve o topo da pilha s; emptyQ(s) é uma função que testa se a pilha s está vazia; down(s) é uma subrotina que desloca o cursor uma posição para baixo na pilha s; up(s) é uma subrotina que desloca o cursor uma posição para cima na pilha s; curr(s) é uma função que devolve o elemento de s apontado pelo cursor; topQ(s) é uma função que devolve .true. se o cursor estiver no topo de s e .false. no caso contrário; bottomQ(s) é uma função que devolve .true. se o cursor estiver no fundo de s e .false. no caso contrário. b) Desenvolva sobre a camada anterior as seguintes operações: noc(x,s): devolve o número de ocorrências do número x na pilha navegável s; prefixo(s1,s2): devolve .true. se a pilha navegável s1 for prefixo da pilha navegável s2 . Uma pilha navegável s1 diz-se prefixo de s2 se s2 é igual a s1 ou s2 pode ser obtida de s1 sobrepondo-lhe alguns elementos. Esta operação não deve alterar o conteúdo das pilhas s1 e s2, podendo no entanto alterar as posições dos cursores. 10.Filas de espera a) Desenvolva em F um módulo que disponibilize as seguintes operações sobre filas: new() é uma função sem parâmetros que devolve a fila vazia; enter(x,q) é uma subrotina que coloca o elemento x no fim da fila q; leave(q) é uma subrotina que retira o primeiro elemento da fila q; first(q) é uma função que devolve o primeiro elemento da fila q; emptyQ(q) é uma função que testa se a fila q está vazia; len(q) é uma função que devolve o comprimento da fila q. b) Desenvolva sobre a camada anterior as seguintes operações: retiraN(n,q): retira os primeiros n elementos da fila q (caso não existam n elementos, retira os elementos todos deixando a fila vazia); noc(x,q): devolve o número de vezes o número x ocorre na fila q; junta(q1,q2): acrescenta os elementos da fila q2 ao fim da fila q1, mantendo a ordem e deixando a fila q2 vazia; distribui(q,q1,q2): distribui alternadamente os elementos da fila q pelas filas q1 e q2, deixando a fila q2 vazia; prefixo(q1,q2): devolve .true. no caso de q1 ser um prefixo de q2 e .false. no caso contrário; subfila(q1,q2): devolve .true. no caso de q1 ser uma subfila de q2 e .false. no caso contrário. Uma fila q1 diz-se subfila de q2 se q1 é igual a q2 ou q2 pode ser obtida de q1 acrescentando-lhe alguns elementos no ínicio e outros no fim. Aula Prática 9 Tipos de dados em F 11.Pilhas navegáveis – implementação dinâmica Recorde o tipo de dados das pilhas navegáveis. c) Desenvolva em F um módulo que disponibilize o tipo xstack das pilhas navegáveis (recorrendo a uma implementação com apontadores) e as seguintes operações sobre pilhas navegáveis: new(): função sem parâmetros que devolve a pilha vazia; push(x,s): subrotina que sobrepõe o elemento x na pilha s; pop(s): subrotina que retira o elemento que está no topo de s; top(s): função que devolve o topo da pilha s; emptyQ(s): função que testa se a pilha s está vazia; down(s): subrotina que desloca o cursor uma posição para baixo na pilha s; up(s): subrotina que desloca o cursor uma posição para cima na pilha s; curr(s): função que devolve o elemento de s apontado pelo cursor; topQ(s): função que devolve .true. se o cursor estiver no topo de s e .false. no caso contrário; bottomQ(s): função que devolve .true. se o cursor estiver no fundo de s e .false. no caso contrário. d) Desenvolva sobre a camada anterior as seguintes operações: noc(x,s): devolve o número de ocorrências do número x na pilha navegável s; prefixo(s1,s2): devolve .true. se a pilha navegável s1 for prefixo da pilha navegável s2 . Uma pilha navegável s1 diz-se prefixo de s2 se s2 é igual a s1 ou s2 pode ser obtida de s1 sobrepondo-lhe alguns elementos. Esta operação não deve alterar o conteúdo das pilhas s1 e s2, podendo no entanto alterar as posições dos cursores. 12.Conjuntos finitos a) Desenvolva em F um módulo que disponibilize o tipo conjunto finito de inteiros (fset) e as seguintes operações sobre conjuntos: emptyset(): função sem parâmetros que devolve o conjunto vazio; insert(x,s): subrotina que acrescenta o elemento x ao conjunto s; remove(x,s): subrotina que retira o elemento x do conjunto s; emptyQ(s): função que devolve .true. se s for o conjunto vazio e .false. caso contrário; memberQ(n,s,b): subrotina que devolve em b .true. se n for um elemento de s e .false. caso contrário; union(s,r,u): subrotina que devolve em u a união dos conjuntos s e r; intersect(s,r,u): subrotina que devolve em u a intersecção dos conjuntos s e r; diff(s,r,u): subrotina que devolve em u a diferença entre os conjuntos s e r, isto é, o conjunto dos elementos que estão em s e não estão em r; min(s,n): subrotina que devolve em n o menor elemento de s, caso s não seja vazio; max(s,n): subrotina que devolve em n o maior elemento de s, caso s não seja vazio; nelem(s,k): subrotina que devolve em k o número de elementos de s. b) Desenvolva sobre a camada anterior as seguintes operações: subsetQ(s,r,b): subrotina que devolve em b o valor .true. se s for um subconjunto de r; supersetQ(s,r,b): subrotina que devolve em b o valor .true. se s for um sobreconjunto de r; e) Defina as operações union, intersect e diff assumindo que estas não são disponibilizadas pelo módulo anterior. Aula Prática 10 Tipos de dados em F 13.Listas Considere o tipo de dados abstracto lista de inteiros. f) Desenvolva em F um módulo que disponibilize as operações a seguir descritas sobre listas de inteiros, escolhendo a implementação seguinte para o tipo lista: type, public :: lista private type(elem), pointer :: prim integer :: comp end type lista type, private :: elem integer :: val type(elem), pointer :: seg end type elem nil(): função sem parâmetros que devolve a lista vazia; first(w,x): subrotina que recebe no parâmetro de entrada/saída w uma lista de inteiros e devolve no parâmetro de saída x o primeiro elemento da lista, caso esta não seja vazia; prepend(w,x): subrotina que recebe no parâmetro de entrada/saída w uma lista de inteiros e no parâmetro de entrada x e acrescenta x no inicio da lista; rest(w): subrotina que recebe no parâmetro de entrada/saída w uma lista de inteiros e lhe retira o primeiro elemento, caso esta não seja vazia; last(w,x): subrotina que recebe no parâmetro de entrada/saída w uma lista de inteiros e devolve no parâmetro de saída x o último elemento da lista, caso esta não seja vazia; append(w,x): subrotina que recebe no parâmetro de entrada/saída w uma lista de inteiros e no parâmetro de entrada x e acrescenta x no fim da lista; most(w): subrotina que recebe no parâmetro de entrada/saída w uma lista de inteiros e lhe retira o último elemento, caso esta não seja vazia; join(w1,w2,w3): subrotina que recebe nos parâmetros de entrada/saída w1 e w2 duas listas de inteiros e devolve em w3 a lista resultante de juntar w1 com w2; emptyQ(w): função que recebe no argumento w uma lista de inteiros e devolve .true. se a lista estiver vazia e .false. caso contrário. g) Desenvolva sobre a camada anterior a seguinte operação: noc(x,w): devolve o número de ocorrências x na lista de inteiros w; merge(w1,w2,w3): operação que recebe duas listas ordenadas w1 e w2 e devolve em w3 o resultado de juntar ordenadamente os elementos de w1 e de w2. 14.Pilhas sobre listas Recorde o tipo de dado abstracto pilha de inteiros. Implemente esse tipo de dados sobre listas de inteiros. Pretende-se que uma pilha seja representada por uma lista e que as operações sobre pilha sejam implementadas recorrendo às operações sobre listas.