Вы находитесь на странице: 1из 11

Notas de Aula de o de Computadores Algoritmos e Programac a

F L AVIO K EIDI M IYAZAWA com a colaborac a o de T OMASZ KOWALTOWSKI

Instituto de Computac a o - UNICAMP

Vers ao 2000.1

Estas notas de aula n ao devem ser usadas como u nica fonte de estudo. O aluno deve ler outros livros dispon veis na literatura. Nenhuma parte destas notas pode ser reproduzida, qualquer que seja a forma ou o meio, sem a permiss ao dos autores. Os autores concedem a permiss ao expl cita para a utilizac a o e reproduc a o deste material no contexto do ensino de disciplinas regulares dos cursos de graduac a o sob a responsabilidade do Instituto de Computac a o da UNICAMP.

c Copyright 2000

Instituto de Computac a o UNICAMP Caixa Postal 6176 13083970 CampinasSP fkm,tomasz @ic.unicamp.br

ii

8 Processamento de Cadeias de Caracteres


Em praticamente todos os padr oes de codiac a o, a representac a o interna das letras est a agrupada e ordenada. Este e um dos motivos dos computadores poderem fazer comparac o es com letras, como A B rapidamente, internamente e comparada sua codicac a o interna. Al em disso, a codicac a o das letras e n umeros e em geral seq ue ncial. Um exemplo disto e a codicac a o ASCII (veja tabela 1). Como vimos, uma cadeia de caracteres pode ser denida com o tipo string. Al em disso, podemos fazer operac o es com os caracteres que est ao nesta string (cadeia). Considere as seguintes declarac o es: type TipoTexto = string[1000]; var Texto : TipoTexto; Com estas declarac o es, podemos fazer a seguinte atribuic a o para a vari avel Texto: Texto := Algoritmo; Uma func a o que devolve o comprimento da cadeia de caracteres e a func a o length. Ap os a atribuic a o acima, length(Texto) deve retornar o inteiro 9. Al em disso, podemos trabalhar com cada caracter deste texto, como se Texto fosse um vetor de 9 posic o es, i.e., podemos acessar e atualizar um elemento da cadeia. Assim, ap os a atribuic a o da vari avel Texto feita acima, temos em Texto[1] a letra A, Texto[2] a letra l, Texto[3] a letra g, ..., Texto[9] a letra o. Observac o es: 1. Em Turbo Pascal h a uma limitac a o do tamanho m aximo de uma String, de 255 caracteres. A declarac a o de vari aveis usando apenas a palavra reservada String denota o tipo string com 255 caracteres. No Turbo Pascal a passagem de tipos e feita de maneira r gida, de tal forma que uma vari avel declarada como String[255] n ao pode ser enviada como um par ametro declarado apenas como o tipo string. 2. Em Delphi, String denota normalmente o tipo long string ou AnsiString cujo limite de comprimento m aximo e 2 GB! Com a diretiva de compilac a o $H-$, String denota o tipo String[255] como em Turbo Pascal. Outra alternativa equivalente e usar o tipo pr e-denido ShortString. 3. Em Gnu Pascal n ao e poss vel declarar vari aveis usando apenas a palavra String, mas na passagem de par ametros e ponteiros sim. Desta maneira poderemos ter vari aveis declaradas como strings de tamanhos diferentes mas que s ao recebidas como par ametros do tipo String (sem especicac a o do tamanho). 4. Em Extended Pascal tamb em n ao e poss vel se usar apenas a palavra String para declarar vari aveis, al em disso o tamanho da string e declarado usando se parenteses em vez de colchetes. Por exemplo, a seguinte declarac a o apresenta uma string em Extended Pascal com 100 caracteres. var nome:string(100); Nos exemplos deste texto usaremos a seguinte sintaxe:

Na declarac a o de vari aveis e tipos usaremos colchetes com o devido tamanho da string. Na passagem de par ametros daremos prioridade para a sintaxe usando a palavra string. No caso onde a rotina tem funcionalidade xa para um determinado tipo usaremos o nome do tipo no lugar da palavra string. A seguir apresentamos algumas rotinas para manipulac a o de strings. Func a o Length SetLength  Pos  ! Concat "  ###$ Copy 1324 Insert "!%325 Delete 1324 Resultado Retorna a quantidade de caracteres da string Redene a quantidade de caracteres em uso como  Retorna a posic a o da cadeia  na cadeia ! (0 se n ao ocorre) Retorna a concatenac a o de  %### (equivale a '&(!)&0### ) Retorna a cadeia formada pelos  caracteres a partir da posic a o 2 Insere  em  a partir da posic a o 2 Remove os  caracteres a partir da posic a o 2

79

Exemplo 8.1 Descreva uma implementac a a o em pascal da func o Pos. function Pos(var s1,s2: String): Integer; var n1,n2,d,i,j : Integer; achou, cont: Boolean; begin n1 : 6 Length(s1); n2 : 6 Length(s2); d : 6 n2 7 n1 & 1; achou : 6 False; i : 6 1; while (not achou) and (i 86 d) do begin j : 6 1; cont : 6 True; while cont and (j 96 n1) do begin cont : 6 (s1[j]6 s2[i & j 7 1]); inc(j) end; achou : 6 cont; inc(i); end; if achou then Pos : 6 i 7 1 else Pos : 6 0 end; Pos Exemplo 8.2 Descreva uma implementac a a o em pascal da func o Insert. function Insert( var s1,s2: String; p: Integer); Insere os caracteres de s1 que couberem em s2 const ComprMax 6 255; var n1,n2,d,i : Integer; begin n1 : 6 Length(s1); n2 : 6 Length(s2); if (n1& n2) @ ComprMax then d : 6 ComprMax 7 n2 else d : 6 n1; i : 6 1; for i: 6 n2 downto n2 7 d & 1 do s2[i& d] : 6 s[i]; for i: 6 1 to d do s2[p& i 7 1] : 6 s1[i]; & d) SetLength(s2,n2 end; Insere Exemplo 8.3 Uma cadeia de caracteres e ndrome se a seq ue dita ser pal ncia dos caracteres da cadeia da esquerda para a direita e ue igual a seq ncia de caracteres da direita para a esquerda. Por exemplo: As seguintes cadeias de caracteres s ao pal ndromes: ABC12321CBA, ACCA, XYZ6.6ZYX. Fac a uma func a ametro e ndrome. o que retorna verdadeiro se a cadeia de caracteres enviada como par pal

80

function Palindrome(var s: String): Boolean; var i,m,n : Integer; p: Boolean; begin p : 6 True; n : 6 Length(s); m : 6 n div 2; i : 6 1; while p and (i 96 m) do begin p : 6 (s[i] 6 s[n 7 i & 1]); inc(i); end; Palindrome :6 p end; Palindrome

8.1 Letras com Ac entos


Em muitas situac o es temos cadeias de caracteres seguindo uma codicac a o para acentuac a o das letras (eg. textos escritos na l ngua portuguesa). As codicac o es de acentuac a o n ao s ao consideradas na codicac a o ASCII e na maioria das vezes n ao seguem uma padronizac a o envolvendo diferentes plataformas (i.e., uma letra acentuada em um ambiente Unix pode ter c odigo diferente da mesma letra acentuada em ambiente MS-DOS). Uma tarefa comum que temos de fazer, quando consideramos ac entos, e a remoc a o destes do texto. A seguir apresentamos duas aplicac o es onde precisamos fazer um pr e-processamento para remover os acentos: 1. Envio de mensagens pela internet por correio eletr onico. A internet e uma rede de computadores que n ao necessariamente seguem a mesma congurac a o. Os textos como as mensagens enviadas por correio eletr onico s ao enviadas considerando a congurac a o ASCII. Por outro lado, letras acentuadas em um computador podem n ao ser consideradas realmente letras em outros computadores. Assim, estes podem ser interpretados como c odigos de ac a o totalmente imprevis vel. Uma soluc a o para isso e eliminar os acentos, ou troc a-los por uma seq ue ncia de letras ASCII que representem a letra acentuada. 2. Ordenac a o de cadeias de caracteres. Para comparar duas cadeias de caracteres, a maioria dos programas considera as representac o es bin arias caracter a caracter. Considerando a codicac a o ASCII, a ordenac a o de letras em ASCII se torna f acil, uma vez que temos apenas que comparar letra a letra nesta codicac a o. Por outro lado, teremos uma ordenac a o errada caso tenhamos acentos. Por exemplo, considere as palavras macro, macaco e mac o. Se a codicac a o de c vier antes de c, ent ao teremos a seguinte ordem para estas palavras: mac o, macaco e macro, que n ao e a ordem que desejamos. Por outro lado, se a codicac a o de c vier antes de c , ent ao teremos a ordem: macaco, macro e mac o, que tamb em n ao e a desejada. Assim, uma soluc a o para isto e comparar as palavras trocando as letras acentuadas pelas correspondentes letras sem acento. Exemplo 8.4 O seguinte programa cont em uma func a a o que dado uma letra, retorna a letra sem acentuac o. Obs.: Esta implementac a a o e dependente da codic o das letras usada no programa fonte.

81

program acentos; function SemAcento(caracter : char):char; begin case caracter of a : SemAcento:6 a; A : SemAcento:6 E : SemAcento:6 E; : SemAcento:6 o : SemAcento:6 o; O : SemAcento:6 U : SemAcento:6 U; ` a : SemAcento:6 a : SemAcento:6 a; A : SemAcento:6 E : SemAcento:6 E; o : SemAcento:6 A : SemAcento:6 a : SemAcento:6 a; O : SemAcento:6 O; u : SemAcento:6 c : SemAcento:6 c; C : SemAcento:6 else SemAcento:6 caracter; end; case end; var c : char; begin a; writeln(A letra ,c, sem acento c: 6 c: 6 e; writeln(A letra ,c, sem acento c: 6 a; writeln(A letra ,c, sem acento c: 6 o; writeln(A letra ,c, sem acento end.

A; i; O; a; A; o; A; u; C;

e : SemAcento: 6 I : SemAcento: 6 u : SemAcento: 6 ` A : SemAcento: 6 e : SemAcento: 6 O : SemAcento: 6 o : SemAcento: 6 U : SemAcento: 6

e; I; u; A; e; O; o; U;

fica fica fica fica

,SemAcento(c)); ,SemAcento(c)); ,SemAcento(c)); ,SemAcento(c));

Exerc cio 8.1 Fac a uma func a ametro uma cadeia de caracteres e retorna a mesma cadeia sem o que tem como par acentos.

o entre Maiusculas 8.2 Transformac a e Minusculas


Uma maneira de se tranformar uma cadeia de caracteres trocando cada letra por sua correspondente em mai uscula e percorrer toda a cadeia e para cada caracter colocar uma seq ue ncia de testes, um para cada letra min uscula, e troc ala pela correspondente letra mai uscula. Um algoritmo deste tipo iria requerer uma estrutura com pelo menos 25 condic o es, tornando o programa longo e lento. Uma maneira mais eciente de se implementar tal procedimento, e considerar a representac a o interna de cada caracter. Considerando que internamente cada letra e representada em um byte, e a representac a o das letras e seq ue ncial A id eia e mudar apenas aqueles caracteres que estiverem no intervalo [a, ### ,z]. Quando ocorrer um caracter A neste intervalo, obtemos o valor inteiro em ASCII de A e seu deslocamento B a partir do caracter C . Em seguida, reatribu mos o caracter que estiver na posic a o de A mais o deslocamento B .

82

program ProgramMaiusculas; type TipoTexto 6 string[1000]; procedure Maiuscula(var texto : TipoTexto); var i,tam : integer; begin tam : 6 length(texto); for i: 6 1 to tam do if (a 96 texto[i]) and (texto[i] 96 z) then texto[i] : 6 chr( ord(A) & ord(texto[i]) 7 ord(a)); end; var Cadeia : TipoTexto; begin write(Entre com um texto: ); readln(cadeia); Maiuscula(cadeia); writeln(O texto em mai usculo e :,cadeia); end. Exerc cio 8.2 Fac a um programa an alogo ao apresentado acima, mas para tranformar uma cadeia em min usculas.

8.3 Casamento de Padr oes


Nesta sec a o vamos construir uma func a o para que dados duas cadeia de caracteres, uma chamada texto, e a outra chamada padr ao, verica se existe uma ocorr encia de padr ao no texto. Caso ocorra uma ocorr encia, a func a o retorna a posic a o no texto onde ocorre o padr ao, caso contr ario, a func a o retorna 0. Uma id eia simples de implementac a o e ir percorrendo todas as posic o es poss veis de texto, de se comec ar o padr ao (i.e., posic o es D%###!FEG"IH1PRQRSUTFV1SXWY`7(EGIH1PQ4badce%fcWgh&iD ). Para cada uma destas posic o es, h a uma outra estrutura de repetic a o que verica se o padr ao est a comec ando naquela posic a o. A func a o para assim que encontrar o primeiro padr ao, ou at e que todas as possibilidades tenham sido testadas. O seguinte programa implementa esta id eia.

83

program ProgramaBuscaPadrao; type TipoString TipoPadrao


6

string[1000]; 6 string[50];

Retorna a posic a ndice onde comec a o padrao, 0 caso n ao exista. o do function BuscaPadrao(var texto : TipoString; var Padrao:TipoPadrao): integer; var i,j,TamTexto,TamPadrao : integer; achou,SubsequenciaIgual : boolean; begin TamTexto : 6 length(texto); TamPadrao : 6 length(padrao); i : 6 0; achou : 6 false; while (not achou) and (i 86 TamTexto 7 TamPadrao) do begin i: 6 i & 1; j: 6 1; SubSequenciaIgual : 6 true; while (j 96 TamPadrao) and (SubsequenciaIgual6 true) do if (Padrao[j]6 Texto[i & j 7 1]) then j: 6 j & 1 else SubSequenciaIgual : 6 false; achou : 6 SubSequenciaIgual; end; if (achou) then BuscaPadrao : 6 i else BuscaPadrao : 6 0; end; BuscaPadrao var texto : TipoString; padrao : TipoPadrao; pos : integer; begin write(Entre com um texto: ); readln(texto); write(Entre com um padrao: ); readln(padrao); pos : 6 BuscaPadrao(texto,padrao); if (pos6 0) then writeln(Padrao n ao encontrado. ) else writeln(Padrao encontrado na posic ao ,pos); end.

Obs.: Existem outros algoritmos para fazer busca de padr oes que s ao computacionalmente mais ecientes, como o algoritmo de Knuth, Morris e Pratt e o algoritmo de Boyer e Moore.

84

es - Cifra de C 8.4 Criptograa por Substituic o esar


Criptograa e a ci encia e o estudo de escrita secreta. Um sistema criptogr aco e um m etodo secreto de escrita pelo qual um texto leg vel e transformado em texto cifrado. O processo de transformac a o e conhecido como ciframento e a transformac a o inversa e conhecida como deciframento. A id eia aqui n ao e a de apresentar m etodos seguros de criptograa, mas sim de trabalhar mais com as cadeias de caracteres. Provavelmente os primeiros m etodos de criptograa usavam m etodos de substituic a o. Dado dois alfabetos p e , uma func a o de criptograa por substituic a o troca um caracter de um texto p por outra em psq . Naturalmente deve haver uma func a o inversa para que o receptor da mensagem criptografada possa recuperar o texto original.
prq

Cifra de C esar Um caso particular do m etodo de substituic a o e o seguinte. Considere um alfabeto pt6u3Awv%FA "###!FAyx5y com  s mbolos. Considere um inteiro , 7D (chamado de chave). Uma func a o de criptograa %spp e sua 5 inversa (para decriptografar) s ao dadas a seguir:
%3AyX)60A ed fdgih%j x 5 3AkUl6mA! n dox fdg9hj x

Assim, se o alfabeto e pp6q3rsFtku8FvwFxFyzk{|F}~###khRiw`klkwF)k , e em v , t em x , u em y , ### . I.e.,


r x v t y u v { } x y { } ### ### ### r t u

a func a o transforma r

Este tipo de criptograa tamb em e chamado de cifra de C esar, porque J ulio C esar usou com 6 . A seguir apresentamos um programa que criptografa um texto, com o alfabeto das letras min usculas, usando este tipo de criptograa, transformando apenas as letras e deixando os demais s mbolos intactos. program progcifracesar; 6 type tipostring string[100]; procedure criptocesar(var texto,cifra : tipostring; k:integer); var i,tam : integer; begin cifra : 6 ; tam : 6 length(texto); for i: 6 1 to tam do begin if (texto[i] @96 a) and (texto[i] 96 z) then cifra : 6 cifra & chr((ord(texto[i]) 7 ord(a) & k) mod 26 & ord(a)) else cifra : 6 cifra & texto[i]; end ; end; criptocesar var Texto,Cripto : tipostring; begin write(Entre com uma cadeia de caracteres: ); readln(texto); criptocesar(texto,cripto,3); writeln(A texto criptografado e: , cripto); end.

85

Exerc cio 8.3 Fac a um procedimento para decriptografar tendo como dados de entrada a cadeia de caracteres criptografada pelo programa acima e o valor usado de . Os m etodos de substituic a o s ao r apidos, mas pouco seguros. Em geral, cada l ngua possui freq ue ncias diferentes para as ocorr encias de cada letra. Exemplo 8.5 Em um texto em ingl es, temos em geral as seguintes freq ue ncias esperadas para as letras:
r6mF1 t6D% ui6mF1 v6dF1 x6D"F1 y6mF1 {i6D% }6mF1 6m 60Y 60Y 6 6mF1 6mF1 6F1 6F1 6mY 6m 6mF1 06mF1 m6F1 6D%F1 6D% 6mY 6mF1 060Y

Assim, para decriptografar um texto, onde o original e es, calculamos as freq ue mbolos no texto em ingl ncias dos s criptografado e em seguida relacionamos com as freq ue mbolos ncias acima. Isto permite que possamos relacionar os s com os caracteres originais mais prov aveis. Exerc cio 8.4 Fac a um programa que l e um n umero inteiro  , (D e escreve seu valor por extenso. Exemplos:

1 = um 19 = dezenove 20 = vinte 21 = vinte e um 100 = cem 111 = cento e onze 1000 = mil 2345 = dois mil trezentos e quarenta e cinco 9012 = nove mil e doze 12900 = doze mil e novecentos 100101 = cem mil cento e um 110600 = cento e dez mil e seiscentos 999999 = novecentos e noventa e nove mil novecentos e noventa e nove 1000000 = um milh ao

Sugest ao: Escreva func o umeros: es ou procedimentos convenientes que tratam de n


at e9 at e 19 at e 99 at e 999 at e um milh ao

Note que as func o o es para intervalos maiores podem usar as func es para intervalos menores. Pense com cuidado na l ogica do uso da conjunc a o e.

86

8.5 Exerc cios


1. Um programador est a implementando um processador de textos e quer adicionar uma facilidade para a composic a o de cartas, colocando um comando que com apenas os dados da data (dia, m es e ano), apresenta o seguinte cabec alho: es @ de ano @ Dia da semana @ , dia @ de m Ex.: Colocando a data 01/01/1901, temos o seguinte cabec alho: Terc a-feira, 1 de janeiro de 1901 Para implementar esta facilidade, ajude este programador construindo uma func a o que tem como par ametros o dia, o m es e o ano e retorna uma string contendo o cabec alho como no exemplo acima. Considere que as datas est ao no intervalo de 01/01/1901 a 01/01/2099. 2. Pelo calend ario gregoriano, intitu do em 1582 pelo Papa Greg orio XIII, os anos bisextos s ao aqueles cujo ano s ao divis veis por 4, exceto os anos que s ao divis veis por 100 e n ao por 400. Por exemplo, os anos 1600, 2000 s ao anos bisextos enquanto os anos 1700, 1800 e 1900 n ao s ao. Com isto, em mente, resolva o exerc cio anterior para considerar anos a partir de 1600. Obs.: O dia 01/01/1600 e um s abado. 3. O programa apresentado na sec a o 8.4 restringe a criptograa ao alfabeto C### criptografar e decriptografar considerando o alfabeto formado pelo tipo byte. 4. Fac a um programa contendo func o es com os seguintes cabec alhos:
Fd

. Fac a um programa para

function criptografa(str : string; k:integer):tipostring; function decriptografa(str : string; k:integer):tipostring; function maiuscula(str : string):tipostring; function minuscula(str : string):tipostring; function semacentos(str : string):tipostring; function cadeialivre(str : string):tipostring; type tipostring=string[255];

onde tipostring e denido como: As func o es criptografa e decriptografa s ao para criptografar e decriptografar usando a cifra de C esar, com deslousculas. As func o es mai uscula e min uscula s ao para retornar a func a o dada camento e o alfabeto das letras min em mai usculo e min usculo. A func a o semacentos retorna a cadeia de caracteres str sem as letras dos acentos (ela preserva mai usculas e min usculas). A func a o cadeia livre transforma a cadeia de caracteres str em uma cadeia sem acentos e com todos as letras em min usculo. O programa deve ler uma cadeia de caracteres e uma opc a o para uma das seis operac o es acima. Caso a opc a o seja para criptografar ou decriptografar, o par ametro tamb em deve ser lido. Ap os a execuc a o de uma opc a o, a cadeia de caracteres resultante deve ser impressa.

87

Вам также может понравиться