//All rights reserved by panqiaomu from:http://blog.csdn.net/panqiaomu
// the Heap and Stack are different data structures....
//Heap must be always dynamic but The stack can be static with array or dynamic with linklist...
//Heap has no fixed order but the Stack must obey the rule:FILO
# include <stdlib.h>
# include <stdio.h>
# include <string.h>
//the storage structure:
typedef struct {
char* ch;
int length;
}*HeapStr;
//Create a "string variable"(memory space) for a string constant;
void StrAssign(HeapStr s, char* strconst){
int len = strlen(strconst);
if(s->ch) free(s->ch);
if(!len){
s->ch = NULL;
s->length = 0;
}
else{
s->ch = (char*)malloc(len+1); //+1
if(!s->ch)
exit(0);
strcpy(s->ch,strconst);
s->length = len;
}
}
// Insert a string into another before position pos which bases on the whole operation;
void InserStr(HeapStr s, int pos ,HeapStr t){
int i;
int len = t->length;
if(pos < 1 || pos > s->length + 1)
exit(0);
if(t->ch){// or t->length;
if(!(s->ch = (char*)realloc(s->ch,s->length + t->length)))
exit(0);
//"Tim,fall back";
for(i = s->length ; i >= pos - 1; --i) //include the '/0'so beginning with s->length not -1....
s->ch[i + len] = s->ch[i];
//Begin inserting the char streams;
//Don't call the function strcpy and copy the '/0' to string s which is wrong;
for(i = 0; i< len; ++i)
s->ch[pos-1 + i] = t->ch[i];
s->length += len;
}
}
//Return the length of the string
int StrLen(HeapStr s){
return s->length;
}
//Clear the string to empty(NULL);
void ClearStr(HeapStr s){
if(s->ch){
free(s->ch);
s->ch = NULL;
}
s->length = 0;
}
// ** Important OP:the match of strings beteen the main string and mode string;
// ** the classic one:String-Search Thought that we will realize it as follows;
// ** the rest ones:KMP and its progress,BM,KR and so on
int PatMatch(HeapStr ms, HeapStr pat , int pos){
int i,j;
if(pos < 1 || pos > ms->length) //match after 'pos';
exit(0);
i = pos-1;
j = 0;
while(i < ms->length && j < pat->length){
if(ms->ch[i] == pat->ch[j]){
++i;
++j;
}
else{ //i and j "fall back ",the worst situation is O(s->length*m->length);
i = i-j+2;
j = 1;
}
}//while
if (j >= pat->length)
return i - pat->length+1;
else
return 0; //Failure and return 0;
}
//Replace the substring Sub with string Target in string Ms;
void ReplaceStr(HeapStr ms,HeapStr sub, HeapStr tar){
int pos = 1;
int i;
if(!tar->ch) return;
pos = PatMatch(ms,sub,pos);
while(pos){
if(tar->length <= sub->length){
for(i = 0; i< tar->length; ++i) //replace...
ms->ch[pos-1+i] = tar->ch[i];
if(tar->length != sub->length) // not equal that is to say: <
for(i = pos-1+sub->length;i <= ms->length; ++i) // move to the front....
ms->ch[i - sub->length + tar->length] = ms->ch[i];
ms->length -= (sub->length - tar->length);
}//if
else{
ms->ch = (char*)realloc(ms->ch,ms->length+tar->length - sub->length); //reallocate...not +1
if(!ms->ch)
exit(0);
for(i = ms->length; i >= pos-1+sub->length; --i) //move to the back....
ms->ch[i+tar->length-sub->length] = ms->ch[i];
for(i = 0;i< tar->length; ++i) //replace....
ms->ch[i+pos-1] = tar->ch[i];
ms->length += (tar->length - sub->length);
}//else
pos += tar->length+1;
pos = PatMatch(ms,sub,pos);
}
}
//Request the substring from the position 'pos' with the length 'len'
void SubStr(HeapStr sub, HeapStr s, int pos, int len){
if(pos < 1 || pos > s->length || len < 0 || len > s->length - pos + 1)
exit(0); // make sure the strenth of codes;
if(sub->ch) free(sub->ch);
if(!len){ //request an empty string ;
sub->ch = NULL;
sub->length = 0;
}
else{
if(!(sub->ch = (char*)malloc(len+1)))
exit(0);
strncpy(sub->ch,s->ch+pos-1,len); //Call function strncpy();
sub->ch[len] = '/0';
sub->length = len;
}
}
//Begin testing in function main()
int main(){
int pos;
HeapStr r,s,t,sub;
StrAssign(s,"Hello,my name is panqiaomu and your name?");
StrAssign(t,"qiaomu ");
StrAssign(r,"mumumumumu");
StrAssign(sub,""); //(sub,NULL)
printf("Call the function InserStr() ......../n");
InserStr(s,7,t);
printf("the Inserted string is:%s/n",s->ch);
printf("the ms string length is:%d/n" ,StrLen(s));
printf("Call the function ReplaceStr()......./n");
ReplaceStr(s,t,r);
printf("the Replaced string is:%s/n",s->ch);
printf("Call the function SubStr().........../n");
SubStr(sub,s,3,3);
printf("the substring is:/n%s/n",sub->ch);
getch();
return 0;
}
/*Summary:(1)不要等到所有的子函數全部寫完後再在主函數裡面測試,這樣的會有很多麻煩,應該每一個模組寫完後及時測試。
(2)不要一上來就動手編程,應該首先在大腦裡面有一個解決問題的總體架構,要考慮全面,包括所有可能出現的情況。
(3)指標向數組轉化的時候,要注意數組的下標是從0開始的,這一點在C語言中最讓人頭痛和討厭。
(4)為字串申請空間,注意什麼時候加1,什麼時候不加1,比如建立字串變數要加1的,其他的操作比如替換,插入
就不需要,因為原字串中就已經存在了'/0'.*********************/