Transcript
Page 1: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 1

Recursividade e Iteração (cont.) Processamento de Texto

Pedro BarahonaDI/FCT/UNL

Abril 2005

Page 2: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 2

Recursividade para Resolução de Problemas• A recursividade pode ser usada na resolução de problemas,

difíceis de resolver por outras técnicas de programação.

• Tal é o caso das “Torres de Hanoi”: dadas três torres (estacas) pretende-se passar uma “pirâmide” de peças ordenadas de uma torre para outra, movendo-se uma peça de cada vez, para o topo de uma torre encimada por uma peça menor.

Page 3: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 3

• Apesar de aparentemente complicado, este problema tem uma solução recursiva simples.

• Para passar n peças de uma torre (A) para outra (C)1. Passar n-1 peças da torre inicial (A) para a torre livre

(B)2. Mover a última peça, para a torre final (C)3. Passar as n-1 peças da torre B para a torre final (C).

Torres de Hanoi - Recursividade

Page 4: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 4

Torres de Hanoi: Movimentos Necessários

• Baseados nesta resolução recursiva podemos

– Determinar o número de movimentos necessários

– Determinar os movimentos necessários

• O número de movimentos necessários é bastante simples de determinar, na versão recursiva

hanoi_count(n) = hanoi_count(n-1)+1+ hanoi_count(n-1)

• Neste caso, pode-se evitar a dupla recursividade (ver adiante) de uma forma muito simples

hanoi_count(n) = 2*hanoi_count(n-1) + 1

• Finalmente, há que especificar a condição de paragem (n=1)hanoi_count(1) = 1

Page 5: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 5

Torres de Hanoi: Movimentos Necessários

• Um programa Octave para resolver o programa é imediatofunction c = hanoi_count(n) if n == 1 c = 1; else c = 2*n_hanoi_count(n-1)+1;

end;endfunction;

• De notar o aumento exponencial do número de movimentos necessários

n 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15count 1 3 7 15 31 63 127 255 511 1 023 2 047 4 095 8 191 16 383 32 767

Page 6: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 6

Torres de Hanoi• O problema propriamente dito pode ser resolvido com base

num vector T, com 3 números, correspondentes ao número de peças em cada uma das torres.

• Notar que não é necessário indicar o tamanho de cada peça, porque o algoritmo nunca coloca uma peça sobre uma menor!

• O movimento de uma só peça da torre A para a torre B, usado no corpo da recursão e na sua terminação, pode ser feito com uma função auxiliar, move_hanoi(T,A,B), especificada da forma óbvia (tira uma peça de A e aumenta em B).

T = [3,1,1]

Page 7: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 7

Torres de Hanoifunction T = hanoi(T,N,A,B) % move N peças de A para B if N == 1 T = hanoi_move(T,A,B); % move a peça de A para B else C = 6-A-B; % C é a outra torre!

T = hanoi(T,N-1,A,C); % move N-1 peças de A para C T = hanoi_move (T,A,B);% move 1 peça de A para B T = hanoi(T,N-1,C,B); % move N-1 peças de C para B end;endfunction;

function T = hanoi_move(T,A,B) T(A) = T(A) - 1; T(B) = T(B) + 1; disp(T);endfunction;

Page 8: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 8

• O funcionamento do programa pode ser visto com a chamada

>> hanoi([4,0,0],4,1,3);4 0 03 1 02 1 12 0 21 1 22 1 12 2 01 3 00 3 10 2 21 1 22 1 12 0 21 1 20 1 30 0 4

Torres de Hanoi

hanoi(_,2,1,3)

hanoi(_,2,3,2)

hanoi(_,3,1,2)move(_,1,2)

hanoi(_,2,2,1)

hanoi(_,2,1,3)

hanoi(_,3,2,3)move(_,2,3)

move(_,1,3)

Page 9: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 9

Recursão e Iteração• Em geral, uma função ou procedimento definidos

recursivamente podem-no ser tambem de uma forma iterativa (através de ciclos).

• Em geral, a definição recursiva é mais “declarativa” na medida em que explicita o que se pretende obter e não a forma como se obtem (ou seja, um determinado programa que é usado).

• Por outro lado, uma definição iterativa, embora não permita uma compreensão tão imediata, é geralmente mais eficiente, já que as instruções de programação de baixo nível para a iteração são mais eficientes que as de chamadas de funções.

• No entanto, estas diferenças são geralmente pouco importantes, excepto em casos de recursão múltipla, em que a ineficiência pode ser “catastrófica”.

Page 10: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 10

Recursão e Iteraçãofunction f = fib(n); % versão recursiva if n <= 2 f = 1; else f = fib(n-1) + fib(n-2); endif; endfunction;

function f = fib(n) % versão iterativa if n <= 2 f = 1; else f1 = 1; f2 = 1; for i = 3:n f = f1+f2; f1 = f2; f2 = f; endfor; endif;endfunction;

Page 11: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 11

Recursão e IteraçãoEsta é a situação da função de Fibonacci, em que o seu valor depende de 2 chamadas recursivas. Como as chamadas são independentes, a mesma função acaba por ser recalculada várias (muitas !) vezes. 7

5

3

2 1

4

23

2 1

6

4

23

2 1

5

3

2 1

4

23

2 1 Na realidade, o número de funções chamadas é o próprio número de fibonacci (7:1, 6:1, 5:2, 4:3, 3:5, 2:8) que aumenta exponencialmente com o valor de n.

Page 12: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 12

Recursão e IteraçãoPara se ter uma ideia do aumento, podemos notar que apesar de inicialmente pequenos

os números tornam-se rapidamente “enormes”

tornando proibitiva a sua computação recursiva (normal).

n 1 2 3 4 5 6 7 8 9 10 11fib(n) 1 1 2 3 5 8 13 21 34 55 89

n 26 27 28 29 30 31 32fib(n) 121 393 196 418 317 811 514 229 832 040 1 346 269 2 178 309

n 45 46 47 48 49 50fib(n) 1 134 903 170 1 836 311 903 2 971 215 073 4 807 526 976 7 778 742 049 12 586 269 025

Page 13: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 13

Memorização• Por vezes é possível aliar a declaratividade da versão

recursiva, com a eficiência da versão iterativa, através da memorização dos valores já computados.

• Por exemplo se se pretenderem os primeiros 100 números de fibonacci, pode criar-se uma tabela, fib_m, com os valores já computados.

– Se fib_m(n) ainda não contiver o valor de fib(n), então determina-se fib(n) e escreve-se em fib_m(n).

– Caso contrário, apenas se retorna o valor de fib_m(n).

• Para que este esquema seja possível, é conveniente que a tabela fib_m seja visível por todas as instâncias da função fib(n). Para evitar passá-la como parâmetro deve declarar-se como uma variável global.

Page 14: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 14

Variáveis Globais em Octave• Em Octave, para que uma variável seja global, ela deve ser

declarada no programa principal com a declaração global. No caso actual, se se pretende um vector linha com 100 elementos inicializados a zero, devemos declarar a variável global

fib_m = zeros(1,100);

global fib_m;

• Uma vez declarada uma variável global, ela pode ser eliminada através da declaração clear. Se pretendermos um vector com 200 elementos deveremos fazer

clear fib_m

fib_m = zeros(1,200)

Page 15: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 15

Memorização• Para que, na função, a variável fib_m considerada seja

a variável global e não uma variável local, a variável deve ser identificada novamente como global.

function f = fib_mem(n); %versão recursiva c/ memória global fib_m; if fib_m(n) > 0 f = fib_m(n); else if n <= 2 f = 1; else fib_m(n) = fib_mem(n-1)+fib_mem(n-2); f = fib_m(n); endif; endif;endfunction;

Page 16: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 16

Processamento de Texto

• Muita informação útil, nomeadamente em tarefas de gestão, não é do tipo numérico.

• Por exemplo, variadas entidades (pessoas, empresas, disciplinas, departamentos, etc...) têm associado um nome que se pode querer processar (por exemplo ordenar).

• Este é apenas um exemplo de situações em que se pretende que os programas efectuem processamento de texto.

• Todas as linguagens de programação prevêem pois tipos de dados para este fim, nomeadamente

– Caracteres;

– Cadeias de caracteres (“strings”).

Page 17: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 17

Caracteres• Os caracteres mais utilizados (representados no código

ASCII - American Standard Code for Information Interchange) incluem

• Letras (52), maiúsculas (26) e minúsculas (26)

• Dígitos (10)

• Espaço e outros caracteres “visíveis” (34)– ‘ “ ( ) [ ] { } , . : ; = < > + - * \ | / ^ ~ ´ ` # $ % & _ ! ? @

• Caracteres de controle (32)– horizontal tab (\t), new line (\n), alert (\a), ...

• Outros caracteres, (ç, ã, ñ, š , ø , ∞, , Σ, ш, غغ ,לא, ך ) só podem ser representados em códigos mais avançados e não são “suportados” em algumas linguagens de programação (em Octave, uma variável não pode ter o nome “acção”)

Page 18: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 18

Cadeias de Caracteres• Cadeias de caracteres (“strings”) são sequências (ordenadas)

de caracteres.

• Em quase todas as linguagens, dados do tipo caracter e cadeia (incluindo simples caracteres) são representados entre delimitadores, que podem ser aspas (“ ”) ou plicas (‘ ’).

• Devem sempre abrir-se e fechar-se com o mesmo tipo de delimitadores.

• Quando se pretende incluir um dos delimitadores no texto, podem usar-se sequências de escape– nome = ‘ Maria Martins d\’Albuquerque’

• ou usar-se o outro delimitador – nome = “ Maria Martins d’Albuquerque”– frase = ‘Ele exclamou: “Óptimo” e fugiu’

Page 19: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 19

Cadeias de Caracteres e Vectores• Em geral, e Octave não foge à regra, cadeias de caracteres são

“implementadas” como vectores dos códigos dos caracteres.

• Muitas funções e operações em Octave exigem a utilização do tipo correcto. Duas funções permitem transformar

– Vectores em cadeias : toascii: <cadeia> <vector>>> a = toascii(“ABC”) a = [65,66,67]

– Cadeias em vectores : setstr: <vector> <cadeia>>> b = setstr([97,98,99]) b = ‘abc’

• O Octave não é muito estrito no que se refere aos tipos de dados. Por exemplo, permite operações “numéricas” com cadeias, fazendo a conversão de tipos necessária

>> c = ‘abc’* 1 c = [97,98,99]• Nota: Estas “facilidades” tornam difícil a detecção de erros de programação e

não devem ser usadas (ou apenas com muito cuidado)

Page 20: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 20

Conversão de Cadeias de Caracteres• Cadeias de caracteres podem ser processados de várias formas.

Para as mais comuns, existem funções pré-definidas.

• Algumas dessas funções permitem converter cadeias de caracteres que representam números para os próprios números.

• Exemplo: Dada a cadeia “ 23.76 ” (com espaços), a sua conversão para um número é obtida com a função str2num.

>> s = “ 23.76 “; a = str2num(s); b = 2*a b = 47.52

• É interessante comparar o resultado acima com (porquê???)>> s = “ 23.76 “; b = 2*s

s = [64,100,102,92,110,108,64,64]

• A conversão oposta, pode fazer-se com a função num2str.

Page 21: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 21

Concatenação de Cadeias de Caracteres• As cadeias podem ser concatenadas. Esta operação é utilizada

para juntar numa só cadeia a informação que está dispersa por várias cadeias. Por exemplo, para juntar

– O(s) nome(s) próprio(s) ao(s) apelido(s)

– Os vários campos de um enedereço (rua, nº, andar, local, etc.)

• O Octave tem uma função strcat, para esse efeito.

• Exemplo: Juntar um nome próprio e um apelido.>> np = “Rui”; ap = “Lopes”; nome= strcat(np,“ ”,ap)

nome = “Rui Lopes”

• De notar a utilização da cadeia com um branco (“ ”) para espaçar o nome próprio e o apelido.

Page 22: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 22

Partição de Cadeias de Caracteres• As cadeias podem ser “partidas” noutras mais simples. Neste

caso pode haver várias formas de fazer a partição. Uma possível é através de caracteres que funcionam como separadores (tipicamente espaços).

• O Octave tem uma função, split, para esse efeito, criando uma matriz de cadeias, cada cadeia na sua linha, com brancos acrescentados se necessário

• Exemplo: Separar os nomes (próprios e apelidos) de uma pessoa.>> nome = “Rui da Costa Pina”; nms = split(nome,“ ”)

nms = “Rui ” “da ” “Costa” “Pina ”

Page 23: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 23

Extracção de Cadeias de Caracteres• Por vezes estamos interessados apenas em partes de uma cadeia.

Uma forma comum de o fazer é indicar – o índice do primeiro caracter pretendido para a subcadeia; e – o comprimento da subcadeia.

• O Octave tem uma função, substr, para esse efeito. Por exemplo: Separar os nomes (próprios e apelidos) de uma pessoa.>> nome = “Rui da Costa Pina”;

nm1 = substr(nome,1,3), nm2 = substr(nome,5,2), nm3 = substr(nome,8,5), nm4 = substr(nome,14,4), nm1= “Rui”, nm2= “da”, nm3= “Costa”, nm4= “Pina”

• Os índices variam de 1 ao comprimento da cadeia. Este comprimento é obtido pela função length.>> nome = “Rui da Costa Pina”; x = length(nome) x= 17

Page 24: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 24

Comparação de Caracteres• Uma operação vulgar no processamento de texto é a ordenação

“por ordem alfabética”.

• Esta ordenação requer a comparação “alfabética” de caracteres.

• Esta pode ser feita através da comparação “numérica” dos códigos dos caracteres.

• A comparação só é fácil se os códigos usados respeitam a ordem alfabética, o que acontece em todos os códigos. Por exemplo em ASCII, o código dos caracteres “A” e “B” é, respectivamente, 65 e 66, pelo que se pode fazer a correspondência pretendida

o caracter c1 “vem antes do” caracter c2 c1 < c2

• Exemplo: >> teste = “a” < “b” teste = 1

Page 25: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 25

Comparação de Cadeias de Caracteres• A comparação “literal” pode ser obtida a partir da comparação

caracter a caracter.

• O Octave tem uma função, strcmp, para verificar se duas cadeias são idênticas.

>> nm1 = “Rui Costa”; nm2 = “Rui Costa”; t = strcmp(nm1,nm2) t = 1

• Para o teste de precedência alfabética (designado por “<<“) o Octave não dispõe de funções predefinidas. Mas elas podem ser definidas tendo em conta a comparação caracter a caracter.

• Vamos pois definir uma função my_str_before como:

my_str_before (s1,s2) = 1 se s1 << s2 0 se s1 = s2 -1 se s1 >> s2

Page 26: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 26

Comparação de Cadeias de Caracteres

function t = my_str_tail(s) c = length(s); if c == 1 t =""; else t = substr(s,2,c-1); endif;endfunction;

• Dada a natureza recursiva da função my_before, esta utiliza uma função auxiliar, my_str_tail, para obter a “cauda da cadeia (isto é, sem o seu primeiro caracter).

• A função my_before compara os primeiros caracteres das cadeias (se existirem). Se estes forem iguais, compara as caudas das cadeias (chamada recursiva).

Page 27: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 27

Comparação de Cadeias de Caracteresfunction b = my_str_before(s1,s2)

c1 = length(s1); c2 = length(s2);

if c1 == 0 & c2 == 0 b = 0; elseif c1 == 0 & c2 > 0 b = 1; elseif c1 > 0 & c2 == 0 b = -1;

else % c1 > 0 & c2 > 0 if s1(1) < s2(1) b = 1; elseif s1(1) > s2(1) b = -1;

else t1 = my_str_tail(s1); t2 = my_str_tail(s2);

b = my_str_before(t1,t2);

endif; endif;endfunction;

Page 28: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 28

Comparação de Cadeias de Caracteres• A comparação de cadeias de caracteres “interpretáveis” (por

exemplo, de texto em português) é mais complexa.

• Os problemas mais frequentes são de 3 tipos:

– Ocorrência de espaços (e outros caracteres brancos)• “Rui Santos” = “ Rui Santos “ ???

– Tratamento de letras maiúsculas e minúsculas• “Rui Santos” = “RUI SANTOS “ ???

– Caracteres especiais (com acentos e cedilhas)• “João França” = “Joao Franca“ ???

• Estes problemas têm de ser considerados no contexto apropriado (Franca e França são apelidos diferentes, ou o terminal (telemóvel) não tinha o caracter “ç” ?), e requerem algoritmos dedicados.

Page 29: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 29

Comparação de Cadeias com Brancos

• Os caracteres brancos servem para separar os “significativos”. Os mais vulgares são os espaços, mas existem outros para mudança de linha (“\n”, “\r” ou “\f”), ou tabulação (“\t” e “\v”).

• No código ASCII todos têm códigos inferiores a 32 (espaço).

• A comparação de cadeias pode simplificar-se se a comparação fôr feita após normalização. Esta normalização, consiste em

– eliminar todos os brancos prefixos/sufixos, i.e. antes/depois do primeiro/último caracter significativo.

– Substituir todos os separadores (grupos de brancos, tabs, mudanças de linha, etc. por um só branco).

• Algumas funções pre-definidas podem auxiliar na normalização, mas o Octave não tem esta função predefinida.

Page 30: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 30

Substituição de Brancos por Espaços

• Assumindo que todos os caracteres brancos têm código inferior a 32, podemos utilizar a função my_str_remctr, indicada abaixo, para substituir todos os caracteres brancos por espaços.

function t = my_str_remctr(s) for i = 1:length(s) if toascii(s(i)) < 32 t(i) = " "; else t(i) = s(i); endif; endfor;endfunction;

Page 31: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 31

Eliminação de Brancos Prefixos e Sufixos

• O Octave dispõe de uma função (deblank) que elimina todos os espaços sufixos.

• A eliminação dos brancos prefixos pode igualmente usar essa função se se inverter (passá-la de trás para a frente) a cadeia. Essa inversão pode usar a função my_str_rev, indicada abaixo

function r = my_str_rev(s) c = length(s); for i = 1:c r(i) = s(c-i+1); endforendfunction;

Page 32: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 32

Eliminação de Espaços Repetidos

• A eliminação dos espaços repetidos pode ser feita usando a função my_str_remrep, indicada abaixo. A função percorre toda a cadeia mantendo a informação (na variável booleana ultimo_branco) sobre se o último caracter era branco. Nesse caso, se o caracter fôr espaço não o copia (seria repetido).

function t = my_remrep(s) j = 1; ultimo_branco = 0; for i = 1:length(s) if s(i) != " " t(j) = s(i); j = j+1; ultimo_branco = 0; elseif !ultimo_branco t(j) = s(i); j = j+1; ultimo_branco = 1; endif; endfor;endfunction;

Page 33: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 33

Normalização de Cadeias de Caracteres • A normalização de cadeias de caracteres pode ser feita usando a

função my_str_norm, indicada abaixo, que utiliza todas as funções anteriores, da forma esperada.

• Primeiro, substitui os brancos por espaços. Depois elimina os espaços sufixos. Em terceiro lugar elimina os brancos prefixos (eliminando os brancos sufixos da cadeia invertida, invertendo de novo o resultado). Finalmente, os espaços repetidos são removidos.

function sn = my_str_norm(s) s1 = my_str_remctr(s) s2 = deblank(s1); s3 = my_str_rev(deblank(my_str_rev(s2))); sn = my_str_remrep(s3);endfunction;

Page 34: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 34

Comparação de Cadeias com Brancos

function b = my_str_norm_before(s1,s2) sn1 = my_str_norm(s1); sn2 = my_str_norm(s2); b = my_str_before(sn1,sn2);endfunction;

• A comparação de cadeias de caracteres pode ser feita usando a função my_str_norm_before, indicada abaixo, que não considera os caracteres brancos.

• As diferenças podem ser exemplificadas em baixo.>> t = my_str_before(“Rui Lopes”, “ Rui Lopes”)

t = -1

>> t = my_str_norm_before(“Rui Lopes”, “ Rui Lopes”)

t = 0

Page 35: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 35

Comparação com Maiúsculas/Minúsculas• A comparação de cadeias de caracteres pode ser igualmente

prejudicada pela existência de letras maiúsculas e minúsculas.

• O Octave tem algumas funções que facilitam o tratamento deste tipo de situações, nomeadamente as funções tolower e toupper, que convertem os caracteres maiúsculos / minúsculos em caracteres minúsculos / maiúsculos.

>> s1 = “\n Rui \t Lopes”; s2 = “RUI lopes”; sn1 = toupper(s1), sn2 = toupper(s2), t1 = my_str_norm_before(s1,s2), t2 = my_str_norm_before(sn1,sn2)

sn1 = “\n RUI \t LOPES” sn2 = “RUI LOPES” t1 = -1 t2 = 0

Page 36: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 36

Conversão entre Maiúsculas/Minúsculas• As funções anteriores assumem um código ASCII, em que os

caracteres brancos têm códigos abiaxo de 32.

• Nesse código ASCII, a conversão entre maiúsculas e minúsculas pode ser feita adicionando ou subtraindo a sua diferença aos códigos respectivos. Esta diferença é 32, como pode ser verificado em

>> dif = toascii(“A”) – toascii(“a”) dif = -32

• No entanto, a utilização destes valores pode ser problemática, se forem usados outros códigos. É da responsabilidade da implementação da linguagem interpretar ter em atenção os códigos usados (que podem não ser ASCII) e disponibilizar primitivas independentes desses códigos.

Page 37: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 37

Conversão independente do Código• Algumas dessas primitivas são

– isalpha(s) 1 se s fôr alfabético (maiúscula ou minúscula)

– islower(s) 1 se s fôr uma minúscula– isupper(s) 1 se s fôr uma maiúscula– isdigit(s) 1 se s fôr um dígito– isalnum(s) 1 se s fôr dígito ou alfabético– ispucnt 1 se s fôr um caracter de pontuação– iscntrl(s) 1 se s fôr caracter de controle

• Desta forma as funções poderão ser rectificadas para se tornarem independentes do código usado para representação dos caracteres. Em particular, o teste

toascii(s(i)) < 32 pode/deve ser substituido por

iscntrl(s2)

Page 38: Recursividade e Iteração (cont.)  Processamento de Texto

21 Abril de 2005 Recursividade e Iteração 38

Cadeias com Caracteres Especiais• Os caracteres com cedilhas e acentos, típicos do português, não

fazem parte do código ASCII básico, e os seus códigos em ASCII estendido não respeitam a ordem “natural”.

• Por exemplo, como os códigos dos caracteres “a”, “s” e “ã” são, respectivamente 97, 115 e 227, o nome João está alfabeticamente após José, ao contrário do que acontece com Joao.

• Uma forma de manter a ordenação pretendida é utilizar, para efeitos de ordenação, as cadeias com os caracteres acentuados substituídos pelos caracteres não acentuados.

• O Octave dispõe de uma função (strrep) que substitui numa cadeia base, todas as de uma (sub)cadeia por outra.

>> s1 = “João”; s2 = strrep(s1,”ã”,”a”) s2 = “Joao”


Recommended