带有自定义规则的java startsWith()方法

时间:2013-11-18 20:43:47

标签: java string startswith

我实现了输入训练器,并希望使用特定规则创建我的特殊String startsWith()方法。 例如:'-' 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替换所有种类的长连字符,但如果有更多规则,我担心替换会太慢。


如何改进此算法?

2 个答案:

答案 0 :(得分: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

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

  • 但是,只有拥有唯一键值时,这才有效。需要注意的是,使用此方法é无法解释为è - 所有键必须是唯一的。但是,如果您担心性能,这是一种非常快速的方法,因为HashMap的查找时间非常接近于O(1)。但是正如本页面上的其他人所写的那样,过早优化往往是一个坏主意 - 尝试实现首先运行的东西,如果在它结束时你发现它太慢了,那么然后优化。

答案 1 :(得分:0)

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

用户传入String。创建一个方法将该String转换为正则表达式,例如

  1. 用短或长([ - ]),
  2. 替换短连字符
  3. 相同的口音,e成为[eé]
  4. 以dohicky(\ b),
  5. 开头

    然后将其转换为正则表达式并开始使用。

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

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

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