首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >寻找所有“字符相等”字符串的有效算法?

寻找所有“字符相等”字符串的有效算法?
EN

Stack Overflow用户
提问于 2013-08-05 13:57:15
回答 1查看 542关注 0票数 5

如何编写输出输入字符串的"同型等价物“的有效函数?

示例1 (伪代码):

代码语言:javascript
复制
homoglyphs_list = [
                     ["o", "0"], // "o" and "0" are homoglyphs
                     ["i", "l", "1"] // "i" and "l" and "1" are homoglyphs
                  ]

input_string    = "someinput"
output          = [
                   "someinput", "s0meinput", "somelnput",
                   "s0melnput", "some1nput", "s0me1nput"
                  ]

示例2

代码语言:javascript
复制
homoglyphs_list = [
                     ["rn", "m", "nn"],
                  ]

input_string    = "rnn"
output          = ["rnn", "rm", "mn", "rrn", "nnn", "nm", "nrn"]

示例3

代码语言:javascript
复制
homoglyphs_list = [
                     ["d", "ci", "a"], // "o" and "0" are homoglyphs
                     ["i", "l", "1"] // "i" and "l" and "1" are homoglyphs
                  ]
                  /*
                     notice that with the two rules above,
                     we can infer "d" = "ci" = "a" = "cl" = "c1"
                  */

input_string    = "pacerier"
output          = [
                   "pacerier",  "pacerler",  "pacer1er",  "pcicerier",
                   "pcicerler", "pcicer1er", "pclcerier", "pc1cerier",
                   "pclcerler", "pc1cerler", "pclcer1er", "pc1cer1er",
                   "pdcerier",  "pdcerler",  "pdcer1er"
                  ]

注意:输出数组中成员的顺序并不重要,我们可以假设给定的同型类型映射是适当的(输入不会给我们一个“无限循环”)。

我现在的算法很好用,但是它使用的是原始的蛮力,性能很差。例如,用同型"mmmmm"输入["rn", "m", "nn"]需要38秒才能运行:

代码语言:javascript
复制
// This is php code (non-pseudo just so we could test the running time), 
// but the question remains language-agnostic

public function Func($in, Array $mappings){
    $out_table = array();
    $out_table[$in] = null;
    while(true){
        $number_of_entries_so_far = count($out_table);
        foreach(array_keys($out_table) as $key){
            foreach($mappings as $mapping){
                foreach($mapping as $value){
                    for($a=0, $aa=strlen($key); $a<$aa; ++$a){
                        $pos = strpos($key, $value, $a);
                        if($pos === false){
                            continue;
                        }
                        foreach($mapping as $equal_value){
                            if($value === $equal_value){
                                continue;
                            }
                            $out_table[substr($key, 0, $pos) . $equal_value . substr($key, $pos + strlen($value))] = null;
                        }
                    }

                }
            }
        }
        if($number_of_entries_so_far === count($out_table)){
            // it means we have tried bruteforcing but added no additional entries,
            // so we can quit now
            break;
        }
    }
    return array_keys($out_table);
}

如何实现高效(快速)同型扩展算法?

EN

回答 1

Stack Overflow用户

发布于 2013-08-20 20:13:24

您应该从递归实现中获得一些性能,虽然我还没有对实际的性能进行过多的考虑。这将避免多次遍历输出字符串并计算每次迭代的输出数。此外,我还添加了一个小的“缓存”,以防止计算相同的同型类型两次,为了简单起见,它不检查映射,但您可以将它实现到,或者在每次调用更改映射之前清除缓存(但这很难看,很容易引入bug)。

代码看起来如下:

代码语言:javascript
复制
cache = {}
def homoglyph(input_string, mappings):
    output = []
    character = input_string[0]
    if input_string in cache:
        return cache[input_string]
    elif not input_string:
        return []
    for charset in mappings:
        if character in charset:
            temp = input_string
            sub_homoglyphs = homoglyph(input_string[1:], mappings)
            for char in charset:
                temp[0] = char
                output.append(temp)
                #adding the homoglyph character to the rest of the string
                for subhomoglyph in sub_homoglyphs:
                    output.append(char+subhomoglyph)
    cache[input_string] = output
    return output

(这是用python编写的,因为我不熟悉php语法,所以我还没有真正运行它,所以可能会出现错误,但逻辑的要点是存在的)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18060037

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档