【问题标题】:The fastest method of determining if a string is a palindrome确定字符串是否为回文的最快方法
【发布时间】:2014-01-28 11:01:13
【问题描述】:

如果字符串是回文(字符串可以是带有大写或小写字母、空格等的命题),我需要一种算法以尽可能快的执行时间进行验证。所有这些都在 Java 中。我有一个样品:

bool isPalindrome(string s) {
    int n = s.length();
    s = s.toLowerCase();
    for (int i = 0; i < (n / 2) + 1; ++i) {
        if (s.charAt(i) != s.charAt(n - i - 1)) {
            return false;
        }
    }
    return true;
}

我使用.toLowerCase()函数将字符串转换为小写字母,但我不知道它对执行时间的影响有多大。

我也不知道如何有效地解决单词之间的标点和空格问题。

【问题讨论】:

  • 您的方法与所有其他有效的方法一样有效。不过,可以尝试找到一种更有效的方法....
  • 这不是作业题吗?
  • @RolandTepp 为什么这很重要?
  • 是的,我想这实际上是我的问题..用“有效”而不是“有效”。
  • Reverse a string in Java的可能重复

标签: java performance palindrome


【解决方案1】:

我想你可以只检查字符串 reverse,不是吗?

StringBuilder sb = new StringBuilder(str);
return str.equals(sb.reverse().toString());

或者,对于 JDK 1.5 之前的版本:

StringBuffer sb = new StringBuffer(str);
return str.equals(sb.reverse().toString());

【讨论】:

  • StringBuilder 有一个,还是和答案不一样。
  • @AndreyKnuppVital 哈哈同意,你至少快了 0.1 秒!
  • @AndreyKnuppVital: :D:D:D 好的,我可以看到我的阅读能力需要一些提升。
  • @maaartinus 主题:问题是String 没有reverse() 方法。如果你尝试str.equals(str.reverse()),你会得到一个编译错误。除此之外,在 StringBuilder-objects 上尝试 .equals() 将检查它们是否是相同的引用,而不是它们是否包含相同的 String 值。因此,我使用了.toString()
  • @Joetjah:我的阅读能力可能比我想象的还要差,但不是。 toString 使用了两次。您所说的涉及第二种用途。第一个只是返回原来的str
【解决方案2】:

这样可以避免任何复制。 isBlanktoLowerCase 函数在您的问题中未指定,因此请按照您想要的方式定义它们。只是一个例子:

boolean isBlank(char c) {
    return c == ' ' || c == ',';
}

char toLowerCase(char c) {
    return Character.toLowerCase(c);
}

不用担心方法调用的成本,这是 JVM 擅长的。

for (int i = 0, j = s.length() - 1; i < j; ++i, --j) {
    while (isBlank(s.charAt(i))) {
        i++;
        if (i >= j) return true;
    }
    while (isBlank(s.charAt(j))) {
        j--;
        if (i >= j) return true;
    }
    if (toLowerCase(s.charAt(i)) != toLowerCase(s.charAt(j))) return false;
}
return true;

尝试对此进行基准测试...我希望 mu 解决方案可能是最快的,但不测量您永远不会知道。

【讨论】:

  • 这看起来是一个不错的解决方案。 +1
【解决方案3】:

就有效性而言,您的解决方案似乎还不错。

至于您的第二个问题,您可以在开始测试之前删除所有空格和点等:

String stripped = s.toLowerCase().replaceAll("[\\s.,]", "");
int n = stripped.length();
for (int i = 0; i < (n / 2) + 1; ++i) {
    if (stripped.charAt(i) != stripped.charAt(n - i - 1)) {
...

【讨论】:

  • .replaceAll("[\\s.,]", "") - "\\s" 是空格字符?
  • \\s 是空白字符的简写:[ \t\n\x0B\f\r]
  • 好的伙计,谢谢。我认为这是我需要的一种解决方案。知道它对时间和空间效率的影响有多大吗?
  • @BogdanMursa:使用toLowerCase() 和正则表达式很可能比即时执行要慢,但这有什么关系呢?
  • @maaartinus 你说的“on the fly”是什么意思
【解决方案4】:

有效不等于有效。

只要您考虑到空格、特殊字符等,您的答案就会有效。即使是口音也可能有问题。

关于效率,toLowerCase 是 O(n),任何正则表达式解析也是 O(n)。如果您对此感到担忧,那么逐个字符转换和比较应该是最好的选择。

【讨论】:

  • 所以像@Keppil 这样的解决方案发布在下面是最好的选择?
  • 即 s.toLowerCase().replaceAll("[\\s.,]", "");正是我所说的问题。 @maaartinus 是迄今为止最快的解决方案。
【解决方案5】:

这是我的尝试:

public static boolean isPalindrome(String s)
 {
    int index1 = 0;
    int index2 = s.length() -1;

    while (index1 < index2)
    {
        if(s.charAt(index1) != s.charAt(index2))
        {
            return false;
        }
        index1 ++;
        index2 --;
    }
    return true;
 }

【讨论】:

    【解决方案6】:

    以下是我使用 Java 检测回文的方法的一些见解。随时提出问题:) 希望我能以某种方式提供帮助....

    import java.util.Scanner;
    public class Palindrome  {
       public static void main(String[]args){
          if(isReverse()){System.out.println("This is a palindrome.");}
          else{System.out.print("This is not a palindrome");}
       }
       public static boolean isReverse(){
         Scanner keyboard =  new Scanner(System.in);
          System.out.print("Please type something: "); 
          String line = ((keyboard.nextLine()).toLowerCase()).replaceAll("\\W","");
          return (line.equals(new StringBuffer(line).reverse().toString()));
       }
    }
    

    【讨论】:

      【解决方案7】:

      正常情况下:

       StringBuilder sb = new StringBuilder(myString);
       String newString=sb.reverse().toString();
       return myString.equalsIgnoreCase(newString); 
      

      在区分大小写的情况下使用:

      StringBuilder sb = new StringBuilder(myString);
      String newString=sb.reverse().toString();
      return myString.equals(newString); 
      

      【讨论】:

      • 我认为 OP 正在寻找区分大小写的解决方案。
      • 我觉得@Kennil的回答不错,好像时间效率最好。
      猜你喜欢
      • 2021-10-12
      • 2016-05-02
      • 1970-01-01
      • 2010-10-19
      • 1970-01-01
      • 2011-12-06
      • 2023-03-22
      • 2012-12-27
      • 1970-01-01
      相关资源
      最近更新 更多