描述
将一句话的单词进行倒置,标点不倒置。比如 I like beijing. 经过函数后变为:beijing. like I
输入描述:
每个测试输入包含1个测试用例: I like beijing. 输入用例长度不超过100
输出描述:
依次输出倒置之后的字符串,以空格分割
示例1
输入:
I like beijing.
输出:
beijing. like I
这是题目链接,看完此篇文章可以点开试一试~~~
分析思路:
在拿到字符串后,首先想到的方法就是倒置字符串。但我们可能会遇到以下两个问题:
问题一:倒置字符串为整体倒置,无法将每一组单词位置分别进行倒置但单词内顺序不变
---->我们可以将字符串进行两次倒置。第一次整体进行倒置,第二次分别对每个单词进行倒置。
问题二:怎样倒置
---->在String字符串中没有内置的reverse函数,StringBuffer中有内置的reverse函数,但是我们通过看源码可知此函数没有参数传入,因此无法倒置指定区间的字符串。所以我们需要自己解决reverse函数。这个函数在牛客上也有链接,属于入门级编程,主要考察思想。
解决过程:
编写倒置函数:该函数需要传入三个参数:需要被倒置的数组arr,倒置开始下标start,倒置终止下标end。定义两个指针表示数组下标,每次交换开始下标与终止下标的元素。
对于输入进的字符串,我们先整体进行倒置,虽然每个单词的拼写顺序已经被打乱,但是每一个单词在应该输出结果的对应的位置。
倒置前 | l like beijing. |
倒置后 | gnijieb. ekil I |
对于已经倒置过的字符串我们定义两个指针,都指向起始位置,当j指针遇到空格或者j指针超出数组长度时,我们将两个指针的区间进行倒置,倒置后的两个指针重新指向合理的位置,准备进行下一次指向。
gnijieb ekil I |
i |
j |
beijing ekil I |
i |
j |
倒置后 i = j + 1;重新开始第二次的倒置,直到完成整个字符串的遍历。
注意:
在进行倒置函数编写时,需要使用void类型,当形参传入实参时,待倒置的数组arr就会被更新成已经成功的数组。若使用char[ ]类型,在倒置过程中会产生许多的与、临时变量。
打印时,如果直接输出Arrays.toString(arr)会被机器判定不通过,因为调用此函数时输出的结果被自动化分为一个个独立的字符,因此需要使用String进行接收,打印输出String类型的字符串。
Java实现代码如下:
import java.util.*;
public class Main{
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String given = in.nextLine();
char[] ans = given.toCharArray();
int len = ans.length;
reverse(ans,0,len-1);//将所有的字符进行倒置
int start = 0;
while(start < len) {
int end = start;
while(end < len && ans[end] != ' ') {//若只有一个字符则出现越界,所以要用end<len进行判断
end++;
}
reverse(ans,start,end-1);//分别倒置每一部分
start = end + 1;
}
String ansEnd = new String(ans);//题目中要求按照字符串输出
System.out.println(ansEnd);
}
public static void reverse(char[] arr, int start, int end) {//可以设置为void型,arr中的元素自动倒置更新
while(start < end) {
char tmp = arr[start];
arr[start] = arr[end];
arr[end] = tmp;
start++;
end--;
}
}
}