alg : 字符串按照字符进行循环移位(左旋转 or 右旋转)
来源:互联网 发布:java内存泄漏解决方法 编辑:程序博客网 时间:2024/05/22 12:29
题目需求:
算法:
/// 字符串循环左移或右移N个字符的算法/// * 将整个串全反转/// * 按照需要移动的字符个数将反转后的串分为2部分/// * 将这2个子字符串分别进行反转////// e.g. 原串: hello world, 要求循环左移3个字符/// * 将整个串反转, dlrow olleh/// * 按照循环的字符数3, 将翻转后的串分为2部分, [dlrow ol][leh]/// * 将这2个子字符串分别进行反转 [lo world][hel]/// 得到字符串按照字符为单位循环移位的结果为 lo worldhel
测试程序效果图:
测试程序算法实现:
// srcStringCirculator.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <windows.h>#include <locale.h>#include <tchar.h>#include "Helper\StringHelper.h"/// 字符串循环左移或右移N个字符的算法/// * 将整个串全反转/// * 按照需要移动的字符个数将反转后的串分为2部分/// * 将这2个子字符串分别进行反转////// e.g. 原串: hello world, 要求循环左移3个字符/// * 将整个串反转, dlrow olleh/// * 按照循环的字符数3, 将翻转后的串分为2部分, [dlrow ol][leh]/// * 将这2个子字符串分别进行反转 [lo world][hel]/// 得到字符串按照字符为单位循环移位的结果为 lo worldhelvoid DoStringCirculatorOnce(); ///< 开始一次字符串字符移位bool IsDoStringCirculatorAgain(); ///< 是否再开始一次新的字符串字符移位int _tmain(int argc, _TCHAR* argv[]){ setlocale(LC_CTYPE, ".936"); //< 控制台为中文输出 do { DoStringCirculatorOnce(); } while (IsDoStringCirculatorAgain()); _tprintf(L"\r\nEND, press any key to quit\r\n"); getchar(); /** run results */return 0;}void DoStringCirculatorOnce(){ wchar_t szBuf[_MAX_PATH]; ///< 用户输入的原始字符串 wchar_t * pszBuf = &szBuf[0]; size_t nInputBufLenMax = SIZEOF_WCHAR_ARRAY(szBuf); bool bLoopLeft = true; size_t nLoopCnt = 0; if (!GetUserInputStringCirculatorParam(pszBuf, nInputBufLenMax, bLoopLeft,nLoopCnt)) return; if (StringCirculator(pszBuf, bLoopLeft,nLoopCnt)) _tprintf(L"\r\n循环字符移位后的串为 : [%s]\n", szBuf); else _tprintf(L"\r\n操作失败\r\n");}bool IsDoStringCirculatorAgain(){ bool bRc = true; wchar_t cInput = L' '; ///< 用户输入的单个字符 wchar_t * pcInput = NULL; wchar_t szloopCnt[_MAX_PATH]; ///< 容纳用户输入的移位字符数 wchar_t * pszloopCnt = NULL; _tprintf(L"\r\n是否开始一次新的字符串字符移位? 输入'Y'为继续, 输入'N'为取消, 支持大小写\r\n"); pcInput = &cInput; GetUsrInput(pcInput, SIZEOF_WCHAR_ARRAY(cInput)); bRc = ((L'Y' == cInput) || (L'y' == cInput)); _tprintf(L"\r\n\r\n您的选择为[%s]\r\n", bRc ? L"继续" : L"取消"); return bRc;}
/// @file helper\StringHelper.h/// @brief 字符串辅助操作定义#ifndef __HELPER_STRING_HELPER_H__#define __HELPER_STRING_HELPER_H__#include <windows.h>#include <locale.h>#include <tchar.h>#define WCHAR_STR_END L'\0' ///< 串结束符#define WCHAR_WORD_END L' ' ///< 单词结束符#define SIZEOF_WCHAR_ARRAY(x) (sizeof((x)) / sizeof(wchar_t))/// @fn ReverseStringByWord/// @brief 对入参串进行单词反转, 单词之间的分隔符号为空格, /// e.g. Hello world, driver => driver world Hello/// @param IN OUT wchar_t * pcMsgW, 输入输出串, 反转后的结果串覆盖原字符串/// @return bool/// @retval true, 串反转成功/// @retval false, 串反转失败bool ReverseStringByWord(IN OUT wchar_t * pcMsgW);/// @fn ReverseString/// @brief 对入参串进行完全反转/// e.g. 123456 7890 => 0987 654321/// @param IN OUT wchar_t * pcMsgW, 输入输出串, 反转后的结果串覆盖原字符串/// @param IN size_t nLenMsg, 串长度/// @return bool/// @retval true, 串反转成功/// @retval false, 串反转失败bool ReverseString(IN OUT wchar_t * pcMsgW, IN size_t nLenMsg);/// @fn GetStringLength/// @brief 此算法不允许用C库函数参与串长度计算, 模拟实现计算串长度/// @param IN const wchar_t * pcMsgW, 输入串/// @param IN const wchar_t & cEndSeparator, 串的结束分隔符/// @param IN const wchar_t & cStrEndSeparator, 字符串结尾字符/// @return size_t, 返回的串长度. 如果串为NULL, 返回0.size_t GetStringLength(IN const wchar_t * pcMsgW, IN const wchar_t & cEndSeparator, IN const wchar_t & cStrEndSeparator = WCHAR_STR_END);/// @fn GetUserInputStringCirculatorParam/// @brief 请用户输入字符串, 指定左移或右移, 移位的字符数/// @param wchar_t *& pszUsrInput, 容纳用户输入字符的缓冲区, 外部给定, 必须有效/// @param size_t nInputBufLenMax, 输入缓冲区最大容量/// @param bool & bLoopLeft, 左移 = TRUE, 右移 = FALSE/// @param size_t & nLoopCnt, 移位的字符数, 可以大于字符串长度, 也可以为零,/// 最后的移位字符数为字符串实际长度(不包括结尾'\0')的模/// @return bool/// @retval true, 用户输入参数成功/// @retval false, 用户输入参数失败bool GetUserInputStringCirculatorParam(wchar_t *& pszUsrInput, size_t nInputBufLenMax, bool & bLoopLeft, size_t & nLoopCnt);/// @fn GetUsrInput/// @brief 给定输入缓冲区, 等待用户输入, 以回车作为结束符/// @param wchar_t *& pszUsrInput, 输入缓冲区/// @param size_t nInputBufLenMax, 输入缓冲区长度/// @return voidvoid GetUsrInput(wchar_t *& pszUsrInput, size_t nInputBufLenMax);/// @fn StringCirculator/// @brief 对输入串进行按字符数循环移位/// @param wchar_t *& pszUsrInput, 输入串/// @param bool bLoopLeft, 左移 = TRUE, 右移 = FALSE/// @param size_t nLoopCnt, 移位的字符数, 可以大于字符串长度, 也可以为零,/// 最后的移位字符数为字符串实际长度(不包括结尾'\0')的模/// @return bool/// @retval true, 成功/// @retval false, 失败bool StringCirculator(wchar_t *& pszUsrInput, bool bLoopLeft, size_t nLoopCnt);#endif
/// @file helper\StringHelper.cpp/// @brief 字符串辅助操作, 实现串反转, 字符串移位等操作#include "stdafx.h"#include "StringHelper.h"bool ReverseStringByWord(wchar_t * pcMsgW){ size_t nLenAll = 0; size_t nPosNow = 0; size_t nPosPrev = 0; size_t nLenStr = 0; if (NULL == pcMsgW) return false; /// 反转整个串 nLenAll = GetStringLength(pcMsgW, WCHAR_STR_END); if (!ReverseString(pcMsgW, nLenAll)) return false; /// 反转每个单词 while (nPosPrev < (nLenAll - 1)) { nLenStr = GetStringLength(pcMsgW + nPosPrev, WCHAR_WORD_END); /// 串长度 - 1 是位置, 位置是基于0的 nPosNow = nPosPrev + nLenStr - 1; if ((nPosNow <= nPosPrev) || (!ReverseString(pcMsgW + nPosPrev, nLenStr))) break; /// 下一个单词的起点是上一个单词的起点 + 一个单词分隔符长度 + 下一个单词的首字符 nPosPrev = nPosNow + 2; } return true;}bool ReverseString(IN OUT wchar_t * pcMsgW, IN size_t nLenMsg){ wchar_t * pcBegin = NULL; wchar_t * pcEnd = NULL; if (NULL == pcMsgW) return false; if (nLenMsg <= 1) return true; pcBegin = pcMsgW; pcEnd = pcMsgW + nLenMsg - 1; while (pcBegin < pcEnd) { /// 交换字符 *pcBegin ^= *pcEnd; *pcEnd ^= *pcBegin; *pcBegin ^= *pcEnd; /// 移动头尾指针 pcBegin++; pcEnd--; } return true;}size_t GetStringLength(IN const wchar_t * pcMsgW, IN const wchar_t & cEndSeparator, IN const wchar_t & cStrEndSeparator){ size_t nLenCnt = 0; const wchar_t * pcBegin = pcMsgW; if (NULL == pcBegin) return 0; while ((*(pcBegin + nLenCnt) != cEndSeparator) && (*(pcBegin + nLenCnt) != cStrEndSeparator)) nLenCnt++; ///< 当前字符不是cEndSeparator, 也不是字符串结尾, 计数++ return nLenCnt;}bool GetUserInputStringCirculatorParam(wchar_t *& pszUsrInput, size_t nInputBufLenMax, bool & bLoopLeft, size_t & nLoopCnt){ wchar_t cInput = L' '; ///< 用户输入的单个字符 wchar_t * pcInput = NULL; wchar_t szloopCnt[_MAX_PATH]; ///< 容纳用户输入的移位字符数 wchar_t * pszloopCnt = NULL; if (nInputBufLenMax < 1) { _tprintf(L"缓冲区长度无效, 必须 >= 1\r\n"); return false; } if (NULL == pszUsrInput) { _tprintf(L"缓冲区为空\r\n"); return false; } _tprintf(L"\r\n请输入字符串, 支持中文和分隔符, 以回车作为输入结束符:\r\n"); ::ZeroMemory(pszUsrInput, nInputBufLenMax * sizeof(wchar_t)); GetUsrInput(pszUsrInput, nInputBufLenMax); _tprintf(L"\r\n该字符串是左移还是右移? 输入'L'为左移, 输入'R'为右移, 支持大小写\r\n"); pcInput = &cInput; GetUsrInput(pcInput, SIZEOF_WCHAR_ARRAY(cInput)); bLoopLeft = ((L'L' == cInput) || (L'l' == cInput)); _tprintf(L"\r\n请输入移位字符数, 可以为0 或大于字符串长度, 最终的移位字符数为您输入的移位字符数模字符串长度\r\n"); ::ZeroMemory(szloopCnt, sizeof(szloopCnt)); pszloopCnt = &szloopCnt[0]; GetUsrInput(pszloopCnt, SIZEOF_WCHAR_ARRAY(szloopCnt)); nLoopCnt = _ttoi64(szloopCnt); _tprintf(L"\r\n\r\n您输入的字符串为: [%s]\r\n", pszUsrInput); _tprintf(L"\r\n字符串循环字符移位操作为: %s%d个字符\r\n", bLoopLeft ? L"左移" : L"右移", nLoopCnt);}void GetUsrInput(wchar_t *& pszUsrInput, size_t nInputBufLenMax){ size_t nPos = 0; wchar_t cInput = L' '; if ((NULL == pszUsrInput) || (nInputBufLenMax < 1)) return; while(1) { cInput = getwchar(); ///< _tprintf_s 有问题,不支持','分隔, 采用getwchar循环接收代替 if (L'\n' == cInput) break; if (nPos >= nInputBufLenMax) break; *(pszUsrInput + nPos++) = cInput; }}bool StringCirculator(wchar_t *& pszUsrInput, bool bLoopLeft, size_t nLoopCnt){ size_t nLenAll = 0; size_t nLoopCntReal = 0; if (NULL == pszUsrInput) return false; /// 反转整个串 nLenAll = GetStringLength(pszUsrInput, WCHAR_STR_END); if (!ReverseString(pszUsrInput, nLenAll)) return false; if (nLenAll < 1) return false; nLoopCntReal = nLoopCnt % nLenAll; if (0 == nLoopCntReal) return true; /// 反转2个子串, 串边界为 nLenAll - nLoopCntReal ReverseString(pszUsrInput, bLoopLeft ? (nLenAll - nLoopCntReal) : nLoopCntReal); ReverseString( pszUsrInput + (bLoopLeft ? (nLenAll - nLoopCntReal) : nLoopCntReal), bLoopLeft ? nLoopCntReal : (nLenAll - nLoopCntReal)); return true;}
- alg : 字符串按照字符进行循环移位(左旋转 or 右旋转)
- 左旋转字符串(数组循环移位)
- 数组循环移位(左旋转字符串)
- 左旋转字符串与右旋转字符串
- 【程序员编程艺术】学习记录2:左旋转字符串之循环移位法
- 旋转字符串(循环移位,rotate)
- 每天一题(47) - 旋转单词顺序 + 左旋转字符串 + 右旋转字符串
- 字符串右循环移位
- 字符串右循环移位
- 字符串右循环移位
- 字符串右循环移位
- 字符串旋转与移位
- 字符串旋转与移位
- 图片的左旋转,右旋转操作!
- 左旋转字符窜
- 字符串操作:左旋转字符串,右旋转字符串,判断一个字符串是否是另一个字符串旋转所得
- 左旋转字符串
- 左旋转字符串
- windows phone:动画
- 常用的系统HOOK方法
- ios开发创建单例的两种方法
- ubuntu 实用命令
- #pragma pack(n)使用
- alg : 字符串按照字符进行循环移位(左旋转 or 右旋转)
- 黑马程序员 + 第24天 网络编程
- linux源代码阅读工具(转载)
- string
- C++学习笔记
- java中的final关键字所起的作用
- 浮点数的比较
- NATIVE应用程序详细之一
- NATIVE应用程序详细之2 NATIVE应用程序的优势和劣势