题目:
将一个字符串进行反转。
- 将字符串中指定部分进行反转。
- 例如,将abcdefg
- 反转为:
- abfedcg
题解:
题目不算难,只是对于String的一个简单应用,但是对于该题目,可以实现一题多解:
将主要的功能模块抽离出来,main()只实现对于功能方法的调用即可:
public static void main(String[] args) {
String str = "abcdefg";
StringDemo stringDemo = new StringDemo();
String reverse = stringDemo.reverse3(str, 2, 5);
System.out.println(reverse);
}
下面是具体的几种解法:
(1)最基本的思路,定义一个char[],先将字符串转换为char[],然后对char[]中需要反转的片段进行遍历,互换相应位置上的元素:
// 方法一:
public String reverse1(String str, int startIndex, int endIndex) {
// 只有字符串str 是实例化过之后的,才有反转的必要
if (str != null) {
// 先将字符串转化为字符数组,进行相应操作
char[] charArray = str.toCharArray();
char temp;
// 进行反转的具体操作
for (int i = startIndex, j = endIndex; i < j; i++, j--) {
// System.out.println("first:" + charArray[i] + "," + "second:" + charArray[j]);
// 开辟了空间
temp = charArray[i];
charArray[i] = charArray[j];
charArray[j] = temp;
// System.out.println("first:" + charArray[i] + "," + "second:" + charArray[j]);
// System.out.println("startIndex = " + i + ",endIndex = " + j);
}
// 将字符数组转化回字符串,进行返回
// System.out.println(str1);
return new String(charArray);
} else {
return null;
}
}
(2)思路为: 将字符串分为三部分:需要反转的部分、需反转部分前面的部分、需反转的部分后面的部分。 通过字符串的拼接 + 自己实现的字符串反转(+拼接)----来实现:
public String reverse2(String str, int startIndex, int endIndex) {
// 出于 健壮性 的考虑
if (str != null) {
// 第一部分
String str1 = str.substring(0, startIndex);// 是 左闭右开区间
// 第二部分:实现中间的反转的部分
/*
* 在实现反转的这一块,表面上没有多开辟空间, 实际上并不是: 因为进行 在现有变量的基础上进行拼接,每一次实际上都会造一个对象 所以,实际上的效率也并不高
*/
for (int i = endIndex; i >= startIndex; i--) {
str1 += str.charAt(i);
}
// 第三部分:
str1 += str.substring(endIndex + 1);
return str1;
} else {
return null;
}
}
(3)实际上,是方法二的迭代(优化): 因为string的不可变性,所以才导致方法二中的反转模块,每拼接一个字符,就要再造一个对象
* 在这里进行改进,运用stringbuilder的可扩容的特点,将方法二中的string修改为stringbuilder
* 并且在最初实例化stringbuilder对象的时候,就将 对应的数组长度设定为后面不需要进行 扩容操作的大小
* 在最后,返回时,将stringbuilder的对象转化为string类型的对象就可以
public String reverse3(String str, int startIndex, int endIndex) {
if(str != null) {
StringBuilder strb = new StringBuilder(str.length());
//第一部分
strb.append(str.substring(0, startIndex));
//第二部分
for(int i=endIndex;i>=startIndex;i--) {
strb.append(str.charAt(i));
}
//第三部分
strb.append(str.substring(endIndex+1));
return strb.toString();
}else {
return null;
}
/*
* 在这里,由于stringbuilder的可变性,
* 每次拼接的过程中,并没有不断地造新的字符串,
* 并且,由于定义的stringbuilder类的对象的初始长度为str.length()+16
* 在整个拼接的过程中,strb也没有扩容,
*/
}
注意:
因为string类是不可变的 所以在这里,采用reverse()实现对于部分元素的反转的话, reverse() 的返回值类型不能为void,而应该是通过方法的返回值将反转后的结果带回:
* 因为反转后的string还需要 该函数的return 带回 不然的话,由于方法的值传递机制,引用数据类型传递的是地址----所以调用reverse()的时候,只是简单地将main()中的str的地址传递过来了。
* 而在reverse()中,对于string中指定元素进行反转的结果,不能传回main()中 这是因为,由于string 的 不可变性,导致:在reverse()中进行相应操作后,实际上是在 字符串常量池中,又造了一个 字符串 abfedcg,----改变了reverse()中,局部变量str所指向的地址 但是 main()中,局部变量str所指向的地址仍旧没有改变。
当你真正努力的时候,全世界都会为你让路。
坚持!