Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 使用模式生成合理的字符串_String_Design Patterns_Pattern Matching - Fatal编程技术网

String 使用模式生成合理的字符串

String 使用模式生成合理的字符串,string,design-patterns,pattern-matching,String,Design Patterns,Pattern Matching,我有一个字符串表(大约100000个),格式如下: pattern , string e、 g- *l*ph*nt , elephant c*mp*t*r , computer s*v* , save s*nn] , sunny ]*rr] , worry 为了简化,假设a*表示元音,辅音保持不变,]表示“y”或“w”(例如,音韵学中的半元音/圆元音) 给定一个模式,生成可能的可感知字符串的最佳方法是什么?一个合理的字符串被定义为一个字符串,该字符串在数据集中具有其连续的两个字母子字符串中的

我有一个字符串表(大约100000个),格式如下:

pattern , string
e、 g-

*l*ph*nt , elephant
c*mp*t*r , computer
s*v* , save
s*nn] , sunny
]*rr] , worry
为了简化,假设a
*
表示元音,辅音保持不变,
]
表示“y”或“w”(例如,音韵学中的半元音/圆元音)

给定一个模式,生成可能的可感知字符串的最佳方法是什么?一个合理的字符串被定义为一个字符串,该字符串在数据集中具有其连续的两个字母子字符串中的每一个,这些子字符串在模式中没有指定

e、 g-

*l*ph*nt , elephant
c*mp*t*r , computer
s*v* , save
s*nn] , sunny
]*rr] , worry
你好,你好,霍拉

“hallo”是合理的,因为“ha”、“al”、“lo”可以在数据集中看到,就像“have”、“alway”、“low”一样。不考虑这两个字母“ll”,因为它是在模式中指定的

有哪些简单有效的方法可以做到这一点? 是否有实现这一目标的库/框架


我没有特定的语言,但更喜欢在这个程序中使用java。

由于两个字母子字符串的可能性不多,您可以遍历数据集并生成一个表,其中包含每两个字母子字符串的计数,因此该表将如下所示:

ee    1024 times
su    567 times
...
xy    45 times
xz    0 times
该表将很小,因为您只需要存储大约26*26=676个值

您只需对数据集执行一次此操作(如果数据集是动态的,则每次更改表时都要更新该表),并且可以使用该表评估可能的字符串。例如,在您的示例中,添加'ha'、'al'和'lo'的值以获得字符串'hallo'的“分数”。然后,选择得分最高的字符串


请注意,可以通过检查较长的子字符串(例如三个字母)来提高评分,但这也会导致较大的表。

这特别适用于Pythonitertoolssetre操作:

import re
import itertools

VOWELS      = 'aeiou'
SEMI_VOWELS = 'wy'
DATASET     = '/usr/share/dict/words'
SENSIBLES   = set()

def digraphs(word, digraph=r'..'):
    '''
    >>> digraphs('bar')
    set(['ar', 'ba'])
    '''
    base = re.findall(digraph, word)
    base.extend(re.findall(digraph, word[1:]))
    return set(base)

def expand(pattern, wildcard, elements):
    '''
    >>> expand('h?', '?', 'aeiou')
    ['ha', 'he', 'hi', 'ho', 'hu']
    '''
    tokens = re.split(re.escape(wildcard), pattern)
    results = set()
    for perm in itertools.permutations(elements, len(tokens)):
        results.add(''.join([l for p in zip(tokens, perm) for l in p][:-1]))
    return sorted(results)

def enum(pattern):
    not_sensible = digraphs(pattern, r'[^*\]]{2}')
    for p in expand(pattern, '*', VOWELS):
        for q in expand(p, ']', SEMI_VOWELS):
            if (digraphs(q) - not_sensible).issubset(SENSIBLES):
                print q

## Init the data-set (may be long...)
## you may want to pre-compute this
## and adapt it to your data-set.
for word in open(DATASET, 'r').readlines():
    for digraph in digraphs(word.rstrip()):
        SENSIBLES.add(digraph)

enum('*l*ph*nt')
enum('s*nn]')
enum('h*ll*')

谢谢你,施奈德。这道题中我的字母表不是英语,而是一个大得多的字母表。例如,它还包括重音字母。(像a,á,ã,å,å,ă,ą——更像是一个扩展的拉丁字母表——我使用的是Unicode)。我的目标是优化性能和最少的内存使用。无论如何,我将尝试看看子字符串表变得有多糟糕。您应该在前面提到字母表的大小,但是这个解决方案可以扩展。作为记录,它在1.6ms内产生60'*l*ph*nt',在0.5ms内产生20'*h*ll*(dict中有98569个单词)。这是一个很好的解决方案。花了一些时间来理解它(我对Python比较陌生)。这就是我一直在寻找的东西。谢谢你@fra。