domingo, 28 de novembro de 2010

Problema 5.22

Contar o número de caracteres, palavras e linhas num texto é um exercício interessante. Na sua aparente simplicidade coloca vários desafios, obrigando-nos a pensar nas diferentes situações que envolvem espaços em branco e mudanças de linha. Vamos mostrar várias soluções, algumas passam por simplificar o problema, um método que é de grande utilidade.

Vejamos uma primeira solução a que chamamos ingénua, pois parte da ideia de que o caracter ‘\n’ indica uma linha e um espaço em branco indica uma palavra.


def wc(texto):
"""Calcula o número de linhas, palavras e caracteres num texto. Não inclui
espaços em branco. Versão ingénua!!!!"""
num_caracteres = 0
num_palavras = 0
num_linhas = 0
for car in texto:
if car == '\n':
num_linhas = num_linhas + 1
elif car == ' ':
num_palavras = num_palavras + 1
else:
num_caracteres = num_caracteres + 1
return (num_caracteres, num_palavras, num_linhas)

Agora uma versão mais sofisticada.

def wc_2(texto):
"""Calcula o número de linhas, palavras e caracteres num texto.
Não inclui espaços em branco"""
num_caracteres = 0
num_palavras = 0
num_linhas = 0
comp_texto = len(texto)
posicao = 0
while posicao < comp_texto:
# analisa por casos
while (posicao < comp_texto ) and (texto[posicao] == ' '):
posicao = posicao + 1

while (posicao < comp_texto ) and (texto[posicao] == '\n'):
num_linhas = num_linhas + 1
posicao = posicao + 1

while (posicao < comp_texto) and (texto[posicao] != ' ') and (texto[posicao] != '\n'):
enc_car = True
num_caracteres = num_caracteres + 1
posicao = posicao + 1

if enc_car:
num_palavras = num_palavras +1
enc_car = False
return (num_caracteres, num_palavras, num_linhas)

Neste caso tratamos de modo mais claro várias linhas em branco ou vários espaços em branco consecutivos.

Mas será que precisamos de complicar assim tanto? Felizmente não! Basta saber um pouco mais sobre os métodos que se aplicam a cadeias de caracteres.... Então se pudermos usar split e splitlines:

def wc_3(texto):
"""Devolve o número de caracteres, palavras e linhas em texto. Inclui espaços em branco."""
return (len(texto.replace('\n','')), len(texto.split()), len(texto.splitlines()))

def wc_4(texto):
"""Devolve o número de caracteres, palavras e linhas em texto. Não inclui espaços em branco."""
texto_aux = texto.replace(' ','') # assim não inclui espaços em branco
return (len(texto_aux.replace('\n','')), len(texto.split()), len(texto.splitlines()))

Nestas duas versões a segunda não conta os espaços em branco. Atente-se que tivemos que criar uma cópia do texto original, o que, com ficheiros grandes não é muito simpático.

Sem comentários:

Enviar um comentário