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 ,子串token
char* 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();
}