链串算法库构建

news2024/11/25 22:26:51

学习贺利坚老师链串算法库

数据结构之自建算法库——链串_串数据结构-CSDN博客

本人详细解析博客

串的链式存储及其基本操作实现_串链式存储的操作-CSDN博客

版本更新日志

V1.0 : 结合顺序串操作, 使用链串进行优化, 此次链串, 空间将不受限制, 只写了最基本的操作, 相当于 单链表的拓展实践, 本版本仍然存在的问题是, 可能没有对内存进行优化, 后续需要结合具体单片机编译器, 进行优化处理.

v2.0补丁: 在每个malloc后面,加入分配空间函数,防止分配失败,导致内存泄露

并且在合法性判断哪里, 加入释放函数. 

后续优化: 在时候函数库时, 数据结束后,记得释放 占用的空间.

函数库调用注意事项:

本文分成两个版本, V1.0是简洁版本, 可用于测试, 第二个优化了内存, 可能代码有点冗余 , 在开发中, 需要根据自己使用的编译器, 进行测试, 比如在c语言单片机中, 无法使用指针地址, 那就要换一种表达方式传参了.

V1.0

函数功能

//(1)将一个字符串数组赋值给链串
void Assignment_Chain_string(Chain_string *&New_String, char Assign_array[]);
//(2) 复制一个链串,到另一个链串
void Copy_Chain_String(Chain_string *&accept_string, Chain_string *copy_string);
//(3)判断两个串是否相等
bool Equal_Chain_String(Chain_string *judge_string1, Chain_string *judge_string2);
//(4)求链串串长
int Length_Chain_String(Chain_string *measure_string);
//(5)链串连接
Chain_string *Connect_Chain_String(Chain_string *link1, Chain_string *link2);
//(6)求链串的子串(从begin_loation开始的number个字符)
Chain_string *Get_Chain_Substring(Chain_string *Mother_string, int begin_loation, int number);
//(7)链串中插入串(从从begin_loation开始插入字符串,然后组合成新的串)
Chain_string *Insert_Chain_String(Chain_string *old_string, int begin_loation,Chain_string *insert_string);
//(8)删除链串(从begin 开始的number个字符)
Chain_string *Delete_Chain_String(Chain_string *old_string, int begin_loation,int number);
//(9)链串替换(从begin 开始的number个字符)
Chain_string *Replace_Chain_String(Chain_string *old_string, int begin_loation,int number,Chain_string *replace_string);
//(10)输出展示串
void Display_Chain_String(Chain_string *show_String);

链串头函数

Chain_string.h
#ifndef _CHAIN_STRING_H_INCLUDED
#define _CHAIN_STRING_H_INCLUDED

typedef struct Chain_string
{
    char data;
    struct Chain_string *next;

}Chain_string;

//(1)将一个字符串数组赋值给链串
void Assignment_Chain_string(Chain_string *&New_String, char Assign_array[]);
//(2) 复制一个链串,到另一个链串
void Copy_Chain_String(Chain_string *&accept_string, Chain_string *copy_string);
//(3)判断两个串是否相等
bool Equal_Chain_String(Chain_string *judge_string1, Chain_string *judge_string2);
//(4)求链串串长
int Length_Chain_String(Chain_string *measure_string);
//(5)链串连接
Chain_string *Connect_Chain_String(Chain_string *link1, Chain_string *link2);
//(6)求链串的子串(从begin_loation开始的number个字符)
Chain_string *Get_Chain_Substring(Chain_string *Mother_string, int begin_loation, int number);
//(7)链串中插入串(从从begin_loation开始插入字符串,然后组合成新的串)
Chain_string *Insert_Chain_String(Chain_string *old_string, int begin_loation,Chain_string *insert_string);
//(8)删除链串(从begin 开始的number个字符)
Chain_string *Delete_Chain_String(Chain_string *old_string, int begin_loation,int number);
//(9)链串替换(从begin 开始的number个字符)
Chain_string *Replace_Chain_String(Chain_string *old_string, int begin_loation,int number,Chain_string *replace_string);
//(10)输出展示串
void Display_Chain_String(Chain_string *show_String);

#endif

链串库函数

V1.0简洁版本

Chain_string.cpp
/*****************************************
功  能: 链串算法库
编程人: 无数碎片寻你
时  间: 2024.7.4
版  本: V1.0
******************************************/
#include <stdio.h>
#include <malloc.h>
#include "Chain_string.h"
/**************************************************
(1)函数名: Assignment_Chain_string
功  能: 将一个字符串数组赋值给链串,从而创建新串
参  数: (1)Chain_string *&New_String:要创建的新串
        (2)char Assign_array[]: 创建新串用到的数组数据
注  意:   创建新串传回是指针地址
返回值:  无
**************************************************/
void Assignment_Chain_string(Chain_string *&New_String, char Assign_array[])
{
    int counter;
    //尾结点,取出数组数据得到的新节点
    Chain_string *rear_Node,*new_Node;
    //为新链串分配空间
    New_String = (Chain_string *)malloc(sizeof(Chain_string));
    //初始化,尾指针指向头结点
    rear_Node = New_String;
    rear_Node->next = NULL;
    for(counter = 0; Assign_array[counter] != '\0'; counter++)
    {
        new_Node = (Chain_string *)malloc(sizeof(Chain_string));
        new_Node->data = Assign_array[counter];
        new_Node->next = NULL;
        rear_Node->next = new_Node;
        rear_Node = new_Node;
    }
    rear_Node->next = NULL;
}

/**************************************************
(2)函数名: Copy_Chain_String
功  能: 复制一个链串,到另一个链串
参  数: (1)Chain_string *&accept_string:接受复制的链串
        (2)Chain_string *copy_string: 被复制的链串
思  路:  逐个遍历,复制即可
返回值: 返回链串
**************************************************/
void Copy_Chain_String(Chain_string *&accept_string, Chain_string *copy_string)
{
    Chain_string *visit_Node = copy_string->next;   //遍历被复制节点
    Chain_string *copy_Node;    //每次复制的节点
    Chain_string *rear_Node;    //尾插法定义的尾结点
    //为接受复制链串分配空间
    accept_string = (Chain_string *)malloc(sizeof(Chain_string));
    //初始时,尾指针指向头结点
    rear_Node = accept_string;
    rear_Node->next = NULL;
    while(visit_Node != NULL)
    {
        //为每次复制的节点,创建空间
        copy_Node = (Chain_string *)malloc(sizeof(Chain_string));
        copy_Node->data = visit_Node->data;
        copy_Node->next = NULL;
        //经典尾插
        rear_Node->next = copy_Node;
        rear_Node = copy_Node;
        //复制节点后移
        visit_Node = visit_Node->next;
    }
    rear_Node->next = NULL;
}

/**************************************************
(3)函数名: Equal_Chain_String
功  能: 判断两个串是否相等
参  数: (1)Chain_string *judge_string1:要进行判断的串1
        (2)Chain_string *judge_string2:要进行判断的串2
返回值: bool 两个串是否相等?相等,true:不相等,false
**************************************************/
bool Equal_Chain_String(Chain_string *judge_string1, Chain_string *judge_string2)
{
    Chain_string *visit_Node1 = judge_string1->next;
    Chain_string *visit_Node2 = judge_string2->next;
    while(visit_Node1 != NULL && visit_Node2 != NULL && visit_Node1->data == visit_Node2->data)
    {
        visit_Node1 = visit_Node1->next;
        visit_Node2 = visit_Node2->next;
    }
    if(visit_Node1 == NULL && visit_Node2 == NULL)
    {
        return true;
    }
    else
    {
        return false;
    }

}

/**************************************************
(4)函数名:Length_Chain_String
功  能:求链串串长
参  数:Chain_string *measure_string:要进行测量串长的链串
返回值:int counter:返回链串长度
**************************************************/
int Length_Chain_String(Chain_string *measure_string)
{
    int counter = 0;
    Chain_string *measure_Node = measure_string;
    while(measure_Node->next != NULL)
    {
        counter++;
        measure_Node = measure_Node->next;
    }
    return counter;
}
/**************************************************
(5)函数名:Connect_Chain_String
功  能:链串连接
参  数:(1)Chain_string *link1:要链接的第一个串
        (2)Chain_string *link2:要链接的第二个串
思 路: 定义两个变量,然后进行遍历两个串
返回值: Chain_string *New_String: 返回链接的串
**************************************************/
Chain_string *Connect_Chain_String(Chain_string *link1, Chain_string *link2)
{
    Chain_string *New_String;
    Chain_string *visit_Node;
    Chain_string *new_Node;
    Chain_string *rear_Node;
    //为组合串分配空间
    New_String = (Chain_string *)malloc(sizeof(Chain_string));
    //初始化时,尾指针指向串头
    rear_Node = New_String;
    rear_Node->next = NULL;
    //第一个串
    visit_Node = link1->next;
    while(visit_Node != NULL)
    {
        //经典尾插法
        new_Node = (Chain_string *)malloc(sizeof(Chain_string));
        new_Node->data = visit_Node->data;
        rear_Node->next = new_Node;
        rear_Node = new_Node;
        visit_Node = visit_Node->next;
    }
    //第二个串
    visit_Node = link2->next;
    while(visit_Node != NULL)
    {
        //经典尾插法
        new_Node = (Chain_string *)malloc(sizeof(Chain_string));
        new_Node->data = visit_Node->data;
        rear_Node->next = new_Node;
        rear_Node = new_Node;
        visit_Node = visit_Node->next;
    }
    rear_Node->next = NULL;
    return New_String;
}
/**************************************************
(6)函数名: Get_Chain_Substring
功  能: 求链串的子串(从begin_loation开始的number个字符)
参  数: (1)Chain_string *Mother_string:摘取子串的母串
        (2)int begin_loation:开始摘取的位置
        (3)int number:摘取子串的数量
返回值: Chain_string *new_Substring: 分隔得到的新子串
**************************************************/
Chain_string *Get_Chain_Substring(Chain_string *Mother_string, int begin_loation, int number)
{
    int counter;
    Chain_string *new_Substring;//新子串
    Chain_string *new_Node; //构建子串的节点
    Chain_string *visit_Node;   //访问旧串的节点
    Chain_string *rear_Node;    //新子串的尾指针

    new_Substring = (Chain_string *)malloc(sizeof(Chain_string));
    new_Substring->next = NULL;
    rear_Node = new_Substring;  //子串初始化

    if(begin_loation <= 0 || begin_loation >= Length_Chain_String(Mother_string)||
       number < 0 || begin_loation+number-1 > Length_Chain_String(Mother_string)  )
    {
        //错误:子串位置超标
        printf("\nError<6>: The substring position exceeds the standard.\n");
        return new_Substring;
    }
    //嗅探子串位置
    visit_Node = Mother_string->next;//从头结点后继开始,就是从1开始,同步推进
    for(counter = 1; counter <= begin_loation-1; counter++)
    {
        visit_Node = visit_Node->next;
    }
    //开始复制子串
    for(counter = 0; counter < number; counter++)
    {
        //经典尾插
        new_Node = (Chain_string *)malloc(sizeof(Chain_string));
        new_Node->data = visit_Node->data;
        new_Node->next = NULL;
        rear_Node->next = new_Node;
        rear_Node = new_Node;
        visit_Node = visit_Node->next;//是否超过,合法性判断
    }
    rear_Node->next = NULL;
    return new_Substring;
}
/**************************************************
(7)函数名: Insert_Chain_String
功  能: 链串中插入串(从从begin_loation开始插入字符串,然后组合成新的串)
参  数: (1)Chain_string *old_string:原始要进行插入操作的链串
        (2)int begin_loation:开始插入的位置
        (3)Chain_string *insert_string:  要插入的链串
注  意:  尾插法的应用
返回值: Chain_string *new_String;
**************************************************/
Chain_string *Insert_Chain_String(Chain_string *old_string, int begin_loation,Chain_string *insert_string)
{
    int counter;
    //形成的新串
    Chain_string *new_String;
    //建立新串,新节点与尾插法
    Chain_string *new_Node,*rear_Node;
    //访问两个串的指针
    Chain_string *visit_Node1,*visit_Node2;
    //新串初始化
    new_String = (Chain_string *)malloc(sizeof(Chain_string));
    new_String->next = NULL;
    rear_Node = new_String;
    //插入位置合法性检测
    if(begin_loation <= 0 || (begin_loation>Length_Chain_String(old_string)+1))
    {
        //错误:链串插入位置错误
        printf("\nError<7>: wrong insertion position of chain string.\n");
    }
    //旧串1插入位置前的串(i-1个元素)
    visit_Node1 = old_string->next;
    for(counter = 0; counter < begin_loation-1; counter++)
    {
        new_Node = (Chain_string *)malloc(sizeof(Chain_string));
        new_Node->data = visit_Node1->data;
        rear_Node->next = new_Node;
        rear_Node = new_Node;
        visit_Node1 = visit_Node1->next;     //最后出来是指向第i个元素
    }
    //加入串2
    visit_Node2 = insert_string->next;
    while(visit_Node2 != NULL)
    {
        new_Node = (Chain_string *)malloc(sizeof(Chain_string));
        new_Node->data = visit_Node2->data;
        rear_Node->next = new_Node;
        rear_Node = new_Node;
        visit_Node2 = visit_Node2->next;
    }
    //加入串1插入位置的后续串(第begin_loation个元素到最后)
    while(visit_Node1 != NULL)
    {
        new_Node = (Chain_string *)malloc(sizeof(Chain_string));
        new_Node->data = visit_Node1->data;
        rear_Node->next = new_Node;
        rear_Node = new_Node;
        visit_Node1 = visit_Node1->next;
    }
    rear_Node->next = NULL;
    return new_String;
}
/**************************************************
(8)函数名: Delete_Chain_String
功  能: 删除链串(从begin 开始的number个字符)
参  数: (1)Chain_string *old_string:在本串基础上截取
        (2)int begin_loation:开始删除的位置
        (3)int number:删除的数量
思  路:  有选择的复制剪切
返回值: Chain_string *new_String:处理完的新串,返回
**************************************************/
Chain_string *Delete_Chain_String(Chain_string *old_string, int begin_loation,int number)
{
    int counter;
    Chain_string *new_String;
    Chain_string *new_Node;
    Chain_string *visit_Node;
    Chain_string *rear_Node;
    new_String = (Chain_string *)malloc(sizeof(Chain_string));
    new_String->next = NULL;
    rear_Node = new_String;

    if( begin_loation <= 0 ||
        begin_loation > Length_Chain_String(old_string) ||
        number < 0 ||
        (begin_loation+number-1 > Length_Chain_String(old_string))
       )
   {
      //错误: 删除位置错误
      printf("\nError<8>: Error in deleting location.\n");
   }
   //把删除位置之前的节点复制
   visit_Node = old_string->next;
   for(counter = 0; counter < begin_loation-1; counter++)
   {
       new_Node = (Chain_string *)malloc(sizeof(Chain_string));
       new_Node->data = visit_Node->data;
       rear_Node->next = new_Node;
       rear_Node = new_Node;
       visit_Node = visit_Node->next;
   }
   //跳过要删除的节点
    for(counter = 0; counter<number; counter++)
    {
        visit_Node = visit_Node->next;
    }
    //把后继节点复制加入new_String
    while(visit_Node != NULL)
    {
        new_Node = (Chain_string *)malloc(sizeof(Chain_string));
        new_Node->data = visit_Node->data;
        rear_Node->next = new_Node;
        rear_Node = new_Node;
        visit_Node = visit_Node->next;
    }
    rear_Node->next = NULL;
    return new_String;
}

/**************************************************
(9)函数名: Replace_Chain_String
功  能: 链串替换(从begin 开始的number个字符)
参  数: (1)Chain_string *old_string:在原始串上进行操作
        (2)int begin_loation:开始替换的位置(头结点不算,头结点之后算第一个节点)
        (3)int number:替换的数量
        (4)Chain_string *replace_string:;要替换成的链串
返回值:  Chain_string *new_String:替换完,形成的链串
**************************************************/
Chain_string *Replace_Chain_String(Chain_string *old_string, int begin_loation,int number,Chain_string *replace_string)
{
    int counter;
    //形成的新串
    Chain_string *new_String;
    //建立新串,新节点与尾插法
    Chain_string *new_Node,*rear_Node;
    //访问两个串的指针
    Chain_string *visit_Node1,*visit_Node2;
    //新串初始化
    new_String = (Chain_string *)malloc(sizeof(Chain_string));
    new_String->next = NULL;
    rear_Node = new_String;
    //替换位置合法性检测
    if(begin_loation <= 0 || begin_loation>Length_Chain_String(old_string))
    {
        //错误:链串替换位置错误
        printf("\nError<9>: the chain string replacement position is wrong.\n");
    }
    //旧串替换位置前的串
    visit_Node1 = old_string->next;
    for(counter = 0; counter < begin_loation-1; counter++)
    {
        new_Node = (Chain_string *)malloc(sizeof(Chain_string));
        new_Node->data = visit_Node1->data;
        new_Node->next = NULL;
        rear_Node->next = new_Node;
        rear_Node = new_Node;
        visit_Node1 = visit_Node1->next;     //最后出来是指向第i个元素
    }
    //visit_Node1跳过number个节点
    for(counter = 0; counter < number; counter++)
    {
        visit_Node1 = visit_Node1->next;
    }
    //把替换的串,加入
    visit_Node2 = replace_string->next;
    while(visit_Node2 != NULL)
    {
        new_Node = (Chain_string *)malloc(sizeof(Chain_string));
        new_Node->data = visit_Node2->data;
        new_Node->next = NULL;
        rear_Node->next = new_Node;
        rear_Node = new_Node;
        visit_Node2 = visit_Node2->next;
    }
    //旧串第二段
    while(visit_Node1 != NULL)
    {
        new_Node = (Chain_string *)malloc(sizeof(Chain_string));
        new_Node->data = visit_Node1->data;
        new_Node->next = NULL;
        rear_Node->next = new_Node;
        rear_Node = new_Node;
        visit_Node1 = visit_Node1->next;
    }
    rear_Node->next = NULL;
    return new_String;
}

/**************************************************
(10)函数名: Display_Chain_String
功  能: 输出展示串
参  数: Chain_string *show_String:要进行展示的串
返回值: 无
**************************************************/
void Display_Chain_String(Chain_string *show_String)
{
    Chain_string *show_Node;
    show_Node = show_String->next;
    while(show_Node != NULL)
    {
        printf("%c",show_Node->data);
        show_Node = show_Node->next;
    }
    printf("\n");

}

V2.0补丁版本

main.cpp
/*****************************************
功  能: 链串算法库
编程人: 无数碎片寻你
时  间: 2024.7.4
版  本: V1.0
******************************************/
#include <stdio.h>
#include <malloc.h>
#include "Chain_string.h"
/**************************************************
(1)函数名: Assignment_Chain_string
功  能: 将一个字符串数组赋值给链串,从而创建新串
参  数: (1)Chain_string *&New_String:要创建的新串
        (2)char Assign_array[]: 创建新串用到的数组数据
注  意:   创建新串传回是指针地址
返回值:  无
**************************************************/
void Assignment_Chain_string(Chain_string *&New_String, char Assign_array[])
{
    int counter;
    //尾结点,取出数组数据得到的新节点
    Chain_string *rear_Node,*new_Node;
    //为新链串分配空间
    New_String = (Chain_string *)malloc(sizeof(Chain_string));
    //初始化,尾指针指向头结点
    rear_Node = New_String;
    rear_Node->next = NULL;
    for(counter = 0; Assign_array[counter] != '\0'; counter++)
    {
        new_Node = (Chain_string *)malloc(sizeof(Chain_string));
        if(!new_Node)   //检查内存分配是否成功
        {

            while(New_String->next)//释放已经分配的节点
            {
                Chain_string *temp = New_String->next;
                New_String->next = temp->next;
                free(temp);
            }
            free(New_String);//释放头结点
            return;
        }

        new_Node->data = Assign_array[counter];
        new_Node->next = NULL;
        rear_Node->next = new_Node;
        rear_Node = new_Node;
    }
    rear_Node->next = NULL;
}

/**************************************************
(2)函数名: Copy_Chain_String
功  能: 复制一个链串,到另一个链串
参  数: (1)Chain_string *&accept_string:接受复制的链串
        (2)Chain_string *copy_string: 被复制的链串
思  路:  逐个遍历,复制即可
返回值: 返回链串
**************************************************/
void Copy_Chain_String(Chain_string *&accept_string, Chain_string *copy_string)
{
    Chain_string *visit_Node = copy_string->next;   //遍历被复制节点
    Chain_string *copy_Node;    //每次复制的节点
    Chain_string *rear_Node;    //尾插法定义的尾结点
    //为接受复制链串分配空间
    accept_string = (Chain_string *)malloc(sizeof(Chain_string));
    //初始时,尾指针指向头结点
    rear_Node = accept_string;
    rear_Node->next = NULL;
    while(visit_Node != NULL)
    {
        //为每次复制的节点,创建空间
        copy_Node = (Chain_string *)malloc(sizeof(Chain_string));
        if(!copy_Node)   //检查内存分配是否成功
        {

            while(accept_string->next)//释放已经分配的节点
            {
                Chain_string *temp = accept_string->next;
                accept_string->next = temp->next;
                free(temp);
            }
            free(accept_string);//释放头结点
            return;
        }
        copy_Node->data = visit_Node->data;
        copy_Node->next = NULL;
        //经典尾插
        rear_Node->next = copy_Node;
        rear_Node = copy_Node;
        //复制节点后移
        visit_Node = visit_Node->next;
    }
    rear_Node->next = NULL;
}

/**************************************************
(3)函数名: Equal_Chain_String
功  能: 判断两个串是否相等
参  数: (1)Chain_string *judge_string1:要进行判断的串1
        (2)Chain_string *judge_string2:要进行判断的串2
返回值: bool 两个串是否相等?相等,true:不相等,false
**************************************************/
bool Equal_Chain_String(Chain_string *judge_string1, Chain_string *judge_string2)
{
    Chain_string *visit_Node1 = judge_string1->next;
    Chain_string *visit_Node2 = judge_string2->next;
    while(visit_Node1 != NULL && visit_Node2 != NULL && visit_Node1->data == visit_Node2->data)
    {
        visit_Node1 = visit_Node1->next;
        visit_Node2 = visit_Node2->next;
    }
    if(visit_Node1 == NULL && visit_Node2 == NULL)
    {
        return true;
    }
    else
    {
        return false;
    }

}

/**************************************************
(4)函数名:Length_Chain_String
功  能:求链串串长
参  数:Chain_string *measure_string:要进行测量串长的链串
返回值:int counter:返回链串长度
**************************************************/
int Length_Chain_String(Chain_string *measure_string)
{
    int counter = 0;
    Chain_string *measure_Node = measure_string;
    while(measure_Node->next != NULL)
    {
        counter++;
        measure_Node = measure_Node->next;
    }
    return counter;
}
/**************************************************
(5)函数名:Connect_Chain_String
功  能:链串连接
参  数:(1)Chain_string *link1:要链接的第一个串
        (2)Chain_string *link2:要链接的第二个串
思 路: 定义两个变量,然后进行遍历两个串
返回值: Chain_string *New_String: 返回链接的串
**************************************************/
Chain_string *Connect_Chain_String(Chain_string *link1, Chain_string *link2)
{
    Chain_string *New_String;
    Chain_string *visit_Node;
    Chain_string *new_Node;
    Chain_string *rear_Node;
    //为组合串分配空间
    New_String = (Chain_string *)malloc(sizeof(Chain_string));
    //初始化时,尾指针指向串头
    rear_Node = New_String;
    rear_Node->next = NULL;
    //第一个串
    visit_Node = link1->next;
    while(visit_Node != NULL)
    {
        //经典尾插法
        new_Node = (Chain_string *)malloc(sizeof(Chain_string));
        if(!new_Node)   //检查内存分配是否成功
        {

            while(New_String->next)//释放已经分配的节点
            {
                Chain_string *temp = New_String->next;
                New_String->next = temp->next;
                free(temp);
            }
            free(New_String);//释放头结点
            return New_String;
        }

        new_Node->data = visit_Node->data;
        rear_Node->next = new_Node;
        rear_Node = new_Node;
        visit_Node = visit_Node->next;
    }
    //第二个串
    visit_Node = link2->next;
    while(visit_Node != NULL)
    {
        //经典尾插法
        new_Node = (Chain_string *)malloc(sizeof(Chain_string));
        if(!new_Node)   //检查内存分配是否成功
        {

            while(New_String->next)//释放已经分配的节点
            {
                Chain_string *temp = New_String->next;
                New_String->next = temp->next;
                free(temp);
            }
            free(New_String);//释放头结点
            return New_String;
        }

        new_Node->data = visit_Node->data;
        rear_Node->next = new_Node;
        rear_Node = new_Node;
        visit_Node = visit_Node->next;
    }
    rear_Node->next = NULL;
    return New_String;
}
/**************************************************
(6)函数名: Get_Chain_Substring
功  能: 求链串的子串(从begin_loation开始的number个字符)
参  数: (1)Chain_string *Mother_string:摘取子串的母串
        (2)int begin_loation:开始摘取的位置
        (3)int number:摘取子串的数量
返回值: Chain_string *new_Substring: 分隔得到的新子串
**************************************************/
Chain_string *Get_Chain_Substring(Chain_string *Mother_string, int begin_loation, int number)
{
    int counter;
    Chain_string *new_Substring;//新子串
    Chain_string *new_Node; //构建子串的节点
    Chain_string *visit_Node;   //访问旧串的节点
    Chain_string *rear_Node;    //新子串的尾指针

    new_Substring = (Chain_string *)malloc(sizeof(Chain_string));
    new_Substring->next = NULL;
    rear_Node = new_Substring;  //子串初始化

    if(begin_loation <= 0 || begin_loation >= Length_Chain_String(Mother_string)||
       number < 0 || begin_loation+number-1 > Length_Chain_String(Mother_string)  )
    {
        //错误:子串位置超标
        printf("\nError<6>: The substring position exceeds the standard.\n");
        free(new_Substring); // 释放头节点内存
        return new_Substring;
    }
    //嗅探子串位置
    visit_Node = Mother_string->next;//从头结点后继开始,就是从1开始,同步推进
    for(counter = 1; counter <= begin_loation-1; counter++)
    {
        visit_Node = visit_Node->next;
    }
    //开始复制子串
    for(counter = 0; counter < number; counter++)
    {
        //经典尾插
        new_Node = (Chain_string *)malloc(sizeof(Chain_string));
        if(!new_Node)   //检查内存分配是否成功
        {

            while(new_Substring->next)//释放已经分配的节点
            {
                Chain_string *temp = new_Substring->next;
                new_Substring->next = temp->next;
                free(temp);
            }
            free(new_Substring);//释放头结点
            return new_Substring;
        }

        new_Node->data = visit_Node->data;
        new_Node->next = NULL;
        rear_Node->next = new_Node;
        rear_Node = new_Node;
        visit_Node = visit_Node->next;//是否超过,合法性判断
    }
    rear_Node->next = NULL;
    return new_Substring;
}
/**************************************************
(7)函数名: Insert_Chain_String
功  能: 链串中插入串(从从begin_loation开始插入字符串,然后组合成新的串)
参  数: (1)Chain_string *old_string:原始要进行插入操作的链串
        (2)int begin_loation:开始插入的位置
        (3)Chain_string *insert_string:  要插入的链串
注  意:  尾插法的应用
返回值: Chain_string *new_String;
**************************************************/
Chain_string *Insert_Chain_String(Chain_string *old_string, int begin_loation,Chain_string *insert_string)
{
    int counter;
    //形成的新串
    Chain_string *new_String;
    //建立新串,新节点与尾插法
    Chain_string *new_Node,*rear_Node;
    //访问两个串的指针
    Chain_string *visit_Node1,*visit_Node2;
    //新串初始化
    new_String = (Chain_string *)malloc(sizeof(Chain_string));
    new_String->next = NULL;
    rear_Node = new_String;
    //插入位置合法性检测
    if(begin_loation <= 0 || (begin_loation>Length_Chain_String(old_string)+1))
    {
        //错误:链串插入位置错误
        printf("\nError<7>: wrong insertion position of chain string.\n");
        free(new_String); // 释放头节点内存
        return new_String;
    }
    //旧串1插入位置前的串(i-1个元素)
    visit_Node1 = old_string->next;
    for(counter = 0; counter < begin_loation-1; counter++)
    {
        new_Node = (Chain_string *)malloc(sizeof(Chain_string));\
        if(!new_Node)   //检查内存分配是否成功
        {

            while(new_String->next)//释放已经分配的节点
            {
                Chain_string *temp = new_String->next;
                new_String->next = temp->next;
                free(temp);
            }
            free(new_String);//释放头结点
            return new_String;
        }


        new_Node->data = visit_Node1->data;
        rear_Node->next = new_Node;
        rear_Node = new_Node;
        visit_Node1 = visit_Node1->next;     //最后出来是指向第i个元素
    }
    //加入串2
    visit_Node2 = insert_string->next;
    while(visit_Node2 != NULL)
    {
        new_Node = (Chain_string *)malloc(sizeof(Chain_string));
        if(!new_Node)   //检查内存分配是否成功
        {

            while(new_String->next)//释放已经分配的节点
            {
                Chain_string *temp = new_String->next;
                new_String->next = temp->next;
                free(temp);
            }
            free(new_String);//释放头结点
            return new_String;
        }

        new_Node->data = visit_Node2->data;
        rear_Node->next = new_Node;
        rear_Node = new_Node;
        visit_Node2 = visit_Node2->next;
    }
    //加入串1插入位置的后续串(第begin_loation个元素到最后)
    while(visit_Node1 != NULL)
    {
        new_Node = (Chain_string *)malloc(sizeof(Chain_string));
        if(!new_Node)   //检查内存分配是否成功
        {

            while(new_String->next)//释放已经分配的节点
            {
                Chain_string *temp = new_String->next;
                new_String->next = temp->next;
                free(temp);
            }
            free(new_String);//释放头结点
            return new_String;
        }
        new_Node->data = visit_Node1->data;
        rear_Node->next = new_Node;
        rear_Node = new_Node;
        visit_Node1 = visit_Node1->next;
    }
    rear_Node->next = NULL;
    return new_String;
}
/**************************************************
(8)函数名: Delete_Chain_String
功  能: 删除链串(从begin 开始的number个字符)
参  数: (1)Chain_string *old_string:在本串基础上截取
        (2)int begin_loation:开始删除的位置
        (3)int number:删除的数量
思  路:  有选择的复制剪切
返回值: Chain_string *new_String:处理完的新串,返回
**************************************************/
Chain_string *Delete_Chain_String(Chain_string *old_string, int begin_loation,int number)
{
    int counter;
    Chain_string *new_String;
    Chain_string *new_Node;
    Chain_string *visit_Node;
    Chain_string *rear_Node;
    new_String = (Chain_string *)malloc(sizeof(Chain_string));
    new_String->next = NULL;
    rear_Node = new_String;

    if( begin_loation <= 0 ||
        begin_loation > Length_Chain_String(old_string) ||
        number < 0 ||
        (begin_loation+number-1 > Length_Chain_String(old_string))
       )
   {
      //错误: 删除位置错误
      printf("\nError<8>: Error in deleting location.\n");
      free(new_String); // 释放头节点内存
      return new_String;
   }
   //把删除位置之前的节点复制
   visit_Node = old_string->next;
   for(counter = 0; counter < begin_loation-1; counter++)
   {
       new_Node = (Chain_string *)malloc(sizeof(Chain_string));
        if(!new_Node)   //检查内存分配是否成功
        {

            while(new_String->next)//释放已经分配的节点
            {
                Chain_string *temp = new_String->next;
                new_String->next = temp->next;
                free(temp);
            }
            free(new_String);//释放头结点
            return new_String;
        }

       new_Node->data = visit_Node->data;
       rear_Node->next = new_Node;
       rear_Node = new_Node;
       visit_Node = visit_Node->next;
   }
   //跳过要删除的节点
    for(counter = 0; counter<number; counter++)
    {
        visit_Node = visit_Node->next;
    }
    //把后继节点复制加入new_String
    while(visit_Node != NULL)
    {
        new_Node = (Chain_string *)malloc(sizeof(Chain_string));
        if(!new_Node)   //检查内存分配是否成功
        {

            while(new_String->next)//释放已经分配的节点
            {
                Chain_string *temp = new_String->next;
                new_String->next = temp->next;
                free(temp);
            }
            free(new_String);//释放头结点
            return new_String;
        }

        new_Node->data = visit_Node->data;
        rear_Node->next = new_Node;
        rear_Node = new_Node;
        visit_Node = visit_Node->next;
    }
    rear_Node->next = NULL;
    return new_String;
}

/**************************************************
(9)函数名: Replace_Chain_String
功  能: 链串替换(从begin 开始的number个字符)
参  数: (1)Chain_string *old_string:在原始串上进行操作
        (2)int begin_loation:开始替换的位置(头结点不算,头结点之后算第一个节点)
        (3)int number:替换的数量
        (4)Chain_string *replace_string:;要替换成的链串
返回值:  Chain_string *new_String:替换完,形成的链串
**************************************************/
Chain_string *Replace_Chain_String(Chain_string *old_string, int begin_loation,int number,Chain_string *replace_string)
{
    int counter;
    //形成的新串
    Chain_string *new_String;
    //建立新串,新节点与尾插法
    Chain_string *new_Node,*rear_Node;
    //访问两个串的指针
    Chain_string *visit_Node1,*visit_Node2;
    //新串初始化
    new_String = (Chain_string *)malloc(sizeof(Chain_string));
    new_String->next = NULL;
    rear_Node = new_String;
    //替换位置合法性检测
    if(begin_loation <= 0 || begin_loation>Length_Chain_String(old_string)||
        number < 0 || (begin_loation+number-1 > Length_Chain_String(old_string))
       )
    {
        //错误:链串替换位置错误
        printf("\nError<9>: the chain string replacement position is wrong.\n");
        free(new_String); // 释放头节点内存
        return new_String;
    }
    //旧串替换位置前的串
    visit_Node1 = old_string->next;
    for(counter = 0; counter < begin_loation-1; counter++)
    {
        new_Node = (Chain_string *)malloc(sizeof(Chain_string));
        if(!new_Node)   //检查内存分配是否成功
        {

            while(new_String->next)//释放已经分配的节点
            {
                Chain_string *temp = new_String->next;
                new_String->next = temp->next;
                free(temp);
            }
            free(new_String);//释放头结点
            return new_String;
        }

        new_Node->data = visit_Node1->data;
        new_Node->next = NULL;
        rear_Node->next = new_Node;
        rear_Node = new_Node;
        visit_Node1 = visit_Node1->next;     //最后出来是指向第i个元素
    }
    //visit_Node1跳过number个节点
    for(counter = 0; counter < number; counter++)
    {
        visit_Node1 = visit_Node1->next;
    }
    //把替换的串,加入
    visit_Node2 = replace_string->next;
    while(visit_Node2 != NULL)
    {
        new_Node = (Chain_string *)malloc(sizeof(Chain_string));
        if(!new_Node)   //检查内存分配是否成功
        {

            while(new_String->next)//释放已经分配的节点
            {
                Chain_string *temp = new_String->next;
                new_String->next = temp->next;
                free(temp);
            }
            free(new_String);//释放头结点
            return new_String;
        }
        new_Node->data = visit_Node2->data;
        new_Node->next = NULL;
        rear_Node->next = new_Node;
        rear_Node = new_Node;
        visit_Node2 = visit_Node2->next;
    }
    //旧串第二段
    while(visit_Node1 != NULL)
    {
        new_Node = (Chain_string *)malloc(sizeof(Chain_string));
        if(!new_Node)   //检查内存分配是否成功
        {

            while(new_String->next)//释放已经分配的节点
            {
                Chain_string *temp = new_String->next;
                new_String->next = temp->next;
                free(temp);
            }
            free(new_String);//释放头结点
            return new_String;
        }
        new_Node->data = visit_Node1->data;
        new_Node->next = NULL;
        rear_Node->next = new_Node;
        rear_Node = new_Node;
        visit_Node1 = visit_Node1->next;
    }
    rear_Node->next = NULL;
    return new_String;
}

/**************************************************
(10)函数名: Display_Chain_String
功  能: 输出展示串
参  数: Chain_string *show_String:要进行展示的串
返回值: 无
**************************************************/
void Display_Chain_String(Chain_string *show_String)
{
    Chain_string *show_Node;
    show_Node = show_String->next;
    if(show_Node == NULL)
    {
        //警告:什么都没有,无法输出字符串
        printf("\nWarning<10>: Nothing, unable to output string.\n");
    }
    else
    {
        while(show_Node != NULL)
        {
            printf("%c",show_Node->data);
            show_Node = show_Node->next;
        }
        printf("\n");
    }

}

main函数测试1:

范围正常情况下测试:

main.cpp
#include <stdio.h>
#include "Chain_string.h"

int main()
{
    Chain_string *test_String,*test_String1,*test_String2,*test_String3,*test_String4;
    char test_char1[ ] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','\0'};
    char test_char2[] = {'1','2','3','\0'};
    printf("\n链串的基本运算如下:\n");
    printf("\n(1)建立串test_String和test_String1\n");
    Assignment_Chain_string(test_String, test_char1);
    printf("\n(2)输出串test_String:\n");
    Display_Chain_String(test_String);
    Assignment_Chain_string(test_String1, test_char2);
    printf("\n(2)输出串test_String1:\n");
    Display_Chain_String(test_String1);
    printf("\n(3)串test_String的长度:%d\n",Length_Chain_String(test_String));
    printf("\n(4)在串test_String的第9个字符位置插入串test_String1而产生test_String2\n");
    test_String2 = Insert_Chain_String(test_String,9,test_String1);
    printf("\n(5)输出串test_String2:\n");
    Display_Chain_String(test_String2);
    printf("\n(6)删除串test_String第二个字符开始的5个字符而产生串2\n");
    test_String2 = Delete_Chain_String(test_String,2,5);
    printf("\n(7)输出串test_String2:\n");
    Display_Chain_String(test_String2);
    printf("\n(8)将串2第2个字符开始的5个字符替换成串1而产生串2\n");
    test_String2 = Replace_Chain_String(test_String2,2,5,test_String1);

    printf("\n(9)输出串2\n");
    Display_Chain_String(test_String2);
    printf("\n(10)提取串s的第2个字符开始的10个字符而产生串3\n");
    test_String3 = Get_Chain_Substring(test_String,2,10);
    printf("\n(11)输出串3\n");
    Display_Chain_String(test_String3);
    printf("\n(12)将串1和串2链接起来而成产生串4\n");
    test_String4 = Connect_Chain_String(test_String1,test_String2);
    printf("\n(13)输出串4\n");
    Display_Chain_String(test_String4);
    return 0;

}

运行结果展示:

main函数测试2:

范围超出情况下测试:

主函数文件名字

main.cpp
#include <stdio.h>
#include "Chain_string.h"

int main()
{
    Chain_string *test_String,*test_String1,*test_String2,*test_String3,*test_String4;
    char test_char1[ ] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','\0'};
    char test_char2[] = {'1','2','3','\0'};
    printf("\n链串的基本运算如下:\n");
    printf("\n(1)建立串test_String和test_String1\n");
    Assignment_Chain_string(test_String, test_char1);
    printf("\n(2)输出串test_String:\n");
    Display_Chain_String(test_String);
    Assignment_Chain_string(test_String1, test_char2);
    printf("\n(2)输出串test_String1:\n");
    Display_Chain_String(test_String1);
    printf("\n(3)串test_String的长度:%d\n",Length_Chain_String(test_String));
    printf("\n(4)在串test_String的第100个字符位置插入串test_String1而产生test_String2\n");
    test_String2 = Insert_Chain_String(test_String,100,test_String1);
    printf("\n(5)输出串test_String2:\n");
    Display_Chain_String(test_String2);
    printf("\n(6)删除串test_String第20个字符开始的10个字符而产生串3\n");
    test_String3 = Delete_Chain_String(test_String,20,10);
    printf("\n(7)输出串test_String3:\n");
    Display_Chain_String(test_String3);
    printf("\n(8)将串第2个字符开始的99个字符替换成串1而产生串4\n");
    test_String4 = Replace_Chain_String(test_String,2,99,test_String1);

    printf("\n(9)输出串4\n");
    Display_Chain_String(test_String4);

    printf("\n(10)提取串s的第2个字符开始的88个字符而产生串3\n");
    test_String3 = Get_Chain_Substring(test_String,2,88);
    printf("\n(11)输出串3\n");
    Display_Chain_String(test_String3);
    printf("\n(12)将串和串1链接起来而成产生串4\n");
    test_String4 = Connect_Chain_String(test_String,test_String1);
    printf("\n(13)输出串4\n");
    Display_Chain_String(test_String4);
    return 0;

}

运行结果展示:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1897943.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HTML【详解】超链接 a 标签的四大功能(页面跳转、页内滚动【锚点】、页面刷新、文件下载)

超链接 a 标签主要有以下功能&#xff1a; 跳转到其他页面 <a href"https://www.baidu.com/" target"_blank" >百度</a>href&#xff1a;目标页面的 url 地址或同网站的其他页面地址&#xff0c;如 detail.htmltarget&#xff1a;打开目标页面…

kylin arm xcb版本异常问题解决

源码编译qt 未生成xcb库&#xff0c;查看源码xcb readme.txt 提示 版本要求 下载 [ANNOUNCE] libxcb 1.14 [ANNOUNCE] xcb-proto 1.14 解压源码编译, 先编译xcb-proto sudo ./configure --prefix/usr/local/xcb-proto make make install 在编译xcb export PKG_CONFIG_PATH…

JavaScript(5)——数据类型和类型检测

字符串类型String 通过单引号&#xff08; &#xff09;、双引号(" "&#xff09;或反引号&#xff08; &#xff09;都叫字符串&#xff0c;单引号和双引号本质上没有区别&#xff0c;一般使用单引号。 注意&#xff1a; 无论单引号或是双引号必须成对使用单引号和…

【html】许多大型网页都会有一个自己的主题色

许多网站确实会选择一种或几种特定的颜色作为他们的主题色&#xff0c;这通常是为了建立品牌识别度和一致性。 主题色在网站设计中起着至关重要的作用&#xff0c;它们不仅影响网站的视觉效果&#xff0c;还能传达品牌的情感和价值观。选择适当的主题色可以增强用户的品牌记忆…

【Spring Boot】Spring AOP中的环绕通知

目录 一、什么是AOP?二、AOP 的环绕通知2.1 切点以及切点表达式2.2 连接点2.3 通知&#xff08;Advice&#xff09;2.4 切面(Aspect)2.5 不同通知类型的区别2.5.1 正常情况下2.5.2异常情况下 2.6 统一管理切点PointCut 一、什么是AOP? Aspect Oriented Programming&#xff…

ELK日志系统和Filebeat采集器的学习总结

ELK是ElasticSerach、Logstash、Kina Logstash负责采集数据&#xff0c;Logstash有三个插件&#xff0c;input、filter、output&#xff0c;filter插件作用是对采集的数据进行处理&#xff0c;过滤的&#xff0c;因此filter插件可以选&#xff0c;可以不用配置。 ElasticSear…

上网总是卡顿?Edge浏览器的4个超强彩蛋,开启你的极速体验

在数字化浪潮的推动下&#xff0c;浏览器已成为我们探索网络世界的罗盘和船锚。微软的Edge浏览器&#xff0c;以其简洁的界面和强大的功能&#xff0c;赢得了众多用户的青睐。 但你知道吗&#xff1f;Edge不仅仅是一个浏览工具&#xff0c;它还隐藏着许多实用的“彩蛋”&#…

python如何不保留小数

1、int() 向下取整&#xff08;内置函数&#xff09; n 3.75 print(int(n)) >>> 3 n 3.25 print(int(n)) >>> 3 2、round() 四舍五入&#xff08;内置函数&#xff09; n 3.75 print(round(n)) >>> 4 n 3.25 print(round(n)) >>> 3 …

Linux平台x86_64|aarch64架构如何实现轻量级RTSP服务

技术背景 我们在做Linux平台x86_64架构或aarch64架构的推送模块的时候&#xff0c;有公司提出这样的技术需求&#xff0c;希望在Linux平台&#xff0c;实现轻量级RTSP服务&#xff0c;实现对摄像头或屏幕对外RTSP拉流&#xff0c;同步到大屏上去。 技术实现 废话不多说&…

鸿蒙 HarmonyOS Next 路由 不废话 全干货

一、页面的创建 &#xff08;1&#xff09;直接通过创建一个新的Page的方式创建 &#xff08;2&#xff09;先创建一个 ArkTs File文件&#xff0c;然后在resources/base/profile/main_pages.json中加上页面对应的src路径&#xff0c;下面的Index_3.ets文件是通过创建ArkTs Fi…

创建本地仓库

一、新建挂载目录 二、将挂载本地镜像挂载到目录 三、配置yum仓库 一、新建挂载目录 mkdir /BenDiCangKu 二、将挂载本地镜像挂载到目录 1、先连接本地光盘 2、挂载光盘 mount /dev/sr0 /BenDiCangKu 3、查看挂载 由此可见挂载成功 三、配置yum仓库 1、新建yum仓库文件…

LeetCode 196, 73, 105

目录 196. 删除重复的电子邮箱题目链接表要求知识点思路代码 73. 矩阵置零题目链接标签简单版思路代码 优化版思路代码 105. 从前序与中序遍历序列构造二叉树题目链接标签思路代码 196. 删除重复的电子邮箱 题目链接 196. 删除重复的电子邮箱 表 表Person的字段为id和email…

图像处理中的二维傅里叶变换

图像处理中的二维傅里叶变换 问题来源是对彩色图像进行压缩时得出的傅里叶系数的图像如何解释&#xff0c;导入图片&#xff0c;转化为灰度图片&#xff1a; #彩色图片一般是由RGB组成&#xff0c;其实就是3个二维数组叠加而成&#xff0c;当RGB时&#xff0c;彩色图片就会变成…

基于springboot的工作绩效管理系统的设计与实现+文档

&#x1f497;博主介绍&#x1f497;&#xff1a;✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示&#xff1a;文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐…

1117 数字之王

solution 判断现有数字是否全为个位数 全为个位数&#xff0c;找出出现次数最多的数字&#xff0c;并首行输出最多出现次数&#xff0c;第二行输出所有出现该次数的数值不全为个位数 若当前位数值为0&#xff0c;无需处理若当前位数值非0&#xff0c;则每位立方相乘&#xff0…

VBA语言専攻T3学员领取资料通知0706

T3学员领取资料通知0706 各位学员∶本周MF系列VBA技术资料增加641-645讲&#xff0c;T3学员看到通知后请免费领取,领取时间7月5日晚上19:00-7月6日晚上19:00。本次增加内容&#xff1a; MF641:前个窗体组合框选项联动下个组合框 MF642:工作表中数据选项联动下个数据验证 MF…

数据库-MySQL 实战项目——书店图书进销存管理系统数据库设计与实现(附源码)

一、前言 该项目非常适合MySQL入门学习的小伙伴&#xff0c;博主提供了源码、数据和一些查询语句&#xff0c;供大家学习和参考&#xff0c;代码和表设计有什么不恰当还请各位大佬多多指点。 所需环境 MySQL可视化工具&#xff1a;navicat&#xff1b; 数据库&#xff1a;MySq…

FlowUs设计师展示自己作品集的优质平台

作为一位资深设计师&#xff0c;我认为在多个渠道展示我们的作品是至关重要的。这不仅仅是为了展示我们的设计能力&#xff0c;更是为了建立我们作为创意专业人士的声誉和品牌。以下是一些我们应当考虑的理由&#xff1a; 专业展示&#xff1a;在多个平台上展示作品集&#xff…

一文带你了解“商贸物流大脑”

商贸物流大脑源于实体物流&#xff0c;物理世界的实体物流是构建商贸物流大脑的基础。商贸物流大脑应该是物理世界的实际物流系统和相应的虚拟物流系统两个层面血肉相连、相互作用、有机统一的整体。商贸物流的研究内容包括数字产业化和物流数字化两大部分。信息产业化是进入物…

OpenCV 灰度直方图及熵的计算

目录 一、概述 1.1灰度直方图 1.1.1灰度直方图的原理 1.1.2灰度直方图的应用 1.1.3直方图的评判标准 1.2熵 二、代码实现 三、实现效果 3.1直方图显示 3.2 熵的计算 一、概述 OpenCV中的灰度直方图是一个关键的工具&#xff0c;用于分析和理解图像的灰度分布情况。直…