1

我实现了打字训练器,并想startsWith()用特定的规则创建我的特殊 String 方法。例如:'-'char 应该等于任何长连字符('‒'等)。此外,我将为特殊重音字符添加其他规则(e 等于é,但不é等于 e)。

public class TestCustomStartsWith {
    private static Map<Character, List<Character>> identityMap = new HashMap<>();
    static { // different hyphens: ‒, –, —, ―
        List<Character> list = new LinkedList<>();
        list.add('‒');
        list.add('–'); // etc
        identityMap.put('-', list);
    }

    public static void main(String[] args) {
        System.out.println(startsWith("‒d--", "-"));
    }

    public static boolean startsWith(String s, String prefix) {
        if (s.startsWith(prefix)) return true;
        if (prefix.length() > s.length()) return false;
        int i = prefix.length();
        while (--i >= 0) {
            if (prefix.charAt(i) != s.charAt(i)) {
                List<Character> list = identityMap.get(prefix.charAt(i));
                if ((list == null) || (!list.contains(s.charAt(i)))) return false;
            }
        }
        return true;
    }
}

我可以用char替换各种长连'-'字符,但是如果有更多规则,恐怕替换会太慢。


我该如何改进这个算法?

4

2 回答 2

0

我认为类似于HashMap的东西可以将不需要的字符映射到您希望它们被解释的内容,如果您担心性能,这可能是可行的方法;

HashMap<Character, Character> fastMap = new Map<Character, Character>();

// read it as '<long hyphen> can be interpreted as <regular-hyphen>
fastMap.add('–', '-');
fastMap.add('é', 'e');
fastMap.add('è', 'e');
fastMap.add('?', '?');
...
// and so on

这样你就可以要求 key: 的值value = map.get(key)

  • 但是,这仅在您拥有唯一键值的情况下才有效。需要注意的是,é不能用这种方法解释为è - 所有的键都必须是唯一的。但是,如果您担心性能,这是一种非常快速的方法,因为 HashMap 的查找时间非常接近 O(1)。但是正如本页上的其他人所写的那样,过早的优化通常是一个坏主意 - 尝试先实现一些可行的东西,如果在最后你发现它太慢了,那么就进行优化。
于 2013-11-18T21:55:05.970 回答
0

我不知道您所有的自定义规则,但是正则表达式会起作用吗?

用户正在传递一个字符串。创建一个方法将该字符串转换为正则表达式,例如

  1. 用短或长 ([-‒]) 替换短连字符,
  2. 你的口音也一样,e 变成 [eé]
  3. 以单词 dohicky (\b) 开头,

然后将其转换为正则表达式并试一试。

请注意,替换列表可以按照 Tobbias 的建议保存在 Map 中。您的代码可能类似于

public boolean myStartsWith(String testString, String startsWith) {

    for (Map.Entry<String,String> me : fancyTransformMap) {
       startsWith = startsWith.replaceAll(me.getKey(), me.getValue());
    }

    return testString.matches('\b' + startsWith);
}

ps 我不是正则表达式超级大师,所以如果可能有改进的话。

于 2013-11-19T01:18:44.557 回答