Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

NEDM64

Alguém que perceba disto melhor que eu? (strings)

Mensagens Recomendadas

NEDM64

Boas, eu queria começar a programar numa linguagem nova, nomeadamente Python, e tenho já um hackzito a funcionar bem que andei a aprender olhando para exemplos (uma das vantagens destas linguagens populares). ;) sei que não é a maneira correta de aprender, mas precisava mesmo de uma linguagem como o python para desenrascar o que eu queria...

Agora queria outro "hackzito" mais dificil... alguém me possa dar umas luzes?

Básicamente tenho dois sets de strings:

Tenho no grupo A várias Strings

Tenho no grupo B outras várias Strings (mais)

Queria, para cada string do grupo A, encontrar a mais parecida do grupo B!

Sendo que string A, pode estar corrompida...

Por exemplo, no B tenho foo, bar

E no A, posso ter f00, sendo que esta vai para foo e não para bar...

As strings do grupo A e B são mutuamente exclusivas...

Há alguma maneira rápida de fazer isto?

Obrigado

Editado por NEDM64

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Pedro C.

Bem o rápido depende do nível de pormenor que exigires do teu algoritmo. Tens várias bibliotecas para trabalhar e comparar strings. Este link do stackoverflow fala de pelo menos três:

http://stackoverflow.com/questions/682367/good-python-modules-for-fuzzy-string-comparison

Provavelmente farão aquilo que pretendes em recurso a um comando directo no entanto terias de primeiro conhecer a biblioteca ou então conseguires encontrar alguém que tenha passado pelo mesmo problema, solucionado, documentado e publicado na Internet (ou na biblioteca mais próxima :) ). Pessoalmente muito pouco fiz para este tipo de programação no que toca a strings mas a nível da matemática já mexi com coeficientes de semelhança ou distâncias especiais para conjuntos não numéricos. Utilizando a biblioteca de python nativo difflib (que aparece no link acima) posso fazer:

# IMPORT A BIBLIOTECA DIFFLIB
import difflib as dl

# FACO UMA FUNCAO PARA COMPARAR UMA STRING A UMA LISTA DE STRINGS E
# DEVOLVO AQUELA QUE E MAIS PROXIMA SEGUNDO O SEQUENCE MATCHER DO
# DIFFLIB
def compare_strings(string,compare_set):
 values = []
 for i in xrange(len(compare_set)):
	  values.append(dl.SequenceMatcher(None,string,compare_set[i]).ratio())
 index = values.index(max(values))
 print 'Closest to ',string,' is ',compare_set[index]
 return compare_set[index]

# UMA LISTA EXEMPLO PARA TESTAR O PROGRAMA
B = ['fuubar','boofarv','f00bar','barbvar']

# COMPARO foobar COM A LISTA EXEMPLO
compare_strings('foobar',B)

O resultado da experiência a cima é:

Closest to foobar is fuubar

Agora tu queres meter outras restrições segundo percebi, por exemplo os zeros (0) servirem de "o". Pessoalmente se quisesse despachar o assunto começaria por fazer função para limpar a string antes de a comparar:

# IMPORT A BIBLIOTECA DIFFLIB
import difflib as dl

# LIMPAR STRING CORRUPTAS
def clean_string(string):
if '0' in string:
	string = string.replace('0','o')
return string

# FACO UMA FUNCAO PARA COMPARAR UMA STRING A UMA LISTA DE STRINGS E
# DEVOLVO AQUELA QUE E MAIS PROXIMA SEGUNDO O SEQUENCE MATCHER DO
# DIFFLIB
def compare_strings(string,compare_set):
values = []
for i in xrange(len(compare_set)):
	# ALTERACAO PARA CONSEGUIR LIMPAR STRING ANTES DE A COMPARAR
	new_string = clean_string(compare_set[i])
	values.append(dl.SequenceMatcher(None,string,new_string).ratio())
index = values.index(max(values))
print 'Closest to ',string,' is ',compare_set[index]
return compare_set[index]

# UMA LISTA EXEMPLO PARA TESTAR O PROGRAMA
B = ['fuubar','boofarv','f00bar','barbvar']

# COMPARO foobar COM A LISTA EXEMPLO
compare_strings('foobar',B)

O resultado passou a ser:

Closest to foobar is f00bar

Claro que neste caso seria preciso fazer funções especiais para cada caso especifico de corrupção de uma string. De qualquer maneira espero que ajude. Se tiveres problemas em algum comando avisa. Para não deixar no ar:

1) o comando replace serve para substituir o caracter que aparece primeiro pelo que aparece em segundo nessa função.

2) o comando index serve para saberes em que indice se encontra o elemento que pretendes (ele dá o primeiro que encontra), neste caso o que teve o racio maximo no sequence matcher.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.