【第九章:模板与群体数据】C9-4 翻转单词

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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值