几个经典的字符串操作算法
1、编写函数,实现把一个char组成的字符串循环右移n位。如abcdehi,n=2,则hiabcde。
示例代码
#include "iostream" using namespace std; const int MAX_LEN = 20; void LoopMove( char * cpStr, int iSteps) { //注意,在整个处理过程中,cpStr的最后字符都没有涉及处理 char cTempArray[MAX_LEN]; size_t szStrLength = strlen (cpStr); size_t in = szStrLength -iSteps; memcpy (cTempArray, cpStr + in, iSteps); memcpy (cTempArray + iSteps, cpStr, in); memcpy (cpStr, cTempArray, szStrLength); cTempArray[szStrLength + 1] = '\0' ; cout << cTempArray << endl; } int main() { char ctemp[] = "abcdefghi" ; LoopMove(ctemp, 2); cout << ctemp << endl; return 1; } |
2、输入一行字符串,找出其中出现的相同且长度最长的字符串,输出它及其首字符的位置。如yyabcdabjcabceg,则输出为abc,3。
大体思路:把字符串yyabcdabjcabceg拆解:
yyabcdabjcabceg
yabcdabjcabceg
abcdabjcabceg
...
ceg
eg
g
然后对字符串进行排序,比较相邻字符串的前驱,求最长的共公前驱。
在我们的程序中的体现,我们没有用这种方法,因为这种方法在排序中会用很多时间。我们借用了C++的实现函数find来巧妙的实现。
注:basic_string::substr
basic_string substr(size_type pos = 0, size_type n = npos) const;
The member function returns an object whose controlled sequence is a copy of up to n elements of the controlled sequence beginning at position pos.
返回一个从指定位置开始,并具有指定长度的子字符串。
参数
pos 必选。所需的子字符串的起始位置。字符串中第一个字符的索引为 0。
n 可选项。返回的子字符串中包含的字符数。
备注 如果 n 为 0 或负数,将返回一个空字符串。如果没有指定该参数,则子字符串将延续到字符串的结尾。
在VS中测试,如是n是负数或大于主串的总长度,则输出是pos开始到主串末尾的字符。
示例代码
#include "iostream" #include "string" using namespace std; int main() { string strInput; cout << "Input a string: " << endl; cin >> strInput; string strTemp; for ( size_t i = strInput.length() - 1; i > 1; i--) { for ( size_t j = 0; j < strInput.length(); j++) { if ((i + j) <= strInput.length()) { size_t szForw = 0; size_t szBacw = 0; strTemp = strInput.substr(j, i); szForw = strInput.find(strTemp); szBacw = strInput.rfind(strTemp); if (szBacw != szForw) { cout << strTemp << " " << szForw + 1 << endl; return 0; } } } } return 1; } |
3、实现strstr()功能。如主串是12345678,子串是234,则返回2345678。
示例代码
#include "iostream" #include "string" using namespace std; const char * strstr1( const char * strMainString, const char * strSubString) { for ( size_t i = 0; strMainString[i]; i++) { size_t iTempj = 0; size_t iTempi = i; if (strMainString[iTempi] == strSubString[iTempj]) { while (strMainString[iTempi++] == strSubString[iTempj++]) { if (strSubString[iTempj] == '\0' ) return &strMainString[i]; } } } return NULL; } int main() { char str1[] = "12345678" ; char str2[] = "234" ; const char *str3 = strstr1(str1, str2); cout << str3 << endl; return 1; } |
4、将一句话中的单词倒置,标点符号不倒换。如“i come from tianjin.”,倒换后变成“tianjin. from come i”。
大体思路:先把整个字符串调整,再针对每个单词进行调整。
示例代码
#include "iostream" #include "string" //#include "functional" //#include "algorithm" using namespace std; int main() { cout << "Input a string: " << endl; string strOfaLine; getline(cin, strOfaLine); size_t szStrLength = strOfaLine.length(); size_t szTempbeg = 0; size_t szTempend = szStrLength - 1; //第一步,全局交换 while (szTempbeg < szTempend) { swap< char >(strOfaLine[szTempbeg++], strOfaLine[szTempend--]); } //第二步,局部交换 size_t szTempi = 0; while (strOfaLine[szTempi]) { if (strOfaLine[szTempi] != ' ' ) { szTempbeg = szTempi; while (strOfaLine[szTempi] != '\0' && strOfaLine[szTempi] != ' ' ) { szTempi++; } szTempi--; szTempend = szTempi; } while (szTempbeg < szTempend) { swap< char >(strOfaLine[szTempbeg++], strOfaLine[szTempend--]); } szTempi++; } cout << strOfaLine << endl; return 1; } |
5、求一个字符串中连续出现次数最多的子串。
大体思路:如abcbcbcabc,则把字符串切割成:
abcbcbcabc
bcbcbcabc
cbcbcabc
bcbcabc
cbcabc
bcabc
...
bc
c
然后,从第一个子串开始到最后一个子串,将当前串与后面的每个子串进行字符匹配,并统计。
示例代码
#include "iostream" #include "string" #include "vector" //#include "functional" //#include "algorithm" using namespace std; pair< int , string> StaticNum( const string &str) { vector<string> substrs; //存放切割后的子字符串 string substr; int iMaxCount = 1, iCount = 1; size_t iTempi, iLen = str.length(); for (iTempi = 0; iTempi < iLen; iTempi++) { substrs.push_back(str.substr(iTempi, iLen - iTempi)); } for (iTempi = 0; iTempi < iLen; iTempi++) { for ( size_t iTempj = iTempi + 1; iTempj < iLen; iTempj++) { iCount = 1; if (substrs[iTempi].substr(0, iTempj - iTempi) == substrs[iTempj].substr(0, iTempj - iTempi)) { iCount++; //对以后子串每一个都进行比较,iTempj - iTempi 为当前要比较的字符串的长度 //注意,此时遍历时,步长是iTempj - iTempi for ( size_t iTempk = iTempj + (iTempj - iTempi); iTempk < iLen; iTempk += iTempj - iTempi) { if (substrs[iTempi].substr(0, iTempj - iTempi) == substrs[iTempk].substr(0, iTempj - iTempi)) { iCount++; } else //接下来的字符串已经不连续了 { break ; } } if (iCount > iMaxCount) { iMaxCount = iCount; substr = substrs[iTempi].substr(0, iTempj - iTempi); } } } } return make_pair(iMaxCount, substr); } int main() { string str; pair< int , string> rs; string strTemp = "abcbcbcabc" ; rs = StaticNum(strTemp); cout << rs.first << " " << rs.second << endl; return 1; } |