2009-07-20 7 views
6

Pour un jeu où l'on aurait besoin de trouver des anagrammes à partir d'un tas de lettres, j'ai fini par implémenter un algorithme de permutation pour trouver tous les anagrammes possibles et les filtrer si nécessaire pour les positions de lettres connues (-match). Mais pour des mots plus longs, cela s'est avéré très sujet aux erreurs, car écrémer une grande liste de charabia ne révèle pas vraiment les mots appropriés qui étaient cachés à l'intérieur.Powershell, type d'intersection encastrée?

donc je pensais que si j'aurais une grande liste de mots anglais (qui devrait être obtenir quelque part) Je pouvais recouper juste ma liste des permutations avec la liste des mots appropriés et d'obtenir (je l'espère) Tous les mots de la liste de permutation.

Depuis de nombreux opérateurs dans le travail de PS différemment avec des collections je pensais que je pouvais faire quelque chose comme

$wordlist -contains $permlist 

et obtenir l'intersection arrière. Malheureusement, ce n'est pas si facile. D'autres options que j'ai pensé seraient à itérer sur une liste et faire une -contains pour chaque élément:

$permlist | ? { $wordlist -contains $_ } 

Cela marcherait probablement, mais est aussi très lent, je pense (surtout quand $wordlist est le résultat d'une gc wordlist.txt). Ou je pourrais construire une expression régulière gigantesque:

$wordlist -matches (($permlist | %{ "^$_`$" }) -join "|") 

Mais ce ne serait probablement pas très rapide non plus. Je pourrais peut-être également utiliser findstr avec regex gigantesque ci-dessus, mais cela se sent tout simplement faux.

Y a-t-il des solutions intégrées que je pourrais utiliser et qui sont meilleures que mes tentatives jusqu'ici? Sinon, je mettrais probablement la liste de mots dans une table de hachage et j'utiliserais l'approche itérative -contains qui devrait être assez rapide.

Répondre

6
$left = New-HashSet string 
$left.Add("foo") 
$left.Add("bar") 
$right = New-HashSet string 
$right.Add("bar") 
$right.Add("baz") 

$left.IntersectWith($right) 
$left.UnionWith($right) 

(Nouvelle-HashSet empruntent de Josh Einstein)

Attention: ces méthodes sur les algorithmes HashSet sont en place qui modifient la collection originale.Si vous voulez style fonctionnel transformer des objets immuables, vous devrez apporter LINQ au parti:

add-type system.core 

$asqueryable = [system.linq.queryable].getmethods() | ? { $_.name -eq "AsQueryable" } | select -first 1 
$asqueryable = $asqueryable.MakeGenericMethod([string]) 
$leftAsQueryable = $asqueryable.Invoke($null, (,$left)) 

$intersect = [system.linq.queryable].getmethods() | ? { $_.name -eq "Intersect" } | select -first 1 
$intersect = $intersect.MakeGenericMethod([string]) 
$result = $intersect.Invoke($null, ($leftAsQueryable, $right)) 

Il est clair que quelqu'un a besoin d'envelopper cette merde réflexion statique générique dans une applet de commande convivial! Ne vous inquiétez pas, je travaille dessus ...

+0

Ok, ça aurait été à propos de mon approche. Certainement pas joli. (Et certainement pas bien adapté pour une utilisation déballée de la cmdline lui-même). – Joey

0

Vous pouvez vérifier l'orthographe de votre liste de mots et éliminer toutes les fautes d'orthographe par rapport à un dictionnaire standard.

Avec le paquet GNU aspell installé,

cat text.txt | aspell list 

vous donnera une liste de tous les mots épeautre manquer. Vous pouvez travailler avec d'autres dictionnaires avec aspell.


Ou simplement prendre un anagram generator like this one made for Scrabble players.

Le Révolution Word Finder a deux options; un chercheur d'anagramme et un solveur de Scrabble. Le Finder Anagramme prend une liste de lettres et renvoie toutes les anagrammes valides qui peuvent être créées en les utilisant par rapport à une liste fixe de mots. Chaque anagramme est vérifié pour la validité par rapport à la liste de mots SOWPODS qui est la liste de mots utilisée dans les tournois internationaux de Scrabble actuels.

+0

"Vous pouvez épeler votre liste de mots et éliminer toutes les fautes d'orthographe par rapport à un dictionnaire standard." Eh bien, c'est exactement ce que j'essayais. Toutefois, cela ne me dit rien sur la façon d'y parvenir, en évitant au moins partiellement ma question. – Joey

+0

Désolé, je ne voulais pas coté votre point de contrôle orthographique, j'ai ajouté une référence sur ce que je voulais dire. Je disais que vous avez des outils standard pour faire la liste de correspondance. – nik

+0

Hmm, c'est vrai, mais ce n'est pas vraiment une solution "Powershell intégrée". Je pourrais probablement aussi contraindre le vérificateur d'orthographe Office à travailler, mais c'est probablement au-delà de ce que je serais prêt à faire pour cela. Me donner aussi une liste de mots mal orthographiés ne m'aidera pas car je préfère avoir une liste de mots correctement épelés :) (Le jeu en question est http://www.kongregate.com/games/Morpheme/ blocs sur des lettres et dans certains niveaux j'ai eu du mal à trouver le mot que j'avais besoin de construire, c'est pourquoi j'ai décidé de forcer toutes les permutations et de chercher des mots dans la liste qui en résulte – Joey