翻转单词顺序列
每天一道算法题
问题:例如
Input: “I am a student.”
Output: “student. a am I”
各个单词里的字母并没有翻转,是整个句子的单词翻转。
学习遗漏点:
1、String的split方法可以把字符串分割为字符数组
2、&&和&的区别,||和|的区别同理
&&当前面的条件不成立时,直接返回false
&会从前往后都算一遍,最后再判断。这样后面可能就会出现数组溢出的异常
3、字符串的初始化方式,可以直接传入字符数组初始化字符串,如new String(charArr)
下面代码
/*
* 题目:
* 翻转单词顺序列。注意--每个单词的顺序是没有改变的!
* 例 Input:"I am a student."
* Output:"student. a am I"
*/
public class Exer3 {
public static void main(String[] args) {
String str = "this am a good student.";
Solution3 solution3 = new Solution3();
System.out.println(solution3.ReverseSentence(str));
System.out.println(solution3.ReverseSentence_2(str));
}
}
class Solution3{
/*
* 方法一:用String的split方法按照空格' '把句子分成一个个单词,然后反着组成一个新的句子就可以了
*/
public String ReverseSentence(String str) {
StringBuilder sb = new StringBuilder();
String[] arr = str.split(" ");//一个String型的数组存储分割后的每个单词
for(int i = arr.length - 1; i >= 0; i--) {//将数组中的单词反向存储到新的字符串中
sb.append(arr[i]);
if(i != 0) {
sb.append(' ');
}
}
String s = sb.toString();
return s;
}
/*
* 方法二:两次反转(推荐使用)
*思路:
我们需要的是将单词位置反转,也即是单词内部不变,属于字符串部分反转问题。
如果将整个字符串反转,单词位置倒是反转了,但是内部次序也改变了,此时就需要将内部再反转回去,
因此两次反转可以解决。
*具体做法:
step 1:将字符串整体反转。
step 2:遍历反转后的字符串,以空格为界限找到一个单词。
step 3:将每个单词部分反转。
*
*/
public String ReverseSentence_2(String str) {
int n = str.length();
char[] c = str.toCharArray();//将字符串转化为字符数组
ReverseString(c, 0, n - 1);//翻转整个字符串
for(int i = 0; i < n; i++) {//遍历字符串,用i做第一个索引
int j = i;
// while(c[j] != ' ' && j < n) {//一开始是这样写,会报错,没有考虑到&&的特性
// 其中就涉及到&&和&的区别:
// &&当前面的条件不成立时,直接返回false
// &会从前往后都算一遍,最后再判断。这样后面可能就会出现数组溢出的异常
while(j < n && c[j] != ' ') {//用j做第二个索引
j++;
}
ReverseString(c, i, j - 1);
i = j;
}
return new String(c);
}
//工具方法翻转两个字符
public void Reverse(char[] c, int p1, int p2) {
char temp;
temp = c[p1];
c[p1] = c[p2];
c[p2] = temp;
}
//工具方法翻转一个字符串
public void ReverseString(char[] c, int p1, int p2) {
while(p1 < p2) {
Reverse(c, p1++, p2--);
}
}
}