最佳地搜索字符串java中的子字符串

时间:2017-08-27 10:14:22

标签: java android search optimization substring

我有一个电话号码列表,其中可能包含也可能没有国家/地区代码。我从后端服务获得一个数字,该服务始终包含国家/地区代码。所以我最优地找到了与后端服务号码相匹配的号码。

现在我正在做的是:

for(String number : backendNumbers){
    for(Map.Entry<String, String> entry : contactMap.entrySet()){
        if(number.endsWith(entry.getKey()) && entry.getKey().length() > MINIMUM_CONTACT_LENGTH){
            Log.i(TAG, "Found name for "+entry.getKey()+" : "+entry.getKey()+":"+entry.getValue());
            break;
        }
    }
}

联系地图是此类联系人的地图=&lt;&#34; 01710111111&#34;,&#34;某些名称&#34;&gt; - &GT;此密钥可能包含也可能不包含国家/地区代码。在大多数情况下,他们不会。

当我从Backend获得一个总是包含国家代码的数字时:&#34; + 8801710111111&#34;。

现在这种方法的问题是每次我需要该地图时都会产生生成联系人地图的开销。另外,如果我从后端获得每个数字的N个数字,我需要围绕整个联系地图循环以找到名称。

那么我能在这里做得更好?任何建议将不胜感激。

4 个答案:

答案 0 :(得分:0)

对于给定的循环代码,您可以转移到map.keySet()以仅处理字符串键。 否则这种方法没有错,这是您在比较hashmap的值时所需的最小开销。

答案 1 :(得分:0)

  

现在这种方法的问题是每次我需要该地图时都会产生联系地图的开销。

好吧,要么你有一些结构来方便搜索,要么你搜索整个列表。

我要创建一个Map<String, String>的号码来命名。创建地图时,还要计算数字minLength的最小长度。

然后,给定一个后端编号,不仅要查找数字,还要查找长度为minLength的所有后缀。

for (int beginIndex = 0; beginIndex <= (backendNumber.length() - minLength); beginIndex++) {
    String name = nameByNumber.get(backendNumber.substring(beginIndex));
    if (name != null) {
        return name;
    }
}

这将为您提供类似O(后端数量的最大长度 - 最小数字长度)的复杂性。

答案 2 :(得分:0)

假设两个集合都很大,以下可能会得到10倍:

for (char c='0'; c<='9'; ++c) {
    Map<String, String> submap = new Map<>();
    for(Map.Entry<String, String> entry : contactMap.entrySet()) {
        String key = entry.getKey();
        if (key.length() > MINIMUM_CONTACT_LENGTH
              && key.charAt(key.length() - 1) == c) {
          submap.put(key, entry.getValue());
        }
    }
    for(String number : backendNumbers){
        if (!number.isEmpty()
                 && number.charAt(number.length() - 1) == c) {
            for(Map.Entry<String, String> entry : submap.entrySet()) {
                 .... do what you did
            }
        }
    }
}

这个想法很简单:一个字符串只能是另一个字符串的子字符串,如果它们都以相同的字符结尾。所以我相应地拆分了两个集合,并保存了xxxxx1对xxxxx2的测试。

显然,您可以使用两个最后的数字,但这会增加更多的开销。最初的复杂性是O(m*n),这个技巧是O((m+n)*k + (m/k)*(n/k)),其中k是桶的数量。我假设最后一个数字是均匀分布的,它们通常是。

可以做得更好....

答案 3 :(得分:0)

您可以使用和不使用国家/地区代码创建后端数据的地图(不是它总是3个字符?)

Map<String,String> backendMap = new HashMap<>();
for(String number : backendNumbers){
    backendMap.put(number,number);
    backendMap.put(number.substring(3),number);
}

然后你可以简单地在后端地图上找到(或找不到)数字(假设数字的国家代码总是以相同的形式)。