Tekson

禧之狼

博客园 首页 联系 订阅 管理

10. 字符串

1)求一个字符串中连续出现次数最多的子串

#include "stdafx.h"

#include <iostream>

#include <string>

using namespace std;

int main()

{

     string str = "abcbcbcabc";

     size_t i, j, k;//用于控制循环

     size_t count, maxcount=1;//count用于计数,最小为;maxcount用于记录重复的最大次数,最小为

     string subStr;

     size_t len = str.size();

     for(i=0; i<len; ++i)

     {

         for(j=i+1; j<len; ++j)//每一次第二层循环结束后都要对maxcount进行更新

         {

              count = 1;//每次内循环时都要归为

              if(str.substr(i, j-i) == str.substr(j, j-i))//判断第一次连续重复的字符串的出现

              {

                   ++count;//只要有连续重复的字符串出现,则count至少为

                   for(k=j+(i-i); k<len && str.substr(i, j-i)==str.substr(k, j-i); ++k)

                       //寻找后续重复的字符串并计数,这一步只能在已经有重复子串的前提下进行,

                       //因此应该在第三层循环中进行

                       ++count;

              }

              if(count > maxcount)

              {

                   maxcount = count;

                   subStr = str.substr(i, j-i);

              }

         }

     }

    

     cout << "The sub-string \"" << subStr << "\"'s times is " << maxcount << endl;

}

2)找出字符串中重复出现的最长子串,并输出该子串及其首字符的位置

#include "stdafx.h"

#include <iostream>

#include <string>

using namespace std;

int main()

{

     string str = "eabcdbcebcfabc";//结果为abc's index is 1

     /*string str = "ddd"时,结果为dd's index is 0,可见,两个相同的子串可以彼此重叠, 但这时一定是若干个相同字符组成的*/

     size_t i, j;//用于控制循环

     size_t p1, p2;//pos用于存储重复字符串的位置;p1p2用于存储正向和逆向搜索子串的位置

     string subStr;

     size_t len = str.size();

     for(i=len-1; i>1; --i)//i为子串的长度,这里并没有强调一定要两个子串不重叠,故子串的最大长度可以为n-1

     {

         for(j=0; j<len && j+i<=len; ++j)//j+i<=len保证了以j为起始点i为子串长度的子串不会超出原字符串

         {

              subStr = str.substr(j, i);

              p1 = str.find(subStr);

              p2 = str.rfind(subStr);

              if(p1 != p2)//表明有重复的子串出现,且第一次满足此条件的一定是最长的子串

              {

                   cout << subStr << "\'s index is " << p1 << endl;

                   return 0;//当运行当此if子句时,则说明已经完成任务,故返回

              }

         }

     }

}

3)编写strstr()函数,返回值是字符串中子串的位置及其以后的所有字符

#include "stdafx.h"

#include <assert.h>

#include <iostream>

using namespace std;

const char *strstr(const char *str, const char *strSearch)

{

     assert(str!=NULL && strSearch!=NULL); //【注】assert函数需要头文件assert.h

     int i, j;//内外层循环索引

     for(i=0; str[i]!='\0'; ++i)

     {

         for(j=0; strSearch[j]!='\0' && str[i+j]==strSearch[j]; ++j);

         if('\0' == strSearch[j])

              return str + i;

     }

     return NULL;

}

int main()

{

     char *str="abcdbcebcfabc", *strSearch="fa";

     cout << strstr(str, strSearch) << endl;//输出:fabc

}

4)字符串倒置问题

倒置字符串但保持单词自身的顺序

【思想】采用<csting>头文件中的strtok()函数先将字符串中的单词(字符串的单词被看作是通过’ ’’,’’|’’.’’;’’-’等符号被隔开的子字符串)提取出来,然后分别将其存入到list<string>中,最后通过<algorithm>中的copy算法将list的各字符串按逆序打印出来,于是便可以达到目的。

#include <stdafx.h>

#include <cstring>

#include <string>

#include <iostream>

#include <vector>

#include <algorithm>

using namespace std;

int main()

{

     char str[]=", WXL, ,is, ,,,really-a,,,Niu|man. | ";

     const char *delims = " ,-|";//delimiter:分隔符,定界符

     vector<string> vstr;

     // Establish string and get the first token:

     char *token = strtok(str, delims);

     while( token != NULL )

     {

        vstr.push_back(token);

         // Get next token:

        token = strtok( NULL, delims); //NULL is the starting index of the next token substring

    }

     for(vector<string>::reverse_iterator iter=vstr.rbegin(); iter!=vstr.rend(); ++iter)

         //【注】这里要将iter声明为reverse_iterator,因为rbegin函数返回的是reverse_iterator

         cout << *iter << " ";

     cout << endl;

     //输出也可以通过一条语句来完成:copy(vstr.rbegin(), vstr.rend(), ostream_iterator<string>(cout, " "));

}

倒置字符串中的单词的字符顺序但保持单词间的顺序

【思想】采用<csting>头文件中的strtok()函数先将字符串中的单词(字符串的单词被看作是通过’ ’’,’’|’’.’’;’’-’等符号被隔开的子字符串)提取出来,然后分别将其存入到vector<string>中,然后对vector中每个元素进行排序,最后通过<algorithm>中的copy算法将vector的各字符串按逆序打印出来,于是便可以达到目的。

#include <stdafx.h>

#include <cstring>

#include <string>

#include <iostream>

#include <vector>

#include <algorithm>

using namespace std;

int main()

{

     char str[]="pots & pans";

     const char *delims = " \t,.;";

     vector<string> vstr;

     // Establish string and get the first token:

     char *token = strtok(str, delims);

     while( token != NULL )

     {

        vstr.push_back(token);

         // Get next token:

        token = strtok( NULL, delims); //NULL is the starting index of the next token substring

     }

     // Sort for every sub-string

     for(size_t i=0; i<vstr.size(); ++i)

     {

         for(string::size_type j=0,k=vstr[i].size()-1; j<k; ++j,--k)

              swap(vstr[i][j],vstr[i][k]);

     }

     copy(vstr.begin(), vstr.end(), ostream_iterator<string>(cout, " "));

     return 0; //it can be omited

}

5)转换字符串格式为:原来字符串里的字符+该字符串连续出现的个数,例如字符串:1233422222,转化为1121314125

#include <stdafx.h>

#include <string>

#include <iostream>

using namespace std;

int main()

{

     char str[]="1233422222";

     size_t i, j, k=0;//i,j为循环控制索引,而k为新数组的索引项

     size_t len = strlen(str);

     char *newStr = new char [2*len+1];//2*len+1为最坏情况(即无连续相同字符存在)下所占用的空间

     size_t n;

     for(i=0; i<len; i+=n)

     {

         for(j=i+1; j<len && str[j]==str[i]; ++j);

         newStr[k++] = str[i];

         n = j-i;

         newStr[k++] = n + '0';//【注】这里必须为n + '0',不能缺少'\0'

     }

     newStr[k] = '\0';

     cout << newStr << endl;

}

6)计算4000000000以内的最大的那个f(n)=n的值,函数f的功能是统计所有从0n之间所有含有数字1的数字和

#include <stdafx.h>

#include <string>

#include <iostream>

using namespace std;

int fun(const int n)

{

     char str[11];

     int i, j;

     int num = 0;//存储n中的个数

     int len;//len为转换后的字符串的长度,也即原整数的位数

     for(i=1; i<=n; ++i)

     {

         ultoa(i, str, 10); //ultoa函数将unsigned int转化为char *型字符串

         len = strlen(str);

         for(j=0; j<len; ++j)

         {

              if('1' == str[j])

                   ++num;

         }

     }

     return num;

}

int main()

{

     unsigned int i;//int的范围为-2^31~2^31-1,即-2147483648~2147483647,因此,应该声明为unsigned int

     for(i=4000000000; i>=1; --i)

         if(i==fun(i))

         {

              cout << i << endl;

              return 0;

         }

     cout << i << endl;

}

 

posted on 2009-11-09 22:39  珍宝老王  阅读(703)  评论(0编辑  收藏  举报