在筆試、面試中經常出現對字符串的操作,所以對於字符串的常用操作要熟練掌握。同時也要牢固掌握字符串的基本操作。
在C語言中,可以通過如下的方式來聲明字符串:
1、char *str="字符串";// 字符常量
- # include <stdio.h>
- # include <math.h>
- void DelSpace(char *s){
- if(s == NULL) return;
- int flag = 0 ;
- if(*s == ' ') flag = 1;
- char *p = s;
- int j = 0;
- while(*p != '\0'){
- if(*p != ' ')
- s[j++] = *p;
- else{
- while(*p == ' '){
- p++;
- }
- // 在首或尾的地方不需要再加入空格,p++可能導致這裏的p指向'\0'
- if(flag==1 || *p=='\0'){
- flag = 0;
- }else{
- s[j++] = ' ';
- }
- p--;//方便外層的p++做處理
- }
- p++;
- }
- s[j] = '\0';
- }
- int main(){
- char str[]=" dddd psdf dd ";
- DelSpace(str);
- printf("%s",str);
- }
# include <stdio.h>
# include <math.h>
void DelSpace(char *s){
if(s == NULL) return;
int flag = 0 ;
if(*s == ' ') flag = 1;
char *p = s;
int j = 0;
while(*p != '\0'){
if(*p != ' ')
s[j++] = *p;
else{
while(*p == ' '){
p++;
}
// 在首或尾的地方不需要再加入空格,p++可能導致這裏的p指向'\0'
if(flag==1 || *p=='\0'){
flag = 0;
}else{
s[j++] = ' ';
}
p--;//方便外層的p++做處理
}
p++;
}
s[j] = '\0';
}
int main(){
char str[]=" dddd psdf dd ";
DelSpace(str);
printf("%s",str);
}
將一個字符串左邊的n個字符移動到右邊即左旋字符串。解決的思路非常多,但是有一個方法感覺比較好。首先想一下,如果要將一個字符串反轉,你會怎麼做?
(1)設兩個指針,一個指向字符串開頭start,一個指向字符串末尾end,然後交換指針的值。
(2)start加1,而end減1,直到start>=end爲止。
代碼如下:
- char * invert(char *start, char *end) {
- char tmp, *ptmp = start;
- while (start != NULL && end != NULL && start < end){
- tmp = *start;
- *start = *end;
- *end = tmp;
- start ++;
- end --;
- }
- return ptmp;
- }
char * invert(char *start, char *end) {
char tmp, *ptmp = start;
while (start != NULL && end != NULL && start < end){
tmp = *start;
*start = *end;
*end = tmp;
start ++;
end --;
}
return ptmp;
}
下面來反轉字符串。將一個字符串分成兩部分,X和Y兩個部分,在字符串上定義反轉的操作X^T,即把X的所有字符反轉(如,X="abc",那麼X^T="cba"),那麼我們可以得到下面的結論:(X^TY^T)^T=YX。顯然我們這就可以轉化爲字符串的反轉的問題了。
不是麼?ok,就拿abcdef 這個例子來說,若要讓def翻轉到abc的前頭,那麼只要按下述3個步驟操作即可:
1、首先分爲倆部分,X:abc,Y:def;
2、X->X^T,abc->cba, Y->Y^T,def->fed。
3、(X^TY^T)^T=YX,cbafed->defabc,即整個翻轉。
如下圖所示。
具體的實現代碼如下:
- char *left(char *s, int pos) //pos爲要旋轉的字符個數,或長度,下面主函數測試中,pos=3。
- {
- int len = strlen(s);
- invert(s, s + (pos - 1)); //如上,X->X^T,即 abc->cba
- invert(s + pos, s + (len - 1)); //如上,Y->Y^T,即 def->fed
- invert(s, s + (len - 1)); //如上,整個翻轉,(X^TY^T)^T=YX,即 cbafed->defabc。
- return s;
- }
char *left(char *s, int pos) //pos爲要旋轉的字符個數,或長度,下面主函數測試中,pos=3。
{
int len = strlen(s);
invert(s, s + (pos - 1)); //如上,X->X^T,即 abc->cba
invert(s + pos, s + (len - 1)); //如上,Y->Y^T,即 def->fed
invert(s, s + (len - 1)); //如上,整個翻轉,(X^TY^T)^T=YX,即 cbafed->defabc。
return s;
}
3、求最長迴文子串
輸入一個字符串,求出其中最長的迴文子串。子串的含義是:在原串連續出現的字符串片段。迴文的含義是:正着看和倒着看是相同的,如abba和abbebba。輸入字符串長度大於等於1小於等於5000。
由於相同字母組成的一定是迴文子串,如a,aa,aaaa,所以在遍歷字符串字符時,直接找第i個元素(圖中淺綠n)左右兩邊與該字符不相同的字符,並用兩個指針pre和post指向。如下圖。
這樣就可以將pre--,post++,然後比較*pre和*post的值。如果相等,繼續pre--,post++(在操作時注意pre和post的邊界條件);如果不相等,記錄並更新迴文子串的長度即可。
代碼如下:
- #include <iostream>
- #include <cstdio>
- using namespace std;
- char *x;
- int length=0;
- void findCircle(char *str){
- if(str==NULL) return;
- char *pre=NULL,*post=NULL;
- for(str; *str!='\0'; str++){
- pre=str;post=str;
- while(*(post+1)!='\0'&&*(post+1)==*str) post++;
- while(*(pre-1)!='\0'&&*(pre-1)==*str) pre--;
- while( pre-1!=NULL&&post+1!=NULL&& (*(pre-1)==*(post+1)) ){
- pre=pre-1;
- post=post+1;
- }
- if(post-pre+1>length) {
- length=post-pre+1;
- x=pre;
- }
- }
- for(int i=0;i<length;i++){
- cout<<*(x++)<<" ";
- }
- }
- int main(){
- char *str;
- gets(str);
- findCircle(str);
- return 0;
- }
#include <iostream>
#include <cstdio>
using namespace std;
char *x;
int length=0;
void findCircle(char *str){
if(str==NULL) return;
char *pre=NULL,*post=NULL;
for(str; *str!='\0'; str++){
pre=str;post=str;
while(*(post+1)!='\0'&&*(post+1)==*str) post++;
while(*(pre-1)!='\0'&&*(pre-1)==*str) pre--;
while( pre-1!=NULL&&post+1!=NULL&& (*(pre-1)==*(post+1)) ){
pre=pre-1;
post=post+1;
}
if(post-pre+1>length) {
length=post-pre+1;
x=pre;
}
}
for(int i=0;i<length;i++){
cout<<*(x++)<<" ";
}
}
int main(){
char *str;
gets(str);
findCircle(str);
return 0;
}
參考博客July
- 頂
- 2
- 踩
- 0