Java 确定字符串是否为回文的最快方法

Java 确定字符串是否为回文的最快方法,java,performance,palindrome,Java,Performance,Palindrome,如果字符串是回文(字符串可以是带有大写或小写字母、空格等的命题),我需要一个算法,以尽可能快的执行时间进行验证。所有这些都是用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 -

如果字符串是回文(字符串可以是带有大写或小写字母、空格等的命题),我需要一个算法,以尽可能快的执行时间进行验证。所有这些都是用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;
}
bool isPalindrome(字符串s){
int n=s.长度();
s=s.toLowerCase();
对于(int i=0;i<(n/2)+1;++i){
如果(s.charAt(i)!=s.charAt(n-i-1)){
返回false;
}
}
返回true;
}
我使用
.toLowerCase()
函数将字符串转换为小写字母,但我不知道它对执行时间的影响有多大


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

我想你可以只检查字符串的倒数,不是吗

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

在有效性方面,您的解决方案似乎还不错

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

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)) {
...
String stripped=s.toLowerCase().replaceAll(“[\\s,]”,“”);
int n=stripped.length();
对于(int i=0;i<(n/2)+1;++i){
if(stripped.charAt(i)!=stripped.charAt(n-i-1)){
...

有效与高效不同

如果你考虑空格、特殊字符等等,你的答案是有效的。甚至口音也会有问题。

关于效率,toLowerCase是O(n),任何regexp解析也将是O(n)。如果您担心这一点,那么逐字符转换和比较应该是最好的选择。

在正常情况下:

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

这避免了任何复制。函数
是空白的
toLowerCase
在您的问题中是未指定的,因此请按您想要的方式定义它们。举个例子:

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;
for(int i=0,j=s.length()-1;i=j)返回true;
}
while(isBlank(s.charAt(j))){
j--;
如果(i>=j)返回true;
}
if(toLowerCase(s.charAt(i))!=toLowerCase(s.charAt(j)))返回false;
}
返回true;

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

以下是我使用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()));
   }
}
以下是我的尝试:

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;
 }
public静态布尔值isAlindrome(字符串s)
{
int index1=0;
int index2=s.长度()-1;
而(index1
你的方法和所有其他有效的方法一样有效。不过,你可以试着找到一种更有效的方法……这不是一个家庭作业问题吗?@RolandTepp为什么这很重要?是的,我想这实际上是我的问题……用“有效”而不是“有效”。StringBuilder的可能副本有一个,仍然与答案不一样。@Andreyknuppital哈哈同意,你至少快了0.1秒!@Andreyknuppital::D:D:D好的,我可以看到我的阅读技能需要一些升级。@Maartinus关于主题:问题是
String
没有
reverse()
方法。如果尝试
str.equals(str.reverse())
,您将得到一个编译错误。此外,在StringBuilder对象上尝试
.equals()
将检查它们是否是相同的引用,而不是它们是否包含相同的字符串值。因此,我使用了
.toString()
@Joetjah:我的阅读能力可能比我想象的还要差,但是没有。有两次使用了
toString
。你说的是关于第二次使用。第一次使用只返回原始的
str
。replaceAll([\\s,]>,“”)“\\s”是空格字符?
\\s
是空格字符的缩写:
[\t\n\x0B\f\r]
。好的,伙计,谢谢。我想这是我需要的一个解决方案。你知道它对时间和空间效率的影响有多大吗?@BogdanMursa:使用
toLowerCase()
和正则表达式很可能比在运行中慢,但这又有什么关系呢?@Maartinus你说的“运行中”是什么意思所以像@Keppil这样的解决方案是最好的选择吗?那就是s.toLowerCase().replaceAll(“[\\s,]”,“”);正是我所说的问题。@maaartinus是迄今为止最快的解决方案。我认为OP正在寻找区分大小写的解决方案。我认为@Kennil Response是一个很好的解决方案,它似乎具有最佳的时间效率。这看起来是一个很好的解决方案。+1