更好的检查字符串的方法?

时间:2014-03-17 03:26:02

标签: java android

我有一个代码,用于检查空格,逗号等字符串 我将处理我的应用程序将要检查的场景,让我们说千字节的最大长度为15,最小长度为14.我担心它会影响性能,因为它在android中。检查我使用的代码..

private final static char[] undefinedChars = {' ','/','.','<','>','*','!'};

    public static boolean checkMessage(String message){

    if (message == null)
        return false;

    char[] _message = message.toCharArray();

    for (char c : _message) {
         for (int i = 0;i > undefinedChars.length;i++)
                if (c == undefinedChars[i])
                    return true;
    }

    return false;
}

这是对的吗?或者有办法改善它?

6 个答案:

答案 0 :(得分:2)

您可以进行一项更改可能会产生一些变化:

更改

    char[] _message = message.toCharArray();
    for (char c : _message) {

    for (int i = 0; i < message.length(); i++) {
        char c = message.charAt(i);

但是,我怀疑它会很重要。

switch替换内部循环更有可能是富有成效的,尽管它取决于JIT编译器对代码的作用。 (只有当一组未定义的字符可以作为编译时常量硬连接到switch语句中时,开关才会起作用。)


  

我担心它会影响性能,因为它在android中。

不要“担心”。科学地解决问题。

  1. 实施代码然后对其进行基准测试。
  2. 如果测量性能是一个问题,那么:
    1. 配置代码
    2. 查看热点,并确定可能的改进
    3. 实施并测试可能的改进
    4. 重新运行基准测试以确定改进是否实际上有所不同
    5. 重复...直到表现足够好或者你的选项用完了。

  3. 另一件需要注意的是,相同的代码在不同的Android平台上的表现可能会有所不同。在最近的版本中,JIT编译器的质量(显然)显着提高。

    我认为,为了让它在旧手机上运行良好而“弯曲”你的代码是一个坏主意。很可能用户很快就会升级他们的硬件......并且可以想象你对旧平台的优化实际上会使你的代码在新平台上变得更慢...'因为你的手优化让代码变得太棘手了为JIT编译器的优化器来处理。

    这也是不试图让你的代码“尽可能快”的论据......

答案 1 :(得分:2)

首先,我看到了一个错误。

for (int i = 0;i > undefinedChars.length;i++)

我认为你的意思是

for (int i = 0;i < undefinedChars.length;i++)

代替?

无论如何,你的算法似乎在O(m * n)中运行,其中m是消息的长度,n是未定义字符的长度(在这种情况下是固定大小,15)。因此,它应该在运行时分析方面有效。

我会首先分析场景,然后决定如何改进它,你可以在某处预先对消息进行排序,然后你只能检查第一个字符串或字符串的最后一个字符,但正如我所说,只有在其他地方进行了分类。

或者可能想到并行化例行程序。它应该是直截了当的。

答案 2 :(得分:1)

在不使用记忆的情况下,您可以尽可能快地获得记忆。您可以交换内存以获得性能。例如,您可以将要检查的字符放入HashMap中。然后,您可以遍历要检查的字符串,并检查每个索引是否在该映射中。如果要检查的字符数很少,则效率会降低。如果数字很大,它将更有效(从技术上讲,这个算法是O(n)而不是O(n * m),但如果m很小,那么你经常被教导忽略的常数就很重要)。

另一种方法是使用布尔数组,字符串中的每个可能字符映射到该数组中的索引。仅将您关注的字符设置为true(并保存该数组)。然后你可以避免上面的哈希计算,但代价是大量内存。

真的,你原来的算法很可能已经足够了。但是这些(特别是哈希映射)是您可以根据需要考虑的事情。

答案 3 :(得分:0)

尝试使用正则表达式。我发现它很干净,不应该损害你的表现。

public static boolean checkMessage(String message)
{
    if (message == null)
        return false;

    String regex = " |\\.|/|<|>|\\*|!";
    Matcher matcher = Pattern.compile(regex).matcher(message);
    if (matcher.find())
        return true;
    else
        return false;
}

答案 4 :(得分:0)

对于对称性和可能的​​编译器优化,为什么不为两个循环使用for-each样式循环。作为额外的好处,你不会冒像釉料指出的错字。您的代码将变为:

private final static char[] undefinedChars = {' ','/','.','<','>','*','!'};

public static boolean checkMessage(String message){

if (message == null)
    return false;

char[] _message = message.toCharArray();

for (char c : _message) {
     for (for u : undefinedChars)
            if (c == u)
                return true;
}

return false;

}

另一个优化是按最有可能发生的顺序对undefinedChars中的字符进行排序。这样你就可以尽快纾困。

答案 5 :(得分:0)

使用Set按住undefinedChars

Set<Character> undefinedChars = new HashSet<Character>(Arrays.asList(new Character(' ') ,new Character('/'),new Character('.')));

public boolean hasUndefinedChar(String str) {
  for (int i = 0; i < str.length(); i++) {
    char iChar = str.charAt(i);
    Character charWrapper = new Character(iChar);
    if (undefinedChars.contains(charWrapper)) {
      return true;
    }
  }
  return false;
}

此方法O(n)时间效率高,并且不足以影响空间复杂性。包含对Set的调用是O(1)次操作,并且在最坏的情况下,您将n包含这些调用。