Вот решение в Python на основе программирования с использованием ограничительного языка:
from constraint import AllDifferentConstraint, InSetConstraint, Problem
# variables
colors = "blue red green white yellow".split()
nationalities = "Norwegian German Dane Swede English".split()
pets = "birds dog cats horse zebra".split()
drinks = "tea coffee milk beer water".split()
cigarettes = "Blend, Prince, Blue Master, Dunhill, Pall Mall".split(", ")
# There are five houses.
minn, maxn = 1, 5
problem = Problem()
# value of a variable is the number of a house with corresponding property
variables = colors + nationalities + pets + drinks + cigarettes
problem.addVariables(variables, range(minn, maxn+1))
# Each house has its own unique color.
# All house owners are of different nationalities.
# They all have different pets.
# They all drink different drinks.
# They all smoke different cigarettes.
for vars_ in (colors, nationalities, pets, drinks, cigarettes):
problem.addConstraint(AllDifferentConstraint(), vars_)
# In the middle house they drink milk.
#NOTE: interpret "middle" in a numerical sense (not geometrical)
problem.addConstraint(InSetConstraint([(minn + maxn) // 2]), ["milk"])
# The Norwegian lives in the first house.
#NOTE: interpret "the first" as a house number
problem.addConstraint(InSetConstraint([minn]), ["Norwegian"])
# The green house is on the left side of the white house.
#XXX: what is "the left side"? (linear, circular, two sides, 2D house arrangment)
#NOTE: interpret it as 'green house number' + 1 == 'white house number'
problem.addConstraint(lambda a,b: a+1 == b, ["green", "white"])
def add_constraints(constraint, statements, variables=variables, problem=problem):
for stmt in (line for line in statements if line.strip()):
problem.addConstraint(constraint, [v for v in variables if v in stmt])
and_statements = """
They drink coffee in the green house.
The man who smokes Pall Mall has birds.
The English man lives in the red house.
The Dane drinks tea.
In the yellow house they smoke Dunhill.
The man who smokes Blue Master drinks beer.
The German smokes Prince.
The Swede has a dog.
""".split("\n")
add_constraints(lambda a,b: a == b, and_statements)
nextto_statements = """
The man who smokes Blend lives in the house next to the house with cats.
In the house next to the house where they have a horse, they smoke Dunhill.
The Norwegian lives next to the blue house.
They drink water in the house next to the house where they smoke Blend.
""".split("\n")
#XXX: what is "next to"? (linear, circular, two sides, 2D house arrangment)
add_constraints(lambda a,b: abs(a - b) == 1, nextto_statements)
def solve(variables=variables, problem=problem):
from itertools import groupby
from operator import itemgetter
# find & print solutions
for solution in problem.getSolutionIter():
for key, group in groupby(sorted(solution.iteritems(), key=itemgetter(1)), key=itemgetter(1)):
print key,
for v in sorted(dict(group).keys(), key=variables.index):
print v.ljust(9),
print
if __name__ == '__main__':
solve()
Вывод:
1 yellow Norwegian cats water Dunhill
2 blue Dane horse tea Blend
3 red English birds milk Pall Mall
4 green German zebra coffee Prince
5 white Swede dog beer Blue Master
требуется 0,6 секунды (ЦП 1.5 ГГц) для нахождения решения.
ответ является "немецким языком, владеет зеброй".
Для установки constraint
модуль через pip
: победите ограничение Python установки
Для установки вручную:
загрузка:
(Linux/Mac/BSD):
$ bzip2 - CD python-constraint-1.2.tar.bz2 | tar xvf -
извлечение (Windows, с 7zip ):
> 7z e python-constraint-1.2.tar.bz2
> 7z установка e python-constraint-1.2.tar
:
Python cd python-constraint-1.2
$ $ setup.py установка
См. Perl Lingua :: EN :: Words2Nums и Lingua :: EN :: FindNumber .
В частности, исходный код для Lingua :: EN :: FindNumber
содержит:
# This is from Lingua::EN::Words2Nums, after being thrown through
# Regex::PreSuf
my $numbers =
qr/((?:b(?:akers?dozen|illi(?:ard|on))|centillion|d(?:ecilli(?:ard|on)|ozen|u(?:o(?:decilli(?:ard|on)|vigintillion)|vigintillion))|e(?:ight(?:een|ieth|[yh])?|leven(?:ty(?:first|one))?|s)|f(?:i(?:ft(?:een|ieth|[yh])|rst|ve)|o(?:rt(?:ieth|y)|ur(?:t(?:ieth|[yh]))?))|g(?:oogol(?:plex)?|ross)|hundred|mi(?:l(?:ion|li(?:ard|on))|nus)|n(?:aught|egative|in(?:et(?:ieth|y)|t(?:een|[yh])|e)|o(?:nilli(?:ard|on)|ught|vem(?:dec|vigint)illion))|o(?:ct(?:illi(?:ard|on)|o(?:dec|vigint)illion)|ne)|qu(?:a(?:drilli(?:ard|on)|ttuor(?:decilli(?:ard|on)|vigintillion))|in(?:decilli(?:ard|on)|tilli(?:ard|on)|vigintillion))|s(?:core|e(?:cond|pt(?:en(?:dec|vigint)illion|illi(?:ard|on))|ven(?:t(?:ieth|y))?|x(?:decillion|tilli(?:ard|on)|vigintillion))|ix(?:t(?:ieth|y))?)|t(?:ee?n|h(?:ir(?:t(?:een|ieth|y)|d)|ousand|ree)|r(?:e(?:decilli(?:ard|on)|vigintillion)|i(?:gintillion|lli(?:ard|on)))|w(?:e(?:l(?:fth|ve)|nt(?:ieth|y))|o)|h)|un(?:decilli(?:ard|on)|vigintillion)|vigintillion|zero|s))/i;
в соответствии с художественной лицензией Perl .
Вы можете использовать Regex :: PreSuf для автоматически вычеркивает общие пре- и суффиксы:
#!/usr/bin/perl
use strict;
use warnings;
use Regex::PreSuf;
my %singledigit = (
one => 1,
two => 2,
three => 3,
four => 4,
five => 5,
six => 6,
seven => 7,
eight => 8,
nine => 9,
);
my $singledigit = presuf(keys %singledigit);
print $singledigit, "\n";
my $text = "one two three four five six seven eight nine";
$text =~ s/($singledigit)/$singledigit{$1}/g;
print $text, "\n";
Вывод:
C:\Temp> cvb (?:eight|f(?:ive|our)|nine|one|s(?:even|ix)|t(?:hree|wo)) 1 2 3 4 5 6 7 8 9
Боюсь, после этого станет труднее; -)
Создайте сценарий bash с именем client.sh:
#!/bin/bash
cat someFile
while read FOO; do
echo $FOO >&3
if [[ $FOO =~ `printf ".*\x00\x1c.*"` ]]; then
break
fi
done
. Затем вызовите netcat из основного сценария следующим образом:
3>&1 nc -c ./client.sh somehost 1234
(Для сопоставления регулярных выражений вам понадобится версия 3 bash).
Предполагается, что сервер отправляет данные по строкам - в противном случае вам придется настроить client.sh так, чтобы он считывал и отображал символ за раз.
Вы можете увидеть примеры вывода Regexp :: Assemble, Regexp :: List, Regexp :: Optimizer и Regex :: PreSuf в http://groups.google.com/group/perl.perl5.porters/msg/ 132877aee7542015 . Начиная с perl 5.10, perl сам обычно оптимизирует списки |
d точных строк в дерево. Что вы пытаетесь сделать и какой алгоритм вы используете?
Я не знаком с механизмом регулярных выражений Java, но с другими механизмами регулярных выражений, которые я использовал (Perl, awk) позволяют снимать матчи. Например, если вы пытаетесь сопоставить:
один миллион сто тысяч сто один
У вас может быть регулярное выражение, которое может идентифицировать миллион, все, что перед ним (например, «один»), и все, что после него (т.е. «сто тысяч сто один»). То, что было раньше, будет захвачено для дополнительного сопоставления (с использованием ваших регулярных выражений сотен, десятков и единиц), а вещи после него будут захвачены для дополнительного сопоставления (с использованием вашего регулярного выражения тысяч, сотен регулярных выражений, десятков регулярных выражений или регулярных выражений единиц).
Этот алгоритм естественно рекурсивен, и его несложно реализовать.
Regex действительно плохой способ сделать это. Лично я просто создал бы небольшую карту всех известных слов и стал бы искать таким образом. (Найдите каждое слово, когда вы найдете совпадение, определите, совпадают ли слова рядом с ним, и продолжайте так, пока не получите номер).