Powershell, вид установленного пересечения встроен? - PullRequest
6 голосов
/ 20 июля 2009

В некоторых играх, где нужно было бы находить анаграммы из набора свободных букв, я в итоге реализовал алгоритм перестановки, чтобы найти все возможные анаграммы и отфильтровать их при необходимости для известных положений букв (кстати, -match отлично ). Но для более длинных слов это оказалось очень подверженным ошибкам, так как просмотр большого списка тарабарщин на самом деле не показывает правильные слова, которые были скрыты внутри.

Так что я подумал, что если у меня будет большой список английских слов (должен быть где-то доступен), я мог бы просто пересечь мой список перестановок со списком правильных слов и получить (надеюсь) все реальные слова из списка перестановок.

Так как многие операторы в PS работают с коллекциями по-разному, я подумал, что могу просто сделать что-то вроде

$wordlist -contains $permlist

и верни пересечение. К сожалению, это не так просто. Другие варианты, о которых я подумал, - перебирать один список и делать -contains для каждого элемента:

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

Это, вероятно, сработало бы, но я думаю, что оно также очень медленное (особенно, когда $wordlist является результатом gc wordlist.txt). Или я мог бы построить гигантское регулярное выражение:

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

Но это, вероятно, тоже было бы не очень быстро. Возможно, я мог бы также использовать findstr с приведенным выше гигантским регулярным выражением, но это просто неправильно.

Есть ли какие-нибудь встроенные решения, которые я мог бы использовать, и которые лучше моих попыток? В противном случае я, вероятно, поместил бы список слов в хеш-таблицу и использовал бы итерационный подход -contains, который должен быть достаточно быстрым.

Ответы [ 2 ]

6 голосов
/ 20 июля 2009
$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)

(заимствуя New-HashSet от Джош Эйнштейн )

Предупреждение: эти методы в HashSet являются алгоритмами на месте, которые модифицируют исходную коллекцию. Если вы хотите преобразование в функциональном стиле на неизменяемых объектах, вам нужно принести LINQ на вечеринку:

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))

Очевидно, что кто-то должен обернуть это дерьмо статическим отражением в дружественный командлет! Не волнуйся, я работаю над этим ...

0 голосов
/ 20 июля 2009

Вы можете проверить орфографию в своем списке слов и устранить все орфографические ошибки в стандартном словаре.

С установленным пакетом GNU aspell,

 cat text.txt | aspell list

выдаст вам список всех слов, написанных с ошибками.
Вы можете работать с другими словарями с aspell.


Или просто возьмите генератор анаграммы , подобный этому, созданный для игроков в Эрудит .

Revolution Word Finder имеет две опции; Anagram Finder и Scrabble Solver. Anagram Finder берет список букв и возвращает все действительные анаграммы, которые могут быть созданы с их использованием относительно фиксированного списка слов. Каждая анаграмма проверяется на соответствие списку слов SOWPODS , который является списком слов, используемым в текущих международных турнирах по скрэббл.

...