字符串的最大匹配

时间:2011-11-19 17:00:53

标签: java string optimization

我正在尝试编写一个方法,该方法将返回与我需要传递给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);
   }
}

以上代码段尝试为输入执行最大匹配。因此,如果我将“员工兴趣检查”作为输入,我会在“兴趣检查”中获得匹配,而不仅仅是“检查”。

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

5 个答案:

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

答案 1 :(得分:2)

如果我理解你的问题,你想找到最长的匹配,以防有多个匹配。一种方法是按降序(根据长度)对“名称”进行排序,并在第一场比赛时停止。

您可以使用 SortedMap&lt; Integer,String&gt; 来执行此操作,其中您将“名称”中每个“名称”的长度作为其键。

例如通过这样做:

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

然后,一旦找到第一场比赛,就会迭代并停止。

它有点“矫枉过正”,但它确实有效。

答案 2 :(得分:0)

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

答案 3 :(得分:0)

如果我理解正确,找到的字符串应始终是查询的子字符串吗?

使用contains()查找子字符串,如果找到,则保留它,如果它是最长的。

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

答案 4 :(得分:-2)

用它来寻找最后的位置

names.lastIndexOf(input)

基于数组位置,得到值