5

我想确定一个字符串是否是一个月的名称,并且我想相对快速地完成它。目前卡在我大脑中的功能是这样的:

boolean isaMonth( String str ) {
    String[] months = DateFormatSymbols.getInstance().getMonths();
    String[] shortMonths = DateFormatSymbols.getInstance().getShortMonths();
    int i;

    for( i = 0; i<months.length(); ++i;) {
        if( months[i].equals(str) ) return true;
        if( shortMonths[i].equals(str ) return true;
    }
    return false;
}

但是,我将处理大量文本,一次将一个字符串传递给这个函数,而且大多数时候我会遇到最坏的情况,即遍历整个循环并返回 false。

我看到另一个问题,它谈到了一个正则表达式来匹配一个月份名称和一个可以适应这种情况的年份。正则表达式会更快吗?有没有其他可能更快的解决方案?

4

3 回答 3

3

为什么不将月份名称存储在 a 中HashSet?这将为您提供恒定时间查找,而不是您从循环中获得的线性时间查找。

import java.util.HashSet;
import java.util.Collections;
import java.text.DateFormatSymbols;

class Test {
  public static void main(String[] args) {

    HashSet<String> months = new HashSet<String>(24);  

    Collections.addAll(months, DateFormatSymbols.getInstance().getMonths());
    Collections.addAll(months, DateFormatSymbols.getInstance().getShortMonths());

    System.out.println(months.contains(args[0]));

  }
}
于 2010-05-21T03:52:11.483 回答
1

将months 和shortMonths 合并到一个排序数组中,并对数组进行二分搜索。或者将它们合并成一个集合(HashSet)并使用包含。如果您希望不区分大小写,请将所有月份名称更改为小写并对搜索值执行相同操作。

如果您希望能够检索月份的编号,请将它们全部合并到一个 Map (HashMap) 中,其值为月份编号。

于 2010-05-21T04:02:49.347 回答
1

HashSet 是一个很好的通用解决方案——但我认为你可以做得更好。看一下月份的第一个字母 - jfmasond - 如果您对它们进行预过滤,并且只检查 HashSet 是否通过,它将处理大量的“返回错误”场景。

您可以通过多种方式进行设置 - 一种超级简单的方法是使用 switch 语句,尽管查找表会更快。另请注意,您只需要检查第一个字符是否介于 a 和 s 之间,因此查找表不必具有完整的 unicode(或 UTF-8,具体取决于要求)代码空间。

为了使这更加有效,您可以构建查找表,使其包含每个月的前 2 个字符 - 生成的查找表不会太大,这将大大减少需要检查的单词数量哈希集。

PS - 在你做任何这些之前,你应该做一些分析并确保这是你的代码区域实际上是瓶颈。

于 2010-05-21T04:21:18.153 回答