在O(1)中用Java反转一个字符串?

在给定CharSequence的情况下,标准Java库中是否有任何工具在O(1)时间内产生反转?

我想这很容易实现,只是想知道它是否已经存在。 (我怀疑这不是提供的原因是因为“简单”的方式实际上会破坏多字符代码点 – 但在许多情况下我们知道我们没有处理那些)。

谢谢

更新嘿,大多数人认为这个“不可能”,好工作的家伙有点有趣! 嗯,实际上它(概念上)是微不足道的 – 伪随之而来是为了清楚:

class MyReverseString extends String { //of course I can't extend String! final String delegate; MyReverseString(String delegate) { this.delegate = delegate; } int length() { return delegate.length(); } int charAt(int i) { return delegate.charAt(delegate.length() - 1 - i); } } 

我正在将这个问题留待更多,只是在极少数事件中,明显的解决方案(例如,见Jon Skeet的那个)已经存在于JDK中并且有人知道它。 (再次,由于那些讨厌的代码点,极不可能)。

编辑可能混淆来自我在标题中有“字符串”(但不是字符串!),而我只要求“CharSequence的反向”。 如果你感到困惑,抱歉。 我希望O(1)部分能够清楚地说明要求的内容。

顺便说一句,这是让我问这个的问题 。 (这是一种从右到左,而不是从左到右运行正则表达式更容易的情况,因此即使对于简单/破坏的代码点实现也可能有一些实用价值)

好吧,您可以轻松生成CharSequence的实现,它返回相同的长度,当被要求输入特定字符时,返回length-index-1那个。 toString()当然变成O(n)……

创建反向的CharSequence将是O(1) – 它所要做的就是存储对原始CharSequence的引用,毕竟。 然而,显然,迭代序列中的所有字符将是O(n)。

请注意,创建反向CharSequence (根据您的问题正文)与创建反向String (根据您的问题标题 )不同。 实际上生成字符串是O(n),必须是。

示例代码,大部分未经测试:

 public final class ReverseCharSequence implements CharSequence { private final CharSequence original; public ReverseCharSequence(CharSequence original) { this.original = original; } public int length() { return original.length(); } public char charAt(int index) { return original.charAt(original.length() - index - 1); } public CharSequence subSequence(int start, int end) { int originalEnd = original.length() - start; int originalStart = original.length() - end; return new ReverseCharSequence( original.subSequence(originalStart, originalEnd)); } public String toString() { return new StringBuilder(this).toString(); } } 

这是不可能的。 为了反转字符串,您必须至少处理一次每个字符,因此,它必须至少为O(n)

 string result = new StringBuffer(yourString).reverse().toString(); 

根据您在O(1)下的理解,似乎不可能,因为即使读取字符串也需要O(n),其中n是字符串中的字符数。

StringBuffer有一个反向: http : //java.sun.com/j2se/1.4.2/docs/api/java/lang/StringBuffer.html#reverse()

顺便说一下,我认为你的意思是O(n),因为O(1)(正如其他人所提到的)显然是不可能的。

所有其他人已经写过了,在O(1)时间内是不可能的,因为你必须至少看一次每个角色。

但是如果你的意思是如何在O(1)空间中进行,那就是它:如果你想在O(1)空间中进行,你显然不能分配一个相同长度的新字符串,但你必须交换人物就地。

因此,您所要做的就是从字符串的左侧到中间迭代,同时从右侧到中间迭代并交换元素。 伪代码(约定:让字符串s可以通过s[n]在第n个字符处访问。如果s长度为k ,我们说它有元素0k-1 ):

 for i=0; i 

所以你看,你需要的只是一个辅助变量tmp包含你当前用于交换它的字符,所以你可以在O(1)空间中完成它。

Jon Skeet的解决方案可能效率最高。 但是如果你只是想快速而又肮脏,那么应该这样做,我不认为它会在性能方面落后。

 StringBuffer reverse=new StringBuffer(original.toString()).reverse(); 

StringBuffer是一个CharSequence,所以如果你暗示结果必须是CharSequence,那就是。

好吧,如果您多次检查序列,这可能比Skeet先生的解决方案更快,因为它消除了计算的开销,以便在每次读取字符时找到正确的char位置。 它每个角色只会做一次。

如果我打算做十亿这些,也许我会做一个基准。

更好的是使用StringBuilder进行反转,这是StringBuffer的非同步版本。

 for (count = str.length()-1; count >= 0; count--) { tempStr = tempStr.concat(Character.toString(origStr.charAt(count))); } 

这里我有一个使用substring方法和o(n)的样本。 我知道使用子字符串将保存完整的字符串内存。

 for(int i = 0; i < s.length(); i++) { s = s.substring(1, s.length() - i) + s.charAt(0) + s.substring(s.length() - i); System.out.println(s); } 

这可能对你有帮助。 告诉我,如果我错了!!

//努力想出这个

 public static String ReverseString(String s){ if (s.length()>0){ s=s.charAt(s.length()-1)+printString(s.substring(0,s.length()-1)); } return s; }