字符串的算法总结

来源:互联网 发布:美国超级计算机和知乎 编辑:程序博客网 时间:2024/06/06 01:24

1、按单词反转字符串

问题:

单词用空格分开的字符串,如 Here is blog.csdn.net/chenjiayi 经过反转后变为:blog.csdn.net/chenjiayi is Here

方法:

1)遍历字符串,将第一个字符和最后一个字符交换,第二个字符和倒数第二个字符交换,以此类推。

2)遍历一遍字符串,按照单词反转,对每一个单词再反转一次

代码如下:  

char * reverseWord(const char *str){    int len = strlen(str);    char * restr = new char[len+1];        strcpy(restr,str);    char tmp;   //首尾交换,i是首的索引 j是尾的索引     for(int i=0,j=len-1;i<j;++i,--j){        tmp = restr[i];        restr[i] = restr[j];        restr[j] = tmp;    }        //再把每个单词反转     int i,j,k = 0;      while(k<len){    while(len > k && restr[k] == ' ')++k;//跳过空格,找到下一个单词开始         i = j = k;        while(restr[j]!=' ' && restr[j]!='\0')            ++j;//查找空格的索引                 k = j;//记录空格索引          //反转单词         char tmp;      for(--j;i<j;++i,--j){            tmp = restr[i];            restr[i] = restr[j];            restr[j] = tmp;        }    }        return restr;  }  


2、字符串反转

题意:给定一个字符串,一个这个字符串的子串,将这个字符串反转,但保留子串的顺序不变。

例如:输入 每一个串 “this is wufl's Chinese site: http://blog.csdn.net/wufenglong”

子串:“wufl”

输出: gnolgnefuw/tne.ndsc/golb//:ptth:eits esenihC s'wufl si siht

说明:

扫描一遍字符串,扫描中如果发现子串,就将子串倒过来压入数组末尾,否则就正向压入字符串的字符到数组末尾。最后翻转数组字符。

代码如下: 

//字符串 str ,子串tokenchar* reverseStr(const char * str, const char * token){    assert(str && token);        char * array = new char[strlen(s1)+1];  //数组  int   arrayIndex = 0;  const char * ptoken = token, *head = str, *rear =str;        while(*head){        while(*head && *ptoken == *head){            ptoken++;            head++;        }                if(*ptoken=='\0'){  //是一个子串          const char *p;                        for(p=head-1;p>=rear;p--){  //反向压入字符子串              array[arrayIndex] = *p;                ++arrayIndex;          }            rear = head;//跳过子串         }else{  //不是一个子串        array[arrayIndex] = *rear;  //正向压入字符串的字符          ++arrayIndex ;             head = ++rear;  //跳过一个字节      }        ptoken = token;  //重新记录子串位置  }        array[arrayIndex] = 0;  int i,j = 0;    char tmp;  //翻转数组  for(i = arrayIndex-1;j < i;--i,++j)    {  tmp =  array[j];  array[j] = array[i];  array[i] = tmp;  }  return array;}  


3、获取两个字符串最大子串

3种实现方式:

(1)c风格 不使用字符串相关的api

#include <iostream> #include <string> using namespace std; char * longestCommonSubstring(const char *str1, const char *str2) {if(!str1 || !str2)return NULL;int strLen1 = strlen(str1);int strLen2 = strlen(str2);int minLen = (strLen1 < strLen2) ? strLen1:strLen2;if(!minLen)return NULL;int count;for (int i = minLen;i>0;i--)//最大字串长度尝试是从大到小{for (int j = 0;j < strLen2;j++){const char *tmpStr1Start = str1;const char *tmpStr2Start = str2 + j;//第二个字符串中的子串开始位置for (;(tmpStr1Start+i-1)[0];tmpStr1Start++)//第一个字符串中的子串开始位置{const char *tmpStr1 = tmpStr1Start;const char *tmpStr2 = tmpStr2Start;count = 0;while (*tmpStr1++ == *tmpStr2++ && ++count <= i);//子串长度if (count >= i)//最大子串{char *tmpStr = (char *)malloc(count + 1);memcpy(tmpStr,tmpStr2Start,count);(tmpStr + count)[0] = 0;return tmpStr;}}}} return NULL;}




(2)c风格 ,使用了strncmp

char * longestCommonSubstring2(const char *str1, const char *str2) {int strLen1 = strlen(str1);int strLen2 = strlen(str2);int minLen = (strLen1 < strLen2) ? strLen1:strLen2;for (int i = minLen;i>0;i--){for (int j = 0;j < strLen2;j++){const char *tmpStr1Start = str1;const char *tmpStr2Start = str2 + j;for (;(tmpStr1Start + i)[0] != 0;tmpStr1Start++){if(0 == strncmp(tmpStr1Start,tmpStr2Start,i)){char *tmpStr = (char *)malloc(i + 1);memcpy(tmpStr,tmpStr2Start,i);(tmpStr + i)[0] = 0;return tmpStr;}}}} return "";}

(3)c++风格

string longestCommonSubstring3(string const& s1, string const& s2) { int n = min(s1.length(), s2.length()); int len1 = s1.length(); string ss; for (int i = n; i > 0; --i) { for (int j = 0; j <= len1-i; ++j) { ss = s1.substr(j, i); if (s2.find(ss, 0) != string::npos) { return ss; } } } return string(); }



原创粉丝点击