第四章 串的基本操作【數據結構】

運行截圖。

自己太久沒有這樣用過指針了,總是用不好~~

下次自己申請了一個指針,就得初始化,不然在判斷是否爲空的操作下,會導致程序停止運行。(傳說中的敲代碼5分鐘,debug2小時又被我碰上了,淚目)。


#include<stdio.h>
#include<string.h> 
#include<stdlib.h>
#include<malloc.h>
#define ERROR 0
#define OK 1
#define MAXSIZE 1000
typedef int Status;
//------串的堆存儲表示-------- 
typedef struct{
    char *ch;//若是非空串,則按串長分配存儲區,否則ch爲NULL 
    int length;//串長度 
}HString;
//--------------------------------------基本操作的算法描述--------------------- 
//生成一個其值等於串常量chars的串T 
Status StrAssign(HString *T,char *chars)
{
    int i,j;
    char *c;
    if(T->ch)
        free(T->ch);//釋放T原有的存儲空間 
    for(i = 0,c = chars;*c; c++,i++);//求chars串的長度 
    if(!i)
    {
        T->ch = NULL;
        T->length = 0;
    }
    else
    {
        T->ch = (char*)malloc(i*sizeof(char));
        if(!T->ch)
            exit(0);
        j = 0;
        while(j < i)
        {
            T->ch[j] = chars[j++];
        }
        T->length = i;
    }
    return OK;
}
//返回串S的長度
int StrLength(HString S) 
{
    return S.length;
}
//若S>T,返回值>0;若S==T,返回值=0;若S<T,返回值<0 
int StrCompare(HString S,HString T)
{
    for(int i = 0;i < S.length &&i< T.length ;i ++)
        if(S.ch[i]!=T.ch[i])
        {
            return S.ch[i] - T.ch[i];
        }
            
    return S.length - T.length ;
}

//清空串S 
Status ClearString(HString &S)
{
    if(S.ch)
    {
        free(S.ch);
        S.ch = NULL;
    }
    S.length = 0;
    return OK;
}
//連接串s1和串s2,用T返回 
Status Concat(HString &T,HString s1,HString s2)
{
    int i = 0,j;
    if(T.ch)
        free(T.ch);//釋放舊空間 
    T.ch = (char*)malloc((s1.length + s2.length )*sizeof(char));
    if(!T.ch)
        exit(0);
    while(i < s1.length)
    {
        T.ch[i] = s1.ch[i++];
    }
    T.length = s1.length + s2.length ;
    j = 0;
    while(j < s2.length)
    {
        T.ch [i++] = s2.ch[j++];
    }
    return OK;
}
//返回串s的第pos個字符起長度爲len的子串
Status SubString(HString &sub,HString s,int pos,int len)
{
    int i = 0;
    if(pos < 1||pos > s.length || len < 0||len > s.length -1)
        return ERROR;
    if(sub.ch)
        free(sub.ch);
    if(!len)//空子串 
    {
        sub.ch = NULL;
        sub.ch = 0;
    }
    else//完整子串 
    {
        sub.ch = (char*)malloc(len*sizeof(char));
        while(i < len)
        {
            sub.ch[i] = s.ch[pos+i-1];
            i++;
        }
        sub.length = len;
    }
    return OK;
} 
//在S串的第pos個字符前插入串T 
Status StrInsert(HString &S,int pos,HString T)
{
    if(pos < 0||pos > S.length-1)//pos 不合法 
        return ERROR;
    if(T.length)//T非空,則重新分配存儲空間,插入T 
    {
        S.ch = (char*)realloc(S.ch, (S.length + T.length)*sizeof(char));
        if(!S.ch)
            exit(0);
        for(int i = S.length-1; i >= pos-1;i--)//爲插入T 騰出位置 
            S.ch[i+T.length] = S.ch[i];
        for(int i = 0; i < T.length ; i ++)//插入T 
            S.ch[i+pos-1] = T.ch[i];
        S.length += T.length ;    
        S.ch[S.length] = '\0';
    }
    return OK;
}
int main()
{
    char s1[MAXSIZE],s2[MAXSIZE];
    HString SS,T,sub,S1,S2;
    int flag,pos,len;
    printf("請輸入串S1和串S2\n");
    while(scanf("%s %s",s1,s2),s1[0]!='#'&&s2[0]!='#')
    {
        T.ch = SS.ch = NULL;
        StrAssign(&SS,s1);//創建串T
        StrAssign(&T,s2); //創建串S 
        printf("S串爲:\n");
        for(int i = 0;SS.ch[i]!='\0';i++)
            printf("%c",SS.ch[i]);
        printf("\n");
        printf("T串爲:\n");
        for(int i = 0; T.ch[i]!='\0';i ++)
            printf("%c",T.ch[i]);
        printf("\n\n");
        
        printf("S串的長度爲%d\n\n",StrLength(SS));
        
        flag = StrCompare(SS,T);//比較兩串
        if(flag > 0)
            printf("S串>T串\n\n");
        else if(flag == 0)
            printf("S串=T串\n\n");
        else
            printf("S串<T串\n\n");
        S1.ch = S2.ch = NULL;
        StrAssign(&S1,s1);//創建串S1 
        StrAssign(&S2,s2);//創建串S2 
        Concat(T,S1,S2);//將串s1和串s2連接
        printf("連接後的串T爲:\n");
        for(int i = 0;T.ch[i]!='\0';i++)
            printf("%c",T.ch[i]);
        printf("\n\n");
        
        printf("請輸入要在S中輸出的子串的位置pos和長度\n"); 
        scanf("%d%d",&pos,&len);
        SubString(sub,SS,pos,len);//返回串s的第pos個字符起長度爲len的子串 
        printf("子串爲:\n");
        for(int i = 0; sub.ch[i]!='\0';i ++)
            printf("%c",sub.ch[i]);
        printf("\n");
        
        StrInsert(SS,pos,T);//在串S的第pos個位置前插入串T
        printf("在第%d個位置前入串T後的串S爲:\n",pos);
        for(int i = 0;SS.ch[i]!='\0';i++)
             printf("%c",SS.ch[i]);
        printf("\n");
        
        ClearString(SS);//清空串S
    }
    return 0;
 }