对一个字符串求逆序,常用方法:
void reverse1(char *s) { int len=strlen(s); char *p=s;//p指向首字符 char *q=s+len-1;//q指向最后一个字符 while(q>p) { char tmp=*q;*q=*p;*p=tmp; q--; p++; } }
用递归的方式,需要给定逆序的区间,调用方法:Reverse(s, 0, strlen(s))
// 对字符串s在区间left和right之间进行逆序,递归法 void Reverse( char* s, int left, int right ) { if(left >= right) return s ; char t = s[left] ; s[left] = s[right] ; s[right] = t ; Reverse(s, left + 1, right - 1) ; }
三 非递归法,同样指定逆序区间,和方法一没有本质区别,一个使用指针,一个使用下标。
// 对字符串str在区间left和right之间进行逆序 char* Reverse( char* s, int left, int right ) { while( left < right ) { char t = s[left] ; s[left++] = s[right] ; s[right--] = t ; } return s ; }
逆序打印:
还有一类题目是要求逆序输出,而不要求真正的逆序存储。这题很简单,有下面几种方法,有的方法效率不高,这里仅是提供一个思路而已。
先求出字符串长度,然后反向遍历即可。
{
int len = strlen(s) ;
for (int i = len - 1; i >= 0; --i)
cout << s[i];
}
如果不想求字符串的长度,可以先遍历到末尾,然后在遍历回来,这要借助字符串的结束符'
void ReversePrint(const char* s) { const char* p = s ; while (*p) *p++ ; --p ; //while结束时,p指向'',这里让p指向最后一个字符 while (p >= s) { cout <<*p ; --p ; } }
对于上面第二种方法,也可以使用递归的方式完成。
{
if(*(s +1) != '')
ReversePrint(s + 1) ;
cout << *s ;
}
我自己写的:
void reverse(char *s) { if(*s=='') { return; } else { func(s+1); cout<<*s; } }
注意,当s为字符串的指针使,cout<<s会输出整个字符串,我最开始
写成cout<<s 就错了。
按单词逆序:
给定一个字符串,按单词将该字符串逆序,比如给定"This is a sentence",则输出是"sentence a is This",为了简化问题,字符串中不包含标点符号。
分两步
1 先按单词逆序得到"sihT si a ecnetnes"
2 再整个句子逆序得到"sentence a is This"
对于步骤一,关键是如何确定单词,这里以空格为单词的分界。当找到一个单词后,就可以使用上面讲过的方法将这个单词进行逆序,当所有的单词都逆序以后,将整个句子看做一个整体(即一个大的包含空格的单词)再逆序一次即可,如下图所示,第一行是原始字符换,第二行是按单词逆序后的字符串,最后一行是按整个句子逆序后的字符串。
// 对指针p和q之间的所有字符逆序 void ReverseWord(char* p, char* q) { while(p < q) { char t = *p ; *p++ = *q ; *q-- = t ; } } // 将句子按单词逆序 char* ReverseSentence(char* s) { // 这两个指针用来确定一个单词的首尾边界 char* p = s ; // 指向单词的首字符 char* q = s ; // 指向空格或者 '' while(*q != '') { if (*q == '') { ReverseWord(p, q - 1) ; q++ ; // 指向下一个单词首字符 p = q ; } else q++ ; } ReverseWord(p, q - 1) ; // 对最后一个单词逆序 ReverseWord(s, q - 1) ; // 对整个句子逆序 return s ; } int main() { /// string s; // cin>>s; char s[100]; gets(s); cout<<strlen(s)<<endl; ReverseSentence(s); cout<<s<<endl; }
注意gets(s),最开始我用的是scanf("%s",s);发现输入this is.strlen(s)为4.原因是scanf忽略空格和换行符。gets则可以接受换行符。
char string[15]; gets(string); /*遇到回车认为输入结束*/
scanf("%s",string); /*遇到空格认为输入结束*/
所以在输入的字符串中包含空格时,应该使用gets输入。
leetcode题目:https://oj.leetcode.com/problems/reverse-words-in-a-string/
Given an input string, reverse the string word by word.
For example,
Given s = "the sky is blue
",
return "blue is sky the
".
- What constitutes a word?
A sequence of non-space characters constitutes a word. - Could the input string contain leading or trailing spaces?
Yes. However, your reversed string should not contain leading or trailing spaces. - How about multiple spaces between two words?
Reduce them to a single space in the reversed string.
void reverseWords(string &s) { string rs; for (int i = s.length()-1; i >= 0; ) { while (i >= 0 && s[i] == ' ') i--; if (i < 0) break; if (!rs.empty()) rs.push_back(' '); string t; while (i >= 0 && s[i] != ' ') t.push_back(s[i--]); reverse(t.begin(), t.end()); rs.append(t); } s = rs; }
更多:http://www.2cto.com/kf/201403/286602.html
参考:http://www.cnblogs.com/graphics/archive/2011/03/09/1977717.html