在Java中反转字符串的最有效方法是什么?我应该使用某种xor运算符吗?简单的方法是将所有字符放在堆栈中并将它们重新放回字符串中,但我怀疑这是一种非常有效的方法。
请不要告诉我在Java中使用一些内置函数。我有兴趣学习如何不使用有效的功能,但不知道为什么它有效或如何建立。
你说你想知道最有效的方式,你不想知道一些标准的内置方式。然后我告诉你:RTSL(读源,luke):
查看AbstractStringBuilder#reverse的源代码,它由StringBuilder#reverse调用。我打赌它会做一些你不会考虑进行强大的反向操作的东西。
如果您不想使用任何内置函数,则需要将字符串返回到其组件部分:字符数组。
现在的问题是什么是反转数组最有效的方法?在实践中这个问题的答案也取决于内存使用(对于非常大的字符串),但理论上在这些情况下的效率是在数组访问中测量的。
最简单的方法是创建一个新数组,并在反向迭代原始数组并返回新数组时使用您遇到的值填充它。 (虽然使用临时变量,你也可以在没有额外数组的情况下执行此操作,如Simon Nickersons的回答)。
这样,对于具有n个元素的数组,您只能访问每个元素一次。从而给出O(n)的效率。
我只是这样做而不使用任何单个util函数。只有String类就足够了。
public class MyStringUtil {
public static void main(String[] args) {
String reversedString = reverse("StringToReverse");
System.out.println("Reversed String : " + reversedString);
}
/**
* Reverses the given string and returns reversed string
*
* @param s Input String
* @returns reversed string
*/
private static String reverse(String s) {
char[] charArray = s.toCharArray(); // Returns the String's internal character array copy
int j = charArray.length - 1;
for (int i = 0; charArray.length > 0 && i < j; i++, j--) {
char ch = charArray[i];
charArray[i] = charArray[j];
charArray[j] = ch;
}
return charArray.toString();
}
}
核实。干杯!!
使用字符串:
String abc = "abcd";
int a= abc.length();
String reverse="";
for (int i=a-1;i>=0 ;i--)
{
reverse= reverse + abc.charAt(i);
}
System.out.println("Reverse of String abcd using invert array is :"+reverse);
使用StringBuilder:
String abc = "abcd";
int a= abc.length();
StringBuilder sb1 = new StringBuilder();
for (int i=a-1;i>=0 ;i--)
{
sb1= sb1.append(abc.charAt(i));
}
System.out.println("Reverse of String abcd using StringBuilder is :"+sb1);
一种变体可以是交换元素。
int n = length - 1;
char []strArray = str.toCharArray();
for (int j = 0; j < n; j++) {
char temp = strArray[j];
char temp2 = strArray[n];
strArray[j] = temp2;
strArray[n] = temp;
n--;
}
public static void main(String[] args){
String string ="abcdefghijklmnopqrstuvwxyz";
StringBuilder sb = new StringBuilder(string);
sb.reverse();
System.out.println(sb);
}
public static String Reverse(String word){
String temp = "";
char[] arr = word.toCharArray();
for(int i = arr.length-1;i>=0;i--){
temp = temp+arr[i];
}
return temp;
}
char* rev(char* str)
{
int end= strlen(str)-1;
int start = 0;
while( start<end )
{
str[start] ^= str[end];
str[end] ^= str[start];
str[start]^= str[end];
++start;
--end;
}
return str;
}
=========================
第一次操作:
x1 = x1 XOR x2
x1: 1 0 0
x2: 1 1 1
New x1: 0 1 1
第二次操作
x2 = x2 XOR x1
x1: 0 1 1
x2: 1 1 1
New x2: 1 0 0
//Notice that X2 has become X1 now
第三次操作:
x1 = x1 XOR x2
x1: 0 1 1
x2: 1 0 0
New x1: 1 1 1
//Notice that X1 became X2
public static string getReverse(string str)
{
char[] ch = str.ToCharArray();
string reverse = "";
for (int i = str.Length - 1; i > -1; i--)
{
reverse += ch[i];
}
return reverse;
}
//using in-built method reverse of Array
public static string getReverseUsingBulidingFunction(string str)
{
char[] s = str.ToCharArray();
Array.Reverse(s);
return new string(s);
}
public static void Main(string[] args)
{
string str = "123";
Console.WriteLine("The reverse string of '{0}' is: {1}",str,getReverse(str));
Console.WriteLine("The reverse string of '{0}' is: {1}", str, getReverseUsingBulidingFunction(str));
Console.ReadLine();
}
使用多个线程交换元素:
final char[] strArray = str.toCharArray();
IntStream.range(0, str.length() / 2).parallel().forEach(e -> {
final char tmp = strArray[e];
strArray[e] = strArray[str.length() - e - 1];
strArray[str.length() - e - 1] = tmp;
});
return new String(strArray);
当然这是最有效的方式:
String reversed = new StringBuilder(str).reverse().toString();
但如果您不喜欢使用它,那么我推荐这样做:
public String reverseString(String str)
{
String output = "";
int len = str.length();
for(int k = 1; k <= str.length(); k++, len--)
{
output += str.substring(len-1,len);
}
return output;
}
以下不涉及UTF-16代理对。
public static String reverse(String orig)
{
char[] s = orig.toCharArray();
int n = s.length;
int halfLength = n / 2;
for (int i=0; i<halfLength; i++)
{
char temp = s[i];
s[i] = s[n-1-i];
s[n-1-i] = temp;
}
return new String(s);
}
static String ReverseString(String input) {
var len = input.Length - 1;
int i = 0;
char[] revString = new char[len+1];
while (len >= 0) {
revString[i] = input[len];
len--;
i++;
}
return new string(revString);
}
为什么我们不能坚持最简单的循环和崇拜与字符读取并继续添加到char数组,我遇到了一个白板采访,面试官设置限制不使用StringBuilder
和内置功能。
public static String reverseString(String str)
{
StringBuilder sb = new StringBuilder();
for (int i = str.length() - 1; i >= 0; i--)
{
sb.append(str[i]);
}
return sb.toString();
}
你说你不想这么简单,但谷歌搜索你应该使用StringBuilder.reverse:
String reversed = new StringBuilder(s).reverse().toString();
如果您需要自己实现它,那么以相反的顺序迭代字符并将它们附加到StringBuilder。如果有(或可以)代理对,你必须要小心,因为这些不应该被颠倒。上面显示的方法会自动为您执行此操作,这就是您应该尽可能使用它的原因。
然而,旧的帖子和问题仍然没有看到与递归有关的答案。递归方法反转给定的字符串s,而不中继内置的jdk函数
public static String reverse(String s) {
if (s.length() <= 1) {
return s;
}
return reverse(s.substring(1)) + s.charAt(0);
}
`
最快的方法是在reverse()
或StringBuilder
类上使用StringBuffer
方法:)
如果你想自己实现它,你可以得到字符数组,分配第二个字符数组并移动字符,在伪代码中这将是:
String reverse(String str) {
char[] c = str.getCharArray
char[] r = new char[c.length];
int end = c.length - 1
for (int n = 0; n <= end; n++) {
r[n] = c[end - n];
}
return new String(r);
}
你也可以运行一半的数组长度并交换字符,检查可能会减慢速度。
当你说你需要一个有效的算法时,我不确定你的意思。
我能想到的扭转字符串的方法是(在其他答案中已经提到过):
问题是所有这些都具有相同的运行时复杂性:O(N)。因此,对于非常大的N值(即非常大的弦),任何一个都不能明显优于其他任何一个。
第三种方法确实有一件事要做,另外两种方法需要额外的O(N)空间(对于堆栈或新的String),而它可以在适当的位置执行交换。但是字符串在Java中是不可变的,所以你需要在新创建的StringBuilder / char []上执行交换,因此最终需要额外的O(N)空间。
public class ReverseInPlace {
static char[] str=null;
public static void main(String s[]) {
if(s.length==0)
System.exit(-1);
str=s[0].toCharArray();
int begin=0;
int end=str.length-1;
System.out.print("Original string=");
for(int i=0; i<str.length; i++){
System.out.print(str[i]);
}
while(begin<end){
str[begin]= (char) (str[begin]^str[end]);
str[end]= (char) (str[begin]^str[end]);
str[begin]= (char) (str[end]^str[begin]);
begin++;
end--;
}
System.out.print("\n" + "Reversed string=");
for(int i=0; i<str.length; i++){
System.out.print(str[i]);
}
}
}
我认为如果你真的没有性能问题,你应该选择最易读的解决方案:
StringUtils.reverse("Hello World");
private static String reverse(String str) {
int i = 0;
int j = str.length()-1;
char []c = str.toCharArray();
while(i <= j){
char t = str.charAt(i);
c[i] = str.charAt(j);
c[j]=t;
i++;
j--;
}
return new String(c);
}