单词翻转(4种思路,C/C++代码)

来源:互联网 发布:知乎问题怎么删除 编辑:程序博客网 时间:2024/05/21 17:05

输入一个英文句子,翻转句子中单词的顺序,要求单词内字符的顺序不变,句子中单词以空格隔开,为简单起见,标点符号和普通字母一样处理。例如:输入“I am a student.”则输出:“student. a am I”。

思路一:最后一个单词的位置是不用移动的。从后面往前面遍历,遇到第一个空格时,开始统计下一个单词的长度n,统计完成后将该单词后面的单词向前移动n位,并将该单词移动到字符串的末尾;依照这样的方式,直至遍历完整个字符串。

评:该方法的实现过程异常复杂,时间复杂度太高。

思路二:从后往前依次遍历源字符串src,每次遍历完一个单词后,直接将该单词整个拷贝到另一个字符串dst中,依次遍历原字符串,分别将每个独立的单词拷贝到dst中。

评:该算法的空间复杂度比较高,因为需要多申请一段空间dst来保存遍历的结果。

思路三:将整个字符串翻转,然后分别将字符串中的单个单词独立进行翻转。

思路四:三步反转法:先将每个单词分成独立的几部分,然后分别对它们进行翻转,返回将整个字符串进行翻转。(最后一步的翻转其实是可以省略的,直接将字符串从后往前输出即可)

评:思路三和四的思想是一样的,个人更喜欢第四种。

    输入:“I am a student.”

中间结果:“I ma a .tneduts”

    输出:“student. a am I”

C/C++代码

//输入“I am a student.”则输出:“student. a am I”。#include <stdio.h>  #include <string.h> #include <iostream>#include <string.h>using namespace std;void *reverse(char *src, char *dst){char *p1, *p2;if(src == NULL || dst == NULL){return NULL;}//从src的最后一个字符开始遍历p1 = src + strlen(src) - 1;p2 = p1;while (p1 != src){if (*p1 == ' '){int len = p2 - p1;//单词的长度memcpy(dst, p1 + 1, len);//每个单词的末尾加上一个空格dst += len;*dst++ = ' ';p1--;p2 = p1;}else{//不断将p1向前移动p1--;}}//最后一次拷贝单词int len = p2 - p1 + 1;memcpy(dst, p1, len);dst += len;*dst++ ='\0';}void print(char *s, int m){for (int i = 0; i < m; i++){if (s[i] == ' ')cout << " ";elsecout << s[i];}cout << endl;}int main(){char *dst;dst = (char*)malloc(sizeof(char) * 10);char a[] = "I am a student.";//单词的长度int n = strlen(a);cout << "n=" << n << endl;//显示未翻转前的字符串print(a, n);//单词翻转reverse(a, dst);//显示翻转之后的字符串print(dst, n);return 0;}

//三步反转法#include"stdafx.h"#include<iostream>using namespace std;void print(char *s, int m){for (int i = 0; i < m; i++){cout << s[i];}cout << endl;}//将每个单词进行翻转void reverse(char *s,int low,int high){while (low < high){int tmp = s[high];s[high] = s[low];s[low] = tmp;low++;high--;}}int main(){int num = 0;int low, high;//cout << "请输入一个字符串:";char a[] = "I am a student.";//单词的长度int n = strlen(a);cout << "n=" << n << endl;//显示未翻转前的字符串print(a, n);//将字符串分为独立的几个单词,并分别进行翻转for (int i = 0; i <= n; i++){if (a[i] == ' '||a[i]=='\0'){//单词翻转reverse(a,i-num,i-1);num = 0;}else{num++;}}//中间结果print(a, n);//显示翻转之后的字符串for (int i = n-1; i >=0; i--){cout << a[i];}cout << endl;return 0;}

附:

memcpy 函数用于把资源内存(src所指向的内存区域)拷贝到目标内存(dest所指向的内存区域);拷贝多少个?有一个count变量控制拷贝的字节数;
函数原型:void *memcpy(void *dest, void *src, unsigned int count);
用法:可以拷贝任何类型的对象,因为函数的参数类型是void*(未定义类型指针),也就是说传进去的实参可以是int*,short*,char*等等但是由于函数拷贝的过程是一个字节一个字节的拷贝的,所以实际操作的时候要把void*强制转化为char*,这样在指针加的时候才会保证每次加一个字节

1 0
原创粉丝点击