自己手写一个字符串【C风格】

news2024/11/19 21:26:06
//字符串的常见操作
#include <iostream>

#define MAX_SIZE 15
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;//状态类型
typedef char ElemType;//元素类型

typedef ElemType String[MAX_SIZE + 1];//第一个字节记录长度

//***tring是数组,名字就是地址位置,不用指针传递
// 
//创建
Status StrAssign(String T, const char* chars)
{
    int length = strlen(chars);
    if (length > MAX_SIZE)
        return ERROR;
    T[0] = (char)length;//第一个放保存字符的长度
    for (int i = 1; i <= length; i++)
    {
        T[i] = chars[i - 1];
    }
    return OK;
}

//复制 T <-- S
Status StrCopy(String T, String S)
{
    for (int i = 0; i <= S[0]; i++)
    {
        T[i] = S[i];//把第一个长度的字符也复制
    }
    return OK;
}

//判断为空
Status StrEmpty(String T)
{
    return T[0] == 0 ? TRUE : FALSE;
}

//比较大小 T>S:1;T==S:0,T<S:-1
int StrCompare(String T, String S)
{
    for (int i = 1; (i <= T[0]) && (i <= T[0]); i++)
    {
        if (T[i] > S[i])
            return 1;
        else if (T[i] <  S[i])
            return -1;
    }
    //在双方最小的字符段长度内相同,就看字符串的长度谁大
    if (T[0] > S[0])
        return 1;
    else if (T[0] < S[0])
        return -1;
    else if (T[0] == S[0])
        return 0;
}

//返回长度
Status StrLength(String T)
{
    return (int)T[0];
}
 
//清空
Status ClearString(String T)
{
    T[0] = 0;
    return OK;
}

//连接字符串
Status Concat(String T, String S1, String S2)
{
    if (((int)S1[0] + (int)S2[0]) <= MAX_SIZE)
    {
        T[0] = (char)((int)S1[0] + (int)S2[0]);
        for (int i = 1; i <= (int)S1[0]; i++)
            T[i] = S1[i];
        for (int j = 1; j <= (int)S2[0]; j++)
            T[ j + (int)S1[0] ] = S2[j];
        return OK;
    }
    //超过了长度
    for (int i = 1; i <= (int)S1[0]; i++)
        T[i] = S1[i];
    for (int j = 1; j <= MAX_SIZE; j++)//第二个太长截断
        T[j + (int)S1[0]] = S2[j];
    T[0] = MAX_SIZE;
    return ERROR;
}

//取子字符串
Status SubString(String Sub, String T, int pos, int len)
{
    //len不能超过剩余的字符串长度
    if ((len < 1) || (pos > (int)T[0]) || (pos < 1) || len > (int)T[0] - pos + 1)
        return ERROR;
    for (int i = 1; i <= len; i++)
    {
        Sub[i] = T[pos + i - 1];
    }
    Sub[0] = (char)len;
    return OK;
}

//在T里面查找S,从pos的位置开始查找,返回查找到的位置
int Index(String T, String S, int pos)
{
    if ((S[0] == 0) || (T[0] == 0) || (S[0] > T[0]) || (pos < 0) ||(pos > T[0]))
        return -1;
    int i = pos;
    int j = 1;
    while (i<=T[0] && j <= S[0])
    {
        if (T[i] == S[j])
        {
            j++;
            i++;
        }
        else
        {
            i = i - j + 2;//回退到下一位置
            j = 1;
        }
    }
    if (j > (int)S[0])
        return i - (int)S[0];
    return -1;
}

//在T里面查找S,从pos的位置开始查找,返回查找到的位置
int Index2(String T, String S, int pos)
{
    if ((S[0] == 0) || (T[0] == 0) || (S[0] > T[0]) || (pos < 0) || (pos > T[0]))
        return -1;
    int n = StrLength(T);
    int m = StrLength(S);
    String sub;
    int i = 1;
    while (i <= n - m + 1)
    {
        SubString(sub, T, i, m);
        if (StrCompare(sub, S) == 0)
            return i;
        i++;
    }
    return -1;
}

//插入,S 插入到T的pos位置
Status StrInsert(String T, int pos, String S)
{
    if (pos<1 || pos > S[0] + 1)
        return ERROR;

    //只能部分插入情况
    if (((int)S[0] + (int)T[0]) > MAX_SIZE)
    {
        //扩张原本的字符串大小,只能扩张到最大
        for (int i = (int)T[0]; i >= pos; i--)
        {
            T[MAX_SIZE+ i- (int)T[0]] = T[ i ];
        }
        //再从pos的位置插入,插入剩余的空余位置
        for (int i = 1; i <= MAX_SIZE - (int)T[0]; i++)
        {
            T[pos + i - 1] = S[i];
        }
        T[0] = MAX_SIZE;
        return ERROR;
    }

    //完全插入
    //扩张原本的字符串大小,并空出位置
    for (int i = (int)T[0]; i >= pos; i--)
    {
        T[ i +(int)S[0] ]= T[i];
    }
    //再从pos的位置插入
    for (int i = 1; i <= (int)S[0]; i++)
    {
        T[pos + i - 1] = S[i];
    }
    T[0] =(char)((int)T[0] + (int)S[0]);
    return OK;
}
//指定位置删除若干字符
Status StrDelete(String T, int pos, int len)
{
    if ((pos<1) || (pos > T[0] + 1) || (len > T[0] - pos + 1) || (pos < 0))
        return ERROR;
    for (int i = pos + len; i <= T[0]; i++)//从后面往前面覆盖删除的位置数据
    {
        T[i - len] = T[i];
    }
    T[0] = (char)((int)T[0] - len);
    return OK;
}

//在T里面把S替换成V
Status Replace(String T, String S, String V)
{
    if (StrEmpty(S))
        return ERROR;
    int i = 1;
    while ( i > 0)
    {
        i = Index(T, S, i);
        if ( i> 0 )
        {
            StrDelete(T, i, StrLength(S));
            StrInsert(T, i, V);
            i += StrLength(V);
        }
    }
    return OK;
}

//显示
Status ShowString(String T)
{
    if (StrLength(T) == 0)
        return ERROR;
    for (int i = 1; i <= StrLength(T); i++)
    {
        printf("%c", T[i]);
    }
    printf("\n\n");
    return OK;
}

int main()
{
    String str, strcopy, strcat;
    StrAssign(str, "abcd");
    printf("长度:%d, 是否为空:%d(1:是 0:否)\n\n", StrLength(str),StrEmpty(str));
    printf("显示str:\n");
    ShowString(str);

    StrCopy(strcopy, str);
    printf("复制str显示strcopy:\n");
    ShowString(strcopy);

    StrAssign(strcopy, "efghijk");
    printf("重新显示strcopy:\n");
    ShowString(strcopy);

    printf("比较str和strcopy是否相等:%d(0:相等)\n\n", StrCompare(str, strcopy));

    printf("str拼接strcopy:\n");
    Concat(strcat, str, strcopy);
    ShowString(strcat);

    ClearString(str);
    printf("清空重新显示str:\n");
    ShowString(str);
    printf("长度:%d, 是否为空:%d(1:是 0:否)\n\n", StrLength(str), StrEmpty(str));
    
    SubString(str, strcat, 2, 3);
    printf("截取后重新显示str:\n");
    ShowString(str);
    printf("长度:%d, 是否为空:%d(1:是 0:否)\n\n", StrLength(str), StrEmpty(str));
    
    StrDelete(str, 1, 2);
    printf("删除重新显示str:\n");
    ShowString(str);
    printf("长度:%d, 是否为空:%d(1:是 0:否)\n\n", StrLength(str), StrEmpty(str));

    StrInsert(str, 2, strcopy);
    printf("插入重新显示str:\n");
    ShowString(str);
    printf("长度:%d, 是否为空:%d(1:是 0:否)\n\n", StrLength(str), StrEmpty(str));


    int ind = Index(str, strcopy, 1);
    printf("查找到了,位置为:%d\n",ind);

    printf("strcat:\n");
    ShowString(strcat);
    printf("strcopy:\n");
    ShowString(strcopy);
    printf("str:\n");
    ShowString(str);

    Replace(strcat, str, strcopy);
    printf("替换重新显示strcat:\n");
    ShowString(strcat);
    printf("长度:%d, 是否为空:%d(1:是 0:否)\n\n", StrLength(strcat), StrEmpty(strcat));

    printf("strcat插入一个更长的数:\n");
    String s;
    StrAssign(s, "123456");
    StrInsert(strcat, 5, s);//原本的串保留,新插入的截断
    printf("strcat:\n");
    ShowString(strcat);
    printf("长度:%d, 是否为空:%d(1:是 0:否)\n\n", StrLength(strcat), StrEmpty(strcat));

    ClearString(str);
    ClearString(strcopy);
    ClearString(strcat);

    printf("strcat:\n");
    ShowString(strcat);
    printf("strcopy:\n");
    ShowString(strcopy);
    printf("str:\n");
    ShowString(str);

    return 0;
}

在这里插入图片描述

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

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

相关文章

华为设备WLAN配置之AP上线

WLAN基础配置之AP上线 配置WLAN无线网络的第一阶段&#xff0c;AP上线技术&#xff1a; 实验目标&#xff1a;使得AP能够获得来自AC的DHCP地址服务的地址&#xff0c;且是该网段地址池中的IP。 实验步骤&#xff1a; 1.把AC当作三层交换机配置虚拟网关 sys Enter system view,…

2024年艺术鉴赏与文化传播国际会议(AACC 2024)

2024年艺术鉴赏与文化传播国际会议&#xff08;AACC 2024&#xff09; 2024 International Conference on Art Appreciation and Cultural Communication 【重要信息】 大会地点&#xff1a;贵阳 大会官网&#xff1a;http://www.icaacc.com 投稿邮箱&#xff1a;icaaccsub-co…

webpack5零基础入门-16封装cssloader函数

1.背景 我们发现配的cssloader中有很多重复性代码&#xff0c;所以应该对其进行封装&#xff0c;减少冗余的代码 2.定义函数getCssLoader function getCssLoader(pre) {return [MiniCssExtractPlugin.loader, css-loader,{loader: postcss-loader,options: {postcssOptions:…

【笔记】树(Tree)

一、树的基本概念 1、树的简介 之前我们都是在谈论一对一的线性数据结构&#xff0c;可现实中也有很多一对多的情况需要处理&#xff0c;所以我们就需要一种能实现一对多的数据结构--“树”。 2、树的定义 树&#xff08;Tree&#xff09;是一种非线性的数据结构&#xff0…

Excel/WPS《超级处理器》同类项处理,合并同类项与拆分同类项目

在工作中处理表格数据&#xff0c;经常会遇到同类项处理的问题&#xff0c;合并同类项或者拆分同类项&#xff0c;接下来介绍使用超级处理器工具如何完成。 合并同类项 将同一列中的相同内容合并为一个单元格。 1&#xff09;用分隔符号隔开 将AB列表格&#xff0c;合并后为…

UML中的图-13中UML图详解

图是一组元素的图形表示&#xff0c;大多数情况下把图画成顶点和弧的联通图。 UML提供了13种图&#xff0c;分别是类图、对象图、用例图、序列图、通信图、状态图、活动图、构建图、组合结构图、部署图、包图、交互概览图和计时图。序列图、通信图、交互概览图和计时图均被称为…

vue3的核心API功能:computed()API使用

常规使用方法: 这样是常规使用方法. 另一种使用方法: 这样分别定义computed的get回调函数和set回调函数, 上面例子定义了plusOne.value的值为1, 那么这时候就走了computed的set回调函数,而没有走get回调函数. 当我们打印plusOne.value的值的时候,走的是get的回调函数而不是…

ubuntu20.04 10分钟搭建无延迟大疆无人机多线程流媒体服务器

1.使用效果 无人机画面 2.服务器视频端口 3.使用教程 3.1.下载ubuntu对应软件包&#xff1a;系统要求ubuntu16以上 3.2修改端口&#xff08;config.xml文件&#xff09; 3.3启动服务 目录下输入&#xff1a;终端启动&#xff1a;./smart_rtmpd 后台启动&#xff1a;nohup ./…

大语言模型的工程技巧(一)——GPU计算

相关说明 这篇文章的大部分内容参考自我的新书《解构大语言模型&#xff1a;从线性回归到通用人工智能》&#xff0c;欢迎有兴趣的读者多多支持。 本文涉及到的代码链接如下&#xff1a;regression2chatgpt/ch07_autograd/gpu.ipynb 本文将讨论如何利用PyTorch实现GPU计算。本…

dubbo复习: (6)和springboot集成时的条件路由

根据指定的条件&#xff0c;对不满足条件的请求进行拦截。 比如拦截ip地址为192.168.31.227的请求。只需要在dubbo admin中的条件路由菜单创建相应的规则 enabled: true force: true runtime: true conditions:- host ! 192.168.31.227

单例模式介绍,及其应用场景?

单例模式(Singleton Pattern)是 Java中最简单的设计模式之一,此模式保证某个类在运行期间,只有一个实例对外提供服务&#xff0c;而这个类被称为单例类。 单例模式也比较好理解&#xff0c;比如一个人一生当中只能有一个真实的身份证号&#xff0c;一个国家只有一个政府&#x…

【linux】深入了解线程池:基本概念与代码实例(C++)

文章目录 1. 前言1.1 概念1.2 应用场景1.3 线程池的种类1.4 线程池的通常组成 2. 代码示例2.1 log.hpp2.2 lockGuard.hpp① pthread_mutex_t 2.3 Task.hpp2.4 thread.hpp2.5 threadPool.hpp① 基本框架② 成员变量③ 构造函数④ 其余功能函数&#xff1a; main.cc结果演示 完整…

[Redis]常见数据和内部编码

相关命令 type (key) type 命令实际返回的就是当前键的数据结构类型&#xff0c;它们分别是&#xff1a;string&#xff08;字符串&#xff09;、list&#xff08;列 表&#xff09;、hash&#xff08;哈希&#xff09;、set&#xff08;集合&#xff09;、zset&#xff08;有…

Cloneable 接口和深拷贝,浅拷贝

目录 一.Cloneable 接口 二.浅拷贝 三.深拷贝 四.comparable接口、 五.comparator接口 1.Java 中内置了一些很有用的接口 , Cloneable 就是其中之一 . Object 类中存在一个 clone 方法 , 调用这个方法可以创建一个对象的 " 拷贝 ". 2.来说说调用 clone 方法…

基于大型语言模型的游戏智能体

在人工智能领域&#xff0c;游戏代理的发展对于实现通用人工智能&#xff08;AGI&#xff09;至关重要。近年来&#xff0c;大型语言模型&#xff08;LLMs&#xff09;及其多模态版本&#xff08;MLLMs&#xff09;的进展为游戏代理的进化和能力提升提供了前所未有的机遇。这些…

Django自定义模板标签与过滤器

title: Django自定义模板标签与过滤器 date: 2024/5/17 18:00:02 updated: 2024/5/17 18:00:02 categories: 后端开发 tags: Django模版自定义标签过滤器开发模板语法Python后端前端集成Web组件 Django模板系统基础 1. Django模板语言概述 Django模板语言&#xff08;DTL&…

Elasticsearch 分析器的高级用法二(停用词,拼音搜索)

Elasticsearch 分析器的高级用法二&#xff08;停用词&#xff0c;拼音搜索&#xff09; 停用词简介停用词分词过滤器自定义停用词分词过滤器内置分析器的停用词过滤器注意&#xff0c;有一个细节 拼音搜索安装使用相关配置 停用词 简介 停用词是指&#xff0c;在被分词后的词…

巨亏22亿还能上市?瑞幸为何越亏越值钱?剖析资本破局的商业思维

瑞幸咖啡 18个月登上纳斯达克 13个月退市 19个月&#xff0c;粉单市场股价再次翻了8倍 这个技术性“上市”无常的产品是谁&#xff1f; 其实现在这个笑贫不笑娼的社会 如果我说&#xff1a;我们公司上市了&#xff0c;悲催又退市了。我朋友会说&#xff1a;工资没降吧?…

信创数据库有哪些?哪家好?堡垒机支持吗?

当今时代&#xff0c;数据已经成为了企业最宝贵的资产&#xff0c;因此数据库厂商也是不断增加。这不不少小伙伴在问&#xff0c;信创数据库有哪些&#xff1f;哪家好&#xff1f;堡垒机支持吗&#xff1f; 信创数据库有哪些&#xff1f; 1、达梦数据库 2、openGauss 3、人大…