2011-11-19 148 views
5

我想写一个方法,将返回一个代码对应于我需要传递给Web服务的银行产品。我有一系列合格的通用类型的产品,输入将是一个字符串,它将成为数组中任何通用类型的特定类型。让我通过我已经有的代码来解释:最大匹配字符串

public static void main(String[] args) 
{ 
    String[] names = { "Checking", "Savings", "DEMAT", "DEMAT Savings", "Interest Checking" }; 
    String input = "Employee Checking"; 
    int min = Integer.MAX_VALUE; 
    String maxMatch = null; 
    for(String name : names) 
    { 
     int i = input.indexOf(name); 
     if(i > -1 && i < min) 
     { 
     min = i; 
     maxMatch = name; 
     } 
    } 
    if(null != maxMatch) 
    { 
     System.out.println("Maximum match for " + input + " found at " + maxMatch); 
    } 
} 

上面的代码片段试图执行输入的最大匹配。因此,如果我有“员工利益检查”作为输入,我会在“利息检查”中获得匹配,而不仅仅是“检查”。

我想知道的是,是否有任何方法可以进一步优化此代码段,或者是否存在代码失败的情况?

+0

如果在名称中可能的匹配,[]是由长度排序,例如“兴趣检查”在“检查”之前出现,您不必与分钟进行比较。较长的比赛将首先自动发生。 – user949300

回答

3

如果你保持有序阵列由字符串的长度,你可以肯定的是第一场比赛将给予最大匹配

import java.util.Arrays; 
import java.util.Comparator; 

public class MaxIndex { 

private static String[] names = { "Checking", "Savings", "DEMAT", "DEMAT Savings", 
     "Interest Checking","Savings Interest Checking","My Employee Savings Interest Checking" }; 

public static void main(String[] args) { 

    Arrays.sort(names, new Comparator<String>() { 

     @Override 
     public int compare(String o1, String o2) { 
      Integer L1 = o1.length(); 
      return L1.compareTo(o2.length())*-1; 
     } 
    }); 

    findMaxMatch("Employee Checking"); 
    findMaxMatch("Employee Savings"); 
    findMaxMatch("Employee Interest Checking"); 
    findMaxMatch("Employee Savings Interest Checking"); 
    findMaxMatch("My Employee Savings Interest Checking"); 
    findMaxMatch("Employee Current"); 
} 

private static void findMaxMatch(String input) { 
    String maxMatch = maxMatch(input); 
    if (null != maxMatch) { 
     System.out.println("Maximum match for '" + input + "' found at '" 
       + maxMatch+"'"); 
    }else{ 
     System.out.println("No match for '"+input+"'"); 
    } 
} 

private static String maxMatch(String input) { 
    for (String name : names) { 
     int i = input.indexOf(name); 
     if (i > -1) { 
      return name; 
     } 
    } 
    return null; 
} 

}

输出

Maximum match for 'Employee Checking' found at 'Checking' 
Maximum match for 'Employee Savings' found at 'Savings' 
Maximum match for 'Employee Interest Checking' found at 'Interest Checking' 
Maximum match for 'Employee Savings Interest Checking' found at 'Savings Interest Checking' 
Maximum match for 'My Employee Savings Interest Checking' found at 'My Employee Savings Interest Checking' 
No match for 'Employee Current' 
+0

我确实想过对数组进行排序,但不会自行排序是一个开销? – Vrushank

+0

如果每次找到匹配时对它进行排序,则可能会产生开销,但是如果对它排序一次并引用已排序的数组,则它不是。 –

0

如果最大匹配不在字符串的第一部分,则会失败。例如,如果您的输入是Interest Checking For Employees,它将匹配Checking而不是Interest Checking。最大匹配是否应该找到匹配最多的顺序字符的帐户?或者只是最接近输入结尾的比赛?

-2

使用这种寻找最后的位置

names.lastIndexOf(input) 

基于阵列的位置,获得的价值

2

如果我理解你的问题正确,你想找到的情况下有多个匹配的最长匹配。一种方法是按照降序排列你的“名字”(根据他们的长度),并在第一场比赛中停下来。

您可以通过在你把每一个“名”的长度从你的“名称”为关键字的的SortedMap <整数,字符串>做到这一点。

例如,通过做这样的事情:

SortedMap<Integer,String> map = new TreeMap<Integer, String>(new Comparator<Integer>() { 
    public int compare(Integer o1, Integer o2) { 
     return -o1.compareTo(o2); 
    } 
}); 
for (final String name: names) { 
    map.put(name.length(),name); 
} 

然后迭代和你找到的第一个匹配就立即停止。

这有点“过度杀伤力”,但它的工作原理。

0

如果我没有理解你是否正确,找到的字符串总是应该是查询的子字符串?

使用找到一个子字符串,如果找到了,如果它是最长的还保留它。

public static void main(String[] args) 
{ 
    String[] names = {"Checking", "Savings", "DEMAT", "DEMAT Savings", "Interest Checking"}; 
    String input = "Employee Interest Checking"; 
    int min = Integer.MIN_VALUE; 
    String maxMatch = null; 
    for (String name : names) 
    { 
     boolean has = input.contains(name); 
     if (has && min < name.length()) 
     { 
      min = name.length(); 
      maxMatch = name; 
     } 
    } 
    if (null != maxMatch) 
    { 
     System.out.println("Maximum match for " + input + " found at " + maxMatch); 
    } 
} 

就像user988052说的那样;如果您以正确的方式订购阵列,您可以在第一场比赛中停止,因此您不必再搜索并可以消除min

订购阵列由长度降序:

Arrays.sort(names, new Comparator<String>() 
    { 
     public int compare(String o1, String o2) 
     { 
      int d = o2.length() - o1.length(); 
      return d != 0? d : ((Comparable<String>)o1).compareTo(o2); 
     } 
    });