2020-9-23 //严蔚敏《数据结构》 //串:串的块链存储表示

//严蔚敏《数据结构》
//串:串的块链存储表示
//特殊之处(重要):除了指针p遍历链串之外,每个数据结点还需要额外的Chunkcount来进行结点内部数据的遍历(便于操作)
//自学中,加油!!!
#include<iostream>
using namespace std;
const int ChunkSize=4;

typedef struct CNode
{
    char ch[ChunkSize];
    struct CNode* next;
}CNode;

typedef struct
{
    CNode* head,* tail;
    int length;
}LString;

bool Init_str(LString& s)//初始化链串
{
    s.head=new CNode;
    if(!s.head)
        return false;
    s.head->next=nullptr;
    s.tail=s.head;
    s.length=0;
    return true;
}

bool Input_str(LString& s)//向链串中输入数据
{
    char ch;
    cout<<"输入数据 #停止\n";
    int Chunkcount=4;//此处默认在头结点的数据数组的最后一个
    CNode* p;
    while(cin>>ch,ch!='#'){
        if(Chunkcount==ChunkSize){
            p=new CNode;
            if(!p)
                return false;
            Chunkcount=0;
            p->ch[Chunkcount++]=ch;
            p->next=s.tail->next;
            s.tail->next=p;
            s.tail=p;
        }
        else{
            s.tail->ch[Chunkcount++]=ch;
        }
        s.length++;
        cout<<"该字符输入完成\n";
    }
    if(Chunkcount!=ChunkSize){//尾结点 剩余空间补'#'
        while(Chunkcount!=ChunkSize)
            s.tail->ch[Chunkcount++]='#';
    }
    if(!cin){
        cin.clear();
        while(cin.get()!='\n')
            continue;
    }
    return true;
}

void Output_str(LString s)//遍历输出
{
    CNode* p=s.head->next;
    cout<<"输出:\n";
    while(p){
        for(int i=0;i!=ChunkSize;i++)
            cout<<p->ch[i];
        cout<<endl;
        p=p->next;
    }
    cout<<"-----"<<endl;
}

bool Clear_Str(LString& s)//清空链串s
{
    CNode* p=s.head->next,* pp;
    while(p){
        pp=p;
        p=p->next;
        free(pp);
    }
    s.head->next=nullptr;
    s.tail=s.head;
    s.length=0;
    return true;
}

bool Assign_Str(LString& s,char* chars)//生成其值与chars相等的链串s(注意 chars的尾部应是'\0')
{
    if(s.length)
        Clear_Str(s);
    int Chunkcount=4;
    CNode* p;
    for(int i=0;chars[i]!='\0';i++){
        if(Chunkcount==ChunkSize){//if目前结点满了
            p=new CNode;
            if(!p)
                return false;
            Chunkcount=0;
            p->ch[Chunkcount++]=chars[i];
            p->next=s.tail->next;
            s.tail->next=p;
            s.tail=p;
        }
        else{
            s.tail->ch[Chunkcount++]=chars[i];
        }
        s.length++;
    }
    if(Chunkcount!=ChunkSize){
        while(Chunkcount!=ChunkSize)
            s.tail->ch[Chunkcount++]='#';
    }
    return true;
}

int Length_Str(LString s)//返回链串的长度
{
    return s.length;
}

int Compare_Str(LString s1,LString s2)//若s1>s2,返回值>0;若s1=s2,返回值=0;若s1<s2,返回值<0
{
    CNode* p1=s1.head->next,* p2=s2.head->next;
    int i=0;
    while(p1&&p2){
        if(p1->ch[i]!=p2->ch[i]){
            if(p1->ch[i]=='#'||p2->ch[i]=='#')
                break;
            return p1->ch[i]-p2->ch[i];
        }
        i++;
        if(i==4){
            p1=p1->next;
            p2=p2->next;
            i=0;//bug1:未重置i值
        }
    }
    return s1.length-s2.length;
}

bool Concat_Str(LString& T,LString s1,LString s2)//T=s1+s2  先将s1、s2存入一个数组
{
    if(T.length)
        Clear_Str(T);
    char* ch=new char[s1.length+s2.length+2];
    int i=0,Chunkcount=0;//i计数读取的长度  chunkcount计数char[]数组
    CNode* p=s1.head->next;
    while(i!=s1.length){
        if(Chunkcount==4){
            p=p->next;
            Chunkcount=0;
        }
        ch[i++]=p->ch[Chunkcount++];
    }
    p=s2.head->next;//p指向s2的第一个数据
    Chunkcount=0;//重置Chunkcount
    while(i!=s1.length+s2.length){
        if(Chunkcount==4){
            p=p->next;
            Chunkcount=0;
        }
        ch[i++]=p->ch[Chunkcount++];
    }
    ch[i]='\0';//(重要  为啥出现一定的乱码  原因就在此)
               //bug:在使用char数组后,将末尾的数据置为'0',不然可能会出现乱码
    Assign_Str(T,ch);
    return true;
}

bool Sub_Str(LString& T,LString s,int pos,int len)//用T存储主串s从pos位置开始的len个数据的子串
{//1<=pos<=s.length  0<=len<=s.length-pos+1
    if(pos<1||pos>s.length||len<0||len>s.length-pos+1)
        return false;
    if(T.length)
        Clear_Str(T);
    char* ch=new char[len];
    int x,y;
    x=(pos-1)/4;y=(pos-1)%4;
    CNode* p=s.head->next;
    while(x){
        p=p->next;
        x--;
    }
    int Chunkcount=y;
    for(int i=0;i!=len;i++){
        ch[i]=p->ch[Chunkcount++];
        if(Chunkcount==4){
            p=p->next;
            Chunkcount=0;
        }
    }
    Assign_Str(T,ch);
    return true;
}

int main()
{
    LString s1;
    Init_str(s1);
    Input_str(s1);
    Output_str(s1);
    cout<<"长度="<<s1.length<<endl;
    Assign_Str(s1,"dong1");
    Output_str(s1);
    cout<<"长度="<<s1.length<<endl;
    LString s2;
    Init_str(s2);
    Input_str(s2);
    Output_str(s2);
    cout<<"长度="<<s2.length<<endl;
    cout<<"result="<<Compare_Str(s1,s2)<<endl;
    cout<<"============\n";
    Output_str(s1);
    Output_str(s2);
    LString T;
    Init_str(T);
    Concat_Str(T,s1,s2);
    Output_str(T);
    Output_str(s1);
    Output_str(s2);
    Sub_Str(T,s2,8,4);
    Output_str(T);
    return 0;
}

输入数据 #停止
dong#
该字符输入完成
该字符输入完成
该字符输入完成
该字符输入完成
输出:
dong
-----
长度=4
输出:
dong
1###
-----
长度=5
输入数据 #停止
dong1234567890999#
该字符输入完成
该字符输入完成
该字符输入完成
该字符输入完成
该字符输入完成
该字符输入完成
该字符输入完成
该字符输入完成
该字符输入完成
该字符输入完成
该字符输入完成
该字符输入完成
该字符输入完成
该字符输入完成
该字符输入完成
该字符输入完成
该字符输入完成
输出:
dong
1234
5678
9099
9###
-----
长度=17
result=-12
============
输出:
dong
1###
-----
输出:
dong
1234
5678
9099
9###
-----
输出:
dong
1don
g123
4567
8909
99##
-----
输出:
dong
1###
-----
输出:
dong
1234
5678
9099
9###
-----
输出:
4567
-----

Process returned 0 (0x0)   execution time : 13.349 s
Press any key to continue.

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值