串的链块表示,操作复杂,不实用

Posted wjundong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了串的链块表示,操作复杂,不实用相关的知识,希望对你有一定的参考价值。

串的链块表示

#include <stdio.h>
#include <stdlib.h>

#define OK 1
#define ERROR 0
#define SRUE 1
#define FALSE 0

typedef int Status;

#define CHUNKSIZE 5

typedef struct Chunk

    char ch[CHUNKSIZE];
    struct Chunk *next;
Chunk;

typedef struct 

    Chunk * head, *tail;    /* 串的头和尾指针*/
    int curlen;             /* 串的当前长度 */ 
LString;

/* 生成一个其值等于chars的串S */
Status StrAssign(LString *S, char * chars)

    if(!S->head)   /* 头结点不存在 */ 
        S->head = (Chunk *)malloc(sizeof(Chunk));   /* 创建头结点 */
        S->tail = S->head;
        S->head->next = NULL;
    
    if(!S->head->next) 
        S->head->next = (Chunk *)malloc(sizeof(Chunk)); /* 创建第一个结点 */
        S->tail = S->head->next;           /* 尾指针指向第一个结点 */
        S->head->next->next = NULL;
        S->curlen = 0;                    /* 字符元素清零 */
    

    Chunk * p = S->head->next;        /* 指向第一个结点 */ 
    int chunklen = 0;
    for(int i=0; chars[i] != '\\0'; i++,S->curlen++) 
        p->ch[chunklen++] = chars[i];   
        if(chunklen % CHUNKSIZE == 0)  /* 数组到达末尾,则新开结点 */
            Chunk * q = (Chunk *)malloc(sizeof(Chunk));
            q->next = p->next;
            p->next = q;    /* 插入到末尾 */
            S->tail = q;    /* 尾指针指向末尾结点 */
            p = q;          /* 指向新插入点 */
            chunklen = 0;
         
    
    while(chunklen < CHUNKSIZE)
        p->ch[chunklen++] = '#'; /* 最后剩余空间填满 # */
    return OK;



/* 返回串S的元素个数 */
int StrLength(LString S)

    return S.curlen;



/* 清空字符串,并释放S所占的空间 */
Status ClearString(LString *S)

    int index = 0;
    while(S->head) 
        S->tail = S->head->next;
        free(S->head);
        index++;
        S->head = S->tail;
    
    printf("free %d\\n",index);
    S->curlen = 0;
    return OK;



/* 比较S,T,若S>T返回值>0 ,若S=T,返回0,若S<T,返回值<0 */
int StrCompare(LString S, LString T)

    if(!S.head->next || !T.head->next)
        return 0;
    int chunklen = 0;
    Chunk * pS = S.head->next;  /* 指向第一个结点 */
    Chunk * pT = T.head->next;
    for(int i=0; i<S.curlen && i<S.curlen; i++) 
        if(pS->ch[chunklen] != pT->ch[chunklen]) 
            return pS->ch[chunklen] - pT->ch[chunklen];
        chunklen++;
        if(chunklen % CHUNKSIZE == 0) 
            pS = pS->next;
            pT = pT->next;
            chunklen = 0;
        
    
    return S.curlen - T.curlen;


/* 用T返回由S1,S2拼接成的串 */
Status Concat(LString *T, LString S1, LString S2)

    // ... 未完成,这链块拼接真的不是那么简单,纠结在于最后的结点并不匹配,
    // 直接链表指指针的方式根本无法完成嘛
    if(!T->head)   /* 头结点不存在 */ 
        T->head = (Chunk *)malloc(sizeof(Chunk));   /* 创建头结点 */
        T->tail = T->head;
        T->head->next = NULL;
    
    T->head->next = S1.head->next;
    S1.tail->next = S2.head->next;
    T->curlen = S1.curlen + S2.curlen;
    return OK;


void PrintStr(LString S)

    if(!S.head) return;
    Chunk * p = S.head->next;   /* 指向第一个结点 */
    
    for(int chunklen=0,i=0; p && i<S.curlen; i++) 
        printf("%c",p->ch[chunklen++]);
        if(chunklen % CHUNKSIZE == 0)   /* 当前结点已经遍历,指向下一个结点 */
            p = p->next;
            chunklen = 0;
        
    
    printf("\\n");


int main()

    LString S1,S2,T;
    S1.head = NULL;
    S2.head = NULL;
    T.head = NULL;

    StrAssign(&S1,"Hello World");
    StrAssign(&S2,"This is a hello world");
    PrintStr(S1);
    PrintStr(S2);
    printf("compare %d\\n",StrCompare(S1,S2));
    Concat(&T,S1,S2);
    PrintStr(T);
    ClearString(&T);
    ClearString(&S1);
    ClearString(&S2);
    printf("OK");

可以看输出结果

最后一个结点填充#号,而拼接的时候如果只是把链表指向重新定向一下是不行的,没法去掉最后一个结点问题。而如果用一个一个复制的方法,那还不如用数组。强行改造也不行,一样效率低。
技术图片

以上是关于串的链块表示,操作复杂,不实用的主要内容,如果未能解决你的问题,请参考以下文章

第四章:1.串 -- 串类型定义及串的表示和实现

iptables实用教程:管理链和策略

最小表示法总结

数据结构 串

Java 判断以数字开头的字串的正则表示式怎么写?

数据结构两个单循环链表的连接操作