字符串的几个算法
1.字符串旋转: a b c d --> d c b a;
结合数据结构我用栈实现,因为这个过程就是进栈与出栈。但是如果单纯的字符串颠倒就不用这么麻烦直接首尾对调就可以了
//字符串翻转 void StrReverse(char* str,int start,int end) { char t; while(start<end){ t = str[start]; str[start++] = str[end]; str[end--] = t; } }
2.复杂点"I am a engineer!" --> "engineer! a am I"
这里是以单词为节点的颠倒,第一步是分割单词,第二步还是翻转,只不过这次翻转不能按照上面的方法来了。利用栈可以解决这个问题。
首先贴出栈的代码,以前已经实现过,不过这次添加了其他东西
int InitStack(Stack* q) { q->bottom = q->top = (Stack_Data*)malloc(INITSIZE*sizeof(Stack_Data)); if(!q->bottom)return -1; q->stack_size = INITSIZE; return 0; } //进栈 int Push(Stack* q,Stack_Data data) { if(q->top - q->bottom >= q->stack_size){ q->bottom = (Stack_Data*)realloc(q->bottom,sizeof(Stack_Data)*(q->stack_size+INCREAMENT)); if(!q->bottom)return -1; q->top = q->bottom + q->stack_size; q->stack_size += INCREAMENT; printf("栈空间不足,增加空间\r\n"); } *(q->top) = data; (q->top)++; return 0; } //出栈 int Pop(Stack* q,Stack_Data* data) { //判断栈空 if(q->bottom == q->top)return -1; (q->top)--; *data = *(q->top); return 0; }
这里是基本的初始化与进栈出栈操作,但是注意定义的节点结构体
typedef struct{ char a; int i; char str[20];//预留20个空间,保存字符串 }Stack_Data;
预留了字节数组保存字符串。如果单词大小超过20字节就会出错。准备了栈,还需要实现split函数
//字符串截断,返回字段数目 //regex:分割字符标志 //cp:保存分割的字符 //返回分割出的字符个数 int StrSplit(char* str,char regex,char* cp[]) { int i=0; int offset = 0; while(*str!='\0'){ if(*str == regex){ if(*(str-1) != regex){ //防止连续出现多个分割字符 i++; } offset = 0; }else{ //printf("%c",*str); *(cp[i]+offset) = *str; offset++; } str++; } return i+1; }
以上准备工作结束,可以完成单词翻转函数:
//单词翻转 //str:翻转的字符串 //collect:保存翻转单词后的数组 int WordReverse(char* str,char* collect[]) { char* wordArr[10];//零时保存单词,预留10个,如果要完备算法可以继续添加 Stack Q; //设定栈 Stack_Data stack_temp; int i,max; for(i=0;i<10;i++){ //分配堆空间保存单词 wordArr[i] = (char*)malloc(20*sizeof(char)); if(wordArr[i]){ memset(wordArr[i],0,20*sizeof(char));//记得初始化堆空间 }else{ return -1; } } max = StrSplit(str,' ',wordArr);//分割单词,保存分割出的单词个数 InitStack(&Q);//初始化栈 for(i=0;i<max;i++){//进栈 strcpy(stack_temp.str,wordArr[i]);//复制单词到栈节点 Push(&Q,stack_temp);//进栈 } for(i=0;i<max;i++){ Pop(&Q,&stack_temp);//出栈 strcpy(collect[i],stack_temp.str);//保存单词 //printf("%s ",stack_temp.str); } return 0; }
验证代码:
int main(int argc, char *argv[]) { char* str = "i am a engineer!"; char* strArr[10]; int i; for(i=0;i<10;i++){ strArr[i] = (char*)malloc(20*sizeof(char)); memset(strArr[i],0,10); } WordReverse(str,strArr); for(i=0;i<10;i++){ if(*strArr[i] == 0)break; printf("%s ",strArr[i]); } printf("\r\n"); system("pause"); return 0; }
运行结果:
3. 将abcdefg --> efgabcd 就是将前N个字符放到字符的结尾。
可以利用"三步翻转法":a. abcd --> dcba;
b. efg --> gfe;
c. dcbagfe -->efgabcd; 将上面翻转过的字符串合并在翻转就是要的结果
这个只不过是自己的流水账,偶尔有一些心得,错误的地方概不负责