您的位置:首页 > 其它

字符串反转

2014-04-16 22:32 155 查看
#include <iostream>
using namespace std;

//str要反转的字符串,len要反转的长度<=字符串长度
char * myreverse1(const char * str,int len)
{
if (!str)
return NULL;
char *newstr=new char[len];
strcpy(newstr,str);
char *start=newstr;
char *end = newstr+len-1;
char ch;
while (start<end)
{
ch=*start;
*start++ =*end;
*end--=ch;
}
return newstr;
}
//str要反转的字符串,长度在函数里计算
bool myreverse2(char *str)
{
if (!str)
return false;
//找到尾指针
char *start=str;//首指针
char *end = str;
while (*str)
{
++str;
}//循环结束后,str指向\0
end=str-1;//尾指针
char ch;
while (start<end)
{
ch=*start;
*start++ =*end;
*end--=ch;
}
return true;
}

int main()
{
char  mystr[]="welcome to 1301";
myreverse2(mystr);
cout<<mystr<<endl;
char *str="welcome to 1301";
char *newstr=myreverse1(str,15);
cout<<newstr<<endl;
}


注意:

一. 字符串指针和字符数组区别:

1 字符串指针变量本身是一个变量,用于存放字符串的首地址。而字符串本身是存放在以该首地址为首的一块连续的内存空间中并以‘\0’作为串的结束。

字符数组是以\0结束?

2 初始化:对字符串指针方式char *ps="C Language";也可以写为:

char *ps;

ps="C Language";

而对数组方式: char st[]={"C Language"};不能写为:

char st[20];

st={"C Language"};

初始化时没有赋值,后面只能对字符数组的各元素逐个赋值。

数组也可以用字符串常量进行初始化:

Char a[]=”abcdefg”;

3 数组和指针都可以在它们的定义中用字符串常量进行初始化,尽管看上去一样,底层的实现机制却不相同。

定义指针时,编译器并不为指针所指向的对象分配空间,它只是分配指针本身的空间,除非在定义的同时赋值给指针一个字符串常量进行初始化。例如:下面的定义创建了一个字符串常量(为其分配了内存):

char *p=”abcdefg”;

注意只有对字符串常量才是如此,不能指望为浮点数之类的常量分配空间,如:

Float *p=3.14; /*错误,无法通过编译*/

4 初始化指针时所创建的字符串常量被定义为只读。如果试图通过指针修改这个字符串的值,程序就会出现未定义的行为。在有些编译器中,字符串常量被存放在只允许读取的文本段中,以防止它被修改。

数组也可以用字符串常量进行初始化: Char a[]=”abcdefg”;

但是和指针相反,由字符串常量初始化的数组是可以修改的。其中的单个字符在以后可以改变。

所以上面程序两个函数分别对常量字符串反转和字符串数组反转。对常量反转不能修改原来指针所指字符,必须内部新分配控件,拷贝原来字符串再做修改。

char mystr2[]={'a','b','c'};
cout<<sizeof(mystr2)<<endl;
cout<<strlen(mystr2)<<endl;
cout<<mystr2<<endl;
char  mystr[]="welcome to 1301";
cout<<sizeof(mystr)<<endl;
cout<<strlen(mystr)<<endl;
cout<<mystr<<endl;
//myreverse2(mystr);

char *str="welcome to 1301";
char *newstr=myreverse1(str,15);
cout<<newstr<<endl;


执行结果:

3
7
abc虉
16
15
welcome to 1301
1031 ot emoclew
Press any key to continue

说明1 :修改为char mystr2[3]={'a','b','c'};//只分配三个字符空间,自然没给结束符\0分配空间。
cout<<sizeof(mystr2)<<endl;
cout<<strlen(mystr2)<<endl;
cout<<mystr2<<endl;

执行结果同上面,因为没有结束符所以strlen读到的会大些,有一些随机值。

2 修改为char mystr2[4]={'a','b','c'};
cout<<sizeof(mystr2)<<endl;
cout<<strlen(mystr2)<<endl;
cout<<mystr2<<endl;

输出:

4
3
abc

可见,分配分配4个字符空间,编译器会自动在结尾加\0;sizeof就是数组大小,而strlen是统计\0之前字符个数。

3 char mystr[15]="welcome to 1301";只分配15个字符空间,编译会出错:error C2117: 'welcome to 1301' : array bounds overflow。溢出。应该写16,或者不写,编译器都会在末尾加\0

字符串指针初始化后编译器自动加\0.

至于代码中char *newstr=myreverse1(str,15);传15看下回strcpy函数讲解。

继续单个单词反转:

#include <iostream>
using namespace std;

//
bool reverse_str(char * str,int startPos,int endPos)
{
int len=strlen(str);
if (startPos>endPos||startPos<0 ||endPos>=strlen(str))
return false;
char cTemp;
while (startPos<endPos)
{
cTemp = str[startPos];
str[startPos++]= str[endPos];
str[endPos--] = cTemp;
}
return true;
}
void reverse_word(char* strInput)
{
//转换成ohm ma i
reverse_str(strInput,0,strlen(strInput)-1);

//ohw ma i 每个单词反转
char* strStart = strInput;
int nStart = 0;
int nEnd = 0;
while( *strInput != '\0')
{
if ( *strInput == ' ')
{
reverse_str(strStart,nStart,nEnd-1);
nStart = nEnd +1;
//strStart = strInput;
}
nEnd ++;
strInput ++;
}
//最后一个单词,nEnd ++后指针移到\0,退出循环了,但最后一个单词没有反转。
reverse_str(strStart,nStart,nEnd-1);
}

int main()
{
char str[]="welcome to 1301";
reverse_word(str);
cout<<str<<endl;
}


单链表+string实现单词翻转

//单链表实现字符串翻转
struct Word
{
string strword;
Word * pre;
};

int main()
{
//输入单个word,创建链表
Word *bom=NULL;
string mystr;
cout<<"输入单词,以回车结束"<<endl;
char ch;
while (ch!='\n')
{
cin>>mystr;
Word * lword=new Word;
lword->strword=mystr;
lword->pre=bom;
bom=lword;
ch=getchar();
}

//输出list
while (bom)
{
cout<<bom->strword<<' ';
bom=bom->pre;
}
}


或者

//单链表实现字符串翻转
struct Word
{
string strword;
Word * pre;
};

int main()
{
//输入单个word,创建链表
Word *bom=NULL;
string mystr;
cout<<"输入单词,以‘0’结束"endl;
cin>>mystr;
while (mystr!="0");
{

Word * lword=new Word;
lword->strword=mystr;
lword->pre=bom;
bom=lword;
cin>>mystr;
}

//输出list
while (bom)
{
cout<<bom->strword<<' ';
bom=bom->pre;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: