Para classificar as letras, linha por linha, em um arquivo, você pode fazer algo assim:
while read line; do
grep -o . <<< "${line}" | sort | tr -d '\n'
echo
done < file.dic
Saída:
abc
adorw
bdorw
abc
adorw
dorwzzz
Eu tenho algum dicionário para myspell em file.dic
. Vamos dizer:
abc
aword
bword
cab
worda
wordzzz
e estou procurando palavras diferentes que sejam permutações (ou anagramas) uma da outra.
Se houvesse um comando "letter-sort" eu faria mais ou menos assim:
cat file.dic | letter-sort | paste - file.dic | sort
Isso me dá:
abc abc
abc cab
adorw aword
adorw worda
bdorw bword
dorwzzz wordzzz
agora vejo claramente os anagramas no arquivo. Existe tal comando letters-sort
ou como obter tal resultado talvez de alguma outra forma?
Você pode usar o comando fold
para dividir uma string em uma matriz de caracteres individuais, como o script abaixo
#!/bin/bash
CHARS='echo $1 | fold -w1'
# $CHARS now contain an array of single character in the string $1
for i in "${CHARS[@]}"
do
# do something with each character
echo $i;
done
Supondo que você salvou o script acima como test.sh
, é possível executá-lo da seguinte maneira:
$./test.sh abcde
e vai quebrar a string "abcde" em uma matriz de caracteres, que você pode usar para encontrar seus anagramas.
Você mencionou python
, mas fique com python
. Duas palavras são anagramas uma da outra se 1. contiverem as mesmas letras e 2. correspondências de letras. A classe Counter
integrada pode ser usada para fazer frequências de letras de uma só passagem, sem a necessidade de ordenação
from __future__ import print_function
from collections import Counter, defaultdict
from itertools import combinations_with_replacement
with open('file') as f:
data = (l.rstrip('\n') for l in f)
data = ((l, Counter(l)) for l in data)
perms = defaultdict(list)
for l, c in data:
perms[frozenset(c.iteritems())].append(l)
for anagrams in perms.itervalues():
print(*anagrams)
bword
aword worda
abc cab
wordzzz
Perl com seus flags de linha de comando pode ser muito bom em ser sucinto:
O comando a seguir classifica as letras em uma palavra
perl -CS -ne 'chomp; print(join("", sort(split("", $_ . "\n"))))'
Na prática, se você estiver trabalhando com anagramas, talvez prefira usar o utilitário an
. Isso pode levar um dicionário como argumento:
an -d /usr/share/dict/ngerman Anagramword