一、需求描述
输入一个字符串,编写程序将该字符串中的各个单词反序拼装并输出。例如,如果输入的字符串是“Hello, how do you do”,那么输出的字符串为“do you do how Hello,”。注意保留各个单词之间的空格及相应的标点符号。
二、算法设计
通过观察示例字符串(即“Hello, how do you do”),我们可以看到该字符串中各个单词与空格之间的关系为:单词总数=空格总数+1。也就是说,示例字符串中的空格总数为4,单词个数为5(即“Hello,”、“how”、“do”、“you”、“do”)。
因此,我们可以考虑先找出输入字符串中的空格总数,再根据空格找出各个单词,然后将这些单词反序拼装起来。
程序的总体流程如图1所示。
图1 程序的总体流程
三、特殊流程考虑
在编写程序的过程中,我们要对输入字符串的格式多做考虑,如:
1.输入字符串的开头几个字符为空格,即形如“ Hello,how do you do”,我们需要先将开头的几个空格去掉,再进行后续处理。
2.输入字符串的结尾几个字符为空格,即形如“Hello, how do you do ”,我们需要先将结尾的几个空格去掉,再进行后续处理。
3.输入字符串的中间几个字符为连续的空格,即形如“Hello, how do youdo”,我们需要先将连续的空格合并为一个空格,再进行后续处理。
4.只要输入字符串中的两个单词之间出现了空格,我们都把它们当作两个不同的单词,即使这两个单词没有实际的意思,即形如“Hello, how do y ou do”,其中的“y”和“ou”虽然要合并在一起才有意义,但我们仍然按照两个不同的单词进行处理。
四、程序代码
/********************************************************************** * 版权所有 (C)2016, Zhou Zhaoxiong。 * * 文件名称: ReverseTheString.c * 文件标识: 无 * 内容摘要: 将字符串中的单词反序 * 其它说明: 例如, 将"I'm a student"转变为"student a I'm" * 当前版本: V1.0 * 作 者: Zhou Zhaoxiong * 完成日期: 20160215 * **********************************************************************/ #include#include // 重新定义数据类型 typedef signed char INT8; typedef unsigned short int UINT16; typedef int INT32; typedef unsigned int UINT32; // 函数声明 INT32 GetFieldFromString(INT8 *pszIn, INT8 cSplitter, UINT16 iIdx, INT8 *pszOut, UINT16 iLen); void CombineSpace(INT8 *pszOldStr, INT8 *pszNewStr); /********************************************************************** * 功能描述: 主函数 * 输入参数: 无 * 输出参数: 无 * 返 回 值: 0-执行成功 其它-执行失败 * 其它说明: 无 * 修改日期 版本号 修改人 修改内容 * --------------------------------------------------------------------- * 20160215 V1.0 Zhou Zhaoxiong 创建 ***********************************************************************/ INT32 main() { INT8 szTestStr[500] = {0}; INT8 szTmpStr[500] = {0}; // 用于存放经过规范化处理之后的字符串 INT8 szResultStr[500] = {0}; INT8 szFieldVal[100] = {0}; INT32 iPosFlag = 0; INT32 iRetFlag = 0; UINT32 iBlankCount = 0; printf("Please input the string: \n"); gets(szTestStr); printf("TestStr=%s\n", szTestStr); // 去除测试字符串中多余的空格及前后的空格 CombineSpace(szTestStr, szTmpStr); // 获取测试字符串中的空格字符的个数 iPosFlag = 0; while (szTmpStr[iPosFlag] != '\0') { if (szTmpStr[iPosFlag] == ' ') { iBlankCount ++; } iPosFlag ++; } // 将测试字符串中的单词按照反序来拼接 strcat(szTmpStr, " "); // 在测试字符串最后面添加空格, 用于解析各个单词 for (iPosFlag = iBlankCount; iPosFlag >= 0; iPosFlag --) { memset(szFieldVal, 0x00, sizeof(szFieldVal)); iRetFlag = GetFieldFromString(szTmpStr, ' ', iPosFlag, szFieldVal, sizeof(szFieldVal)-1); if (iRetFlag != 0) { printf("Exec GetFieldFromString to get FieldVal failed!\n"); return -1; } if (strlen(szResultStr) > sizeof(szResultStr)-1) // 字符串超长, 直接退出 { break; } else { strcat(szResultStr, szFieldVal); // 将各个单词拼接起来 strcat(szResultStr, " "); // 在各个单词后面添加空格 } } if (szResultStr[strlen(szResultStr)-1] == ' ') { szResultStr[strlen(szResultStr)-1] = '\0'; // 去除最后面的空格 } printf("ResultStr=%s\n", szResultStr); return 0; } /********************************************************************** * 功能描述: 从字符串中获取字段的值 * 输入参数: 无 * 输出参数: 无 * 返 回 值: 0-执行成功 其它-执行失败 * 其它说明: 无 * 修改日期 版本号 修改人 修改内容 * --------------------------------------------------------------------- * 20160215 V1.0 Zhou Zhaoxiong 创建 ***********************************************************************/ INT32 GetFieldFromString(INT8 *pszIn, INT8 cSplitter, UINT16 iIdx, INT8 *pszOut, UINT16 iLen) { INT8 *pszStart = NULL; INT8 *pszEnd = NULL; UINT16 iCount = 0; UINT16 iFiledLen = 0; INT8 szBuf[1024] = {0}; if (NULL == pszIn || NULL == pszOut) { return -1; } pszStart = pszIn; for (iCount = 0; iIdx != iCount; iCount++) // for循环用于查找当前字段的起始位置 { pszStart = strchr(pszStart, cSplitter); if (NULL == pszStart) { break; } else { pszStart ++; } } if (NULL == pszStart) { return -2; } pszEnd = strchr(pszStart, cSplitter); if (NULL == pszEnd) { return -3; } // 判断长度大小, 防止拷贝字符串时越界 if (pszEnd - pszStart > sizeof(szBuf)-1) { iFiledLen = sizeof(szBuf)-1; } else { iFiledLen = pszEnd - pszStart; } strncpy(szBuf, pszStart, iFiledLen); if (iLen
五、程序测试
我们将编写好的程序“ReverseTheString.c”上传到Linux机器,并使用“gcc -g -o ReverseTheStringReverseTheString.c”命令对该程序进行编译,生成“ReverseTheString”文件。下面对程序进行详细的测试。
1.输入字符串为“Hello, how do you do”时,程序运行情况如下:
Please input the string:
Hello, how do you do
TestStr=Hello, how do you do
ResultStr=do you do how Hello,
2.输入字符串为“ Hello, how do you do”(注意,前面有两个空格)时,程序运行情况如下:
Please input the string:
Hello, how do you do
TestStr= Hello, how doyou do
ResultStr=do you do how Hello,
3.输入字符串为“Hello, how do you do ”(注意,后面有两个空格)时,程序运行情况如下:
Please input the string:
Hello, how do you do
TestStr=Hello, how do you do
ResultStr=do you do how Hello,
4.输入字符串为“Hello, how do you do”(注意,中间有连续的空格)时,程序运行情况如下:
Please input the string:
Hello, how do you do
TestStr=Hello, howdo you do
ResultStr=do you do how Hello,
5.输入字符串为“Hello, ho w do yo u do”(注意,将几个完整的单词用空格分开)时,程序运行情况如下:
Please input the string:
Hello, ho w do yo u do
TestStr=Hello, ho w do yo u do
ResultStr=do u yo do w ho Hello,
可见,对于上面考虑到的几种特殊情况,程序均能做出正确的处理。
六、需求扩展
基于本文中的需求和程序,我们可考虑对需求进行以下扩展:
1.将反序之后的字符串的首字母大小,并将反序之前的首字母从大写变为小写,即将“Hello, how do you do”转换为“Do you do how hello,”。
2.不改变原字符串中的最后的标点符号的位置,即将“Hello, how do you do!”转换为“do you do how Hello,!”。
3.将原字符串中的标点符号去掉,即将“Hello, how do you do!”转换为“do you do how Hello”。