C9-4 翻转单词 (100/100 分数)
题目描述
给定一个字符串,字符串中包含用空格隔开的单词。翻转字符串中所有单词的顺序。
输入描述
输入为一个长度不超过1000的字符串,字符串中有用空格隔开的单词。
输出描述
输出翻转单词顺序之后的字符串。
样例输入
I love Tsinghua
Tsinghua
样例输出
Tsinghua love I
Tsinghua
代码实现
1.交换模板函数
template<class T>//交换模板函数
void forswap(T &a, T &b)
{
T c;
c = a;
a = b;
b = c;
}
2.颠倒字符串函数
该函数负责将输入字符串的指定位置颠倒顺序,所以需要输入(字符串,首位置,末位置)
需要考虑如何写算法可以同时解决奇数个字符和偶数个字符的问题。(可尝试写成模板函数)
void Change(string &str,int L,int H)//颠倒字符串
{
int M = (H - L+1) / 2;
for (int i =0;i<M;i++)
{
forswap(str[L], str[H]);
L++;
H--;
}
}
3.寻找空格函数
该函数的作用为寻找指定字符串中空格的位置并且把坐标返回到指定数组中
指定数组的大小在main函数中解决
void findspace(const string str, int* a)//找到空格位置并返回位置至数组
{
int add = 0;
for (int i =0;i<str.length();i++)
{
if (str[i]==' ')//注意是单引号
{
a[add] = i;
add++;
}
}
}
4.单词个数函数
该函数负责查找字符串中单词的数量并返回,为了保证返回值的安全性,使用const int 保存返回值
const int HowManyWords(const string str)//单词个数
{
int count = 0;
for (int i = 0; i<str.length(); i++)
{
if (str[i]==' ')
{
count++;
}
}
count += 1;//之前的count是空格的个数,单词数为空格数+1
return count;
}
5.主函数
int main()
{
string str;
while (getline(cin, str))//接受有空格的字符串
{
// cout << str << endl;
int length = str.length();
// cout << length << endl;
int first = 0, end = length - 1;
// cout << str[first] << " " << str[end] << endl;
const int count = HowManyWords(str);
// cout << count << endl;
if (count==1)//如果只有一个单词,输出本身
{
cout << str << endl;
}
else
{
int num = count - 1;//count个单词,所以count-1个空格
int* spaceadd = new int[num];
Change(str, first, end);//字符串完全颠倒
// cout << str << endl;
findspace(str, spaceadd);
// for (int i=0;i<num;i++)
// {
// cout << spaceadd[i] << endl;
// }
for (int i = 0; i < count; i++)
{
if (i == 0)
{
first = 0;
end = spaceadd[0] - 1;
}
else if (i == count - 1)//因为从0开始计数,所以最后一次是count-1次
{
first = spaceadd[num - 1] + 1;
end = length - 1;
}
else
{
first = spaceadd[i - 1] + 1;
end = spaceadd[i] - 1;
}
Change(str, first, end);
// cout << str << endl;
}
cout << str << endl;
}
}
return 0;
}
注意
1.若想要输入含有空格的字符串,需要使用getline(cin,str);
2.数组元素坐标为0到size-1,在交换单个单词时的if语句中切记。
3.容易忽视只有一个单词时的情况,若不考虑,则会将该单词整体翻转,达不到题目要求。
4.勤写注释和检测代码,单步排除代码错误。
完整代码
#include <iostream>
#include <string>
using namespace std;
template<class T>//交换模板函数
void forswap(T &a, T &b)
{
T c;
c = a;
a = b;
b = c;
}
void Change(string &str,int L,int H)//颠倒字符串
{
int M = (H - L+1) / 2;
for (int i =0;i<M;i++)
{
forswap(str[L], str[H]);
L++;
H--;
}
}
void findspace(const string str, int* a)//找到空格位置并返回位置至数组
{
int add = 0;
for (int i =0;i<str.length();i++)
{
if (str[i]==' ')//注意是单引号
{
a[add] = i;
add++;
}
}
}
const int HowManyWords(const string str)//单词个数
{
int count = 0;
for (int i = 0; i<str.length(); i++)
{
if (str[i]==' ')
{
count++;
}
}
count += 1;
return count;
}
int main()
{
string str;
while (getline(cin, str))//接受有空格的字符串
{
// cout << str << endl;
int length = str.length();
// cout << length << endl;
int first = 0, end = length - 1;
// cout << str[first] << " " << str[end] << endl;
const int count = HowManyWords(str);
// cout << count << endl;
if (count==1)//如果只有一个单词,输出本身
{
cout << str << endl;
}
else
{
int num = count - 1;//count个单词,所以count-1个空格
int* spaceadd = new int[num];
Change(str, first, end);//字符串完全颠倒
// cout << str << endl;
findspace(str, spaceadd);
// for (int i=0;i<num;i++)
// {
// cout << spaceadd[i] << endl;
// }
for (int i = 0; i < count; i++)
{
if (i == 0)
{
first = 0;
end = spaceadd[0] - 1;
}
else if (i == count - 1)//因为从0开始计数,所以最后一次是count-1次
{
first = spaceadd[num - 1] + 1;
end = length - 1;
}
else
{
first = spaceadd[i - 1] + 1;
end = spaceadd[i] - 1;
}
Change(str, first, end);
// cout << str << endl;
}
cout << str << endl;
}
}
return 0;
}