数据结构-C语言版本(八)字符串

news2025/4/23 2:36:44

数据结构中的字符串:概念、操作与实战

第一部分 字符串的分类及常见形式

字符串是由零个或多个字符组成的有限序列,是编程中最基础也最重要的数据结构之一。

1. C语言中的字符串表示

字符数组形式
char str1[10] = {'H', 'e', 'l', 'l', 'o', '\0'};
字符串字面量
char str2[] = "Hello World";
动态分配字符串
char *str3 = (char*)malloc(20 * sizeof(char));
strcpy(str3, "Dynamic String");

2. 字符串的存储方式

固定长度存储
#define MAX_LEN 100
char fixedStr[MAX_LEN];
动态长度存储
typedef struct {
    char *data;
    int length;
} DynamicString;

3. 特殊字符串类型

宽字符字符串
#include <wchar.h>
wchar_t wideStr[] = L"宽字符字符串";
多字节字符串
char mbStr[] = "多字节字符串";

第二部分 字符串常见操作

1. 基本操作函数

字符串长度
size_t my_strlen(const char *str) {
    size_t len = 0;
    while (*str++) len++;
    return len;
}
字符串复制
char* my_strcpy(char *dest, const char *src) {
    char *ret = dest;
    while ((*dest++ = *src++));
    return ret;
}
字符串连接
char* my_strcat(char *dest, const char *src) {
    char *ret = dest;
    while (*dest) dest++;
    while ((*dest++ = *src++));
    return ret;
}
字符串比较
int my_strcmp(const char *s1, const char *s2) {
    while (*s1 && (*s1 == *s2)) {
        s1++;
        s2++;
    }
    return *(unsigned char*)s1 - *(unsigned char*)s2;
}

2. 字符串查找与分割

查找字符
char* my_strchr(const char *str, int c) {
    while (*str != (char)c) {
        if (!*str++) return NULL;
    }
    return (char*)str;
}
查找子串
char* my_strstr(const char *haystack, const char *needle) {
    if (!*needle) return (char*)haystack;
    
    for (; *haystack; haystack++) {
        if (*haystack == *needle) {
            const char *h = haystack, *n = needle;
            while (*h && *n && *h == *n) {
                h++;
                n++;
            }
            if (!*n) return (char*)haystack;
        }
    }
    return NULL;
}
字符串分割
char* my_strtok(char *str, const char *delim) {
    static char *last = NULL;
    if (str) last = str;
    if (!last || !*last) return NULL;
    
    char *start = last;
    while (*last && !strchr(delim, *last)) last++;
    
    if (*last) {
        *last = '\0';
        last++;
    } else {
        last = NULL;
    }
    return start;
}

3. 字符串转换与格式化

字符串转数字
int my_atoi(const char *str) {
    int sign = 1, result = 0;
    
    while (*str == ' ') str++;
    
    if (*str == '-' || *str == '+') {
        sign = (*str++ == '-') ? -1 : 1;
    }
    
    while (*str >= '0' && *str <= '9') {
        result = result * 10 + (*str - '0');
        str++;
    }
    
    return sign * result;
}
数字转字符串
void my_itoa(int num, char *str) {
    int i = 0, sign = num;
    
    if (sign < 0) num = -num;
    
    do {
        str[i++] = num % 10 + '0';
    } while ((num /= 10) > 0);
    
    if (sign < 0) str[i++] = '-';
    str[i] = '\0';
    
    // 反转字符串
    int len = i;
    for (int j = 0; j < len/2; j++) {
        char temp = str[j];
        str[j] = str[len-j-1];
        str[len-j-1] = temp;
    }
}
字符串格式化
int my_sprintf(char *str, const char *format, ...) {
    va_list args;
    va_start(args, format);
    int len = vsprintf(str, format, args);
    va_end(args);
    return len;
}

第三部分 字符串编程题例子

1. 反转字符串

void reverseString(char* s, int sSize) {
    int left = 0, right = sSize - 1;
    while (left < right) {
        char temp = s[left];
        s[left++] = s[right];
        s[right--] = temp;
    }
}

2. 验证回文字符串

bool isPalindrome(char* s) {
    int left = 0, right = strlen(s) - 1;
    
    while (left < right) {
        while (left < right && !isalnum(s[left])) left++;
        while (left < right && !isalnum(s[right])) right--;
        
        if (tolower(s[left++]) != tolower(s[right--])) {
            return false;
        }
    }
    return true;
}

3. 字符串转换整数 (atoi)

int myAtoi(char* str) {
    long result = 0;
    int sign = 1;
    
    while (*str == ' ') str++;
    
    if (*str == '-' || *str == '+') {
        sign = (*str++ == '-') ? -1 : 1;
    }
    
    while (*str >= '0' && *str <= '9') {
        result = result * 10 + (*str - '0');
        if (sign == 1 && result > INT_MAX) return INT_MAX;
        if (sign == -1 && -result < INT_MIN) return INT_MIN;
        str++;
    }
    
    return (int)(sign * result);
}

4. 最长公共前缀

char* longestCommonPrefix(char** strs, int strsSize) {
    if (strsSize == 0) return "";
    
    for (int i = 0; ; i++) {
        char c = strs[0][i];
        for (int j = 1; j < strsSize; j++) {
            if (strs[j][i] != c || strs[j][i] == '\0') {
                char *result = malloc(i + 1);
                strncpy(result, strs[0], i);
                result[i] = '\0';
                return result;
            }
        }
        if (c == '\0') break;
    }
    return strdup(strs[0]);
}

5. 字符串的排列组合

bool checkInclusion(char* s1, char* s2) {
    int len1 = strlen(s1), len2 = strlen(s2);
    if (len1 > len2) return false;
    
    int count1[26] = {0}, count2[26] = {0};
    
    for (int i = 0; i < len1; i++) {
        count1[s1[i] - 'a']++;
        count2[s2[i] - 'a']++;
    }
    
    int matches = 0;
    for (int i = 0; i < 26; i++) {
        if (count1[i] == count2[i]) matches++;
    }
    
    for (int i = len1; i < len2; i++) {
        if (matches == 26) return true;
        
        int left = s2[i - len1] - 'a';
        count2[left]--;
        if (count2[left] == count1[left]) {
            matches++;
        } else if (count2[left] == count1[left] - 1) {
            matches--;
        }
        
        int right = s2[i] - 'a';
        count2[right]++;
        if (count2[right] == count1[right]) {
            matches++;
        } else if (count2[right] == count1[right] + 1) {
            matches--;
        }
    }
    
    return matches == 26;
}

6. 字符串相乘

char* multiply(char* num1, char* num2) {
    int len1 = strlen(num1), len2 = strlen(num2);
    int len = len1 + len2;
    int *result = calloc(len, sizeof(int));
    char *final = malloc(len + 1);
    
    for (int i = len1 - 1; i >= 0; i--) {
        for (int j = len2 - 1; j >= 0; j--) {
            int product = (num1[i] - '0') * (num2[j] - '0');
            int sum = product + result[i + j + 1];
            result[i + j] += sum / 10;
            result[i + j + 1] = sum % 10;
        }
    }
    
    int index = 0;
    while (index < len && result[index] == 0) index++;
    
    if (index == len) {
        final[0] = '0';
        final[1] = '\0';
        return final;
    }
    
    int pos = 0;
    while (index < len) {
        final[pos++] = result[index++] + '0';
    }
    final[pos] = '\0';
    
    free(result);
    return final;
}

7. 正则表达式匹配

bool isMatch(char* s, char* p) {
    if (*p == '\0') return *s == '\0';
    
    bool first_match = (*s != '\0') && (*p == *s || *p == '.');
    
    if (*(p + 1) == '*') {
        return isMatch(s, p + 2) || (first_match && isMatch(s + 1, p));
    } else {
        return first_match && isMatch(s + 1, p + 1);
    }
}

字符串处理是编程中最常见的任务之一,几乎所有的应用程序都会涉及到字符串操作。掌握字符串的基本操作和常见算法,对于解决实际问题至关重要。通过练习这些典型题目,可以深入理解字符串的特性和处理技巧,提高编程能力和算法思维。

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

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

相关文章

【漏洞复现】CVE-2024-38856(ApacheOfbiz RCE)

【漏洞复现】CVE-2024-38856&#xff08;ApacheOfbiz RCE&#xff09; 1. 漏洞描述 Apache OFBiz 是一个开源的企业资源规划&#xff08;ERP&#xff09;系统。它提供了一套企业应用程序&#xff0c;用于集成和自动化企业的许多业务流程。 这个漏洞是由于对 CVE-2023-51467 的…

超详细VMware虚拟机扩容磁盘容量-无坑版

1.环境&#xff1a; 虚拟机&#xff1a;VMware Workstation 17 Pro-17.5.2 Linux系统&#xff1a;Ubuntu 22.04 LTS 2.硬盘容量 虚拟机当前硬盘容量180G -> 扩展至 300G 3.操作步骤 &#xff08;1&#xff09;在虚拟机关机的状态下&#xff0c;虚拟机硬盘扩容之前必…

全面理解Linux 系统日志:核心文件与查看方法

全文目录 1 Linux 系统日志分类及功能1.1 通用日志1.1.1 ‌/var/log/messages1.1.2 ‌/var/log/syslog 1.2 安全相关日志1.2.1 ‌/var/log/auth.log‌&#xff08;Debian/Ubuntu&#xff09;或 ‌/var/log/secure‌&#xff08;RHEL/CentOS&#xff09;1.2.2 /var/log/audit/au…

机器学习-08-关联规则更新

总结 本系列是机器学习课程的系列课程&#xff0c;主要介绍机器学习中关联规则和协同过滤。 参考 机器学习&#xff08;三&#xff09;&#xff1a;Apriori算法&#xff08;算法精讲&#xff09; Apriori 算法 理论 重点 【手撕算法】【Apriori】关联规则Apriori原理、代码…

Flutter与FastAPI的OSS系统实现

作者&#xff1a;孙嘉成 目录 一、对象存储 二、FastAPI与对象存储 2.1 缤纷云S4服务API对接与鉴权实现 2.2 RESTful接口设计与异步路由优化 三、Flutter界面与数据交互开发 3.1 应用的创建 3.2页面的搭建 3.3 文件的上传 关键词&#xff1a;对象存储、FastAPI、Flutte…

Kubernetes控制平面组件:API Server详解(二)

云原生学习路线导航页&#xff08;持续更新中&#xff09; kubernetes学习系列快捷链接 Kubernetes架构原则和对象设计&#xff08;一&#xff09;Kubernetes架构原则和对象设计&#xff08;二&#xff09;Kubernetes架构原则和对象设计&#xff08;三&#xff09;Kubernetes控…

MySQL-锁机制3-意向共享锁与意向排它锁、死锁

文章目录 一、意向锁二、死锁应该如何避免死锁问题&#xff1f; 总结 一、意向锁 在表获取共享锁或者排它锁时&#xff0c;需要先检查该表有没有被其它事务获取过X锁&#xff0c;通过意向锁可以避免大量的行锁扫描&#xff0c;提升表获取锁的效率。意向锁是一种表级锁&#xf…

报告系统状态的连续日期 mysql + pandas(连续值判断)

本题用到知识点&#xff1a;row_number(), union, date_sub(), to_timedelta()…… 目录 思路 pandas Mysql 思路 链接&#xff1a;报告系统状态的连续日期 思路&#xff1a; 判断连续性常用的一个方法&#xff0c;增量相同的两个列的差值是固定的。 让日期与行号 * 天数…

Tailwind 武林奇谈:bg-blue-400 失效,如何重拾蓝衣神功?

前言 江湖有云,Tailwind CSS,乃前端武林中的轻功秘籍。习得此技,排版如行云流水,配色似御风随形,收放自如,随心所欲。 某日,小侠你奋笔敲码,正欲施展“蓝衣神功”(bg-blue-400),让按钮怒气冲冠、蓝光满面,怎料一招使出,画面竟一片白茫茫大地真干净,毫无半点杀气…

开始放飞之先搞个VSCode

文章目录 开始放飞之先搞个VSCode重要提醒安装VSCode下载MinGW-w64回到VSCode中去VSCode原生调试键盘问题遗留问题参考文献 开始放飞之先搞个VSCode 突然发现自己的新台式机上面连个像样的编程环境都没有&#xff0c;全是游戏了&#xff01;&#xff01;&#xff01;&#xff…

基于SA模拟退火算法的车间调度优化matlab仿真,输出甘特图和优化收敛曲线

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于SA模拟退火算法的车间调度优化matlab仿真,输出甘特图和优化收敛曲线。输出指标包括最小平均流动时间&#xff0c;最大完工时间&#xff0c;最小间隙时间。 2…

【仿Mudou库one thread per loop式并发服务器实现】SERVER服务器模块实现

SERVER服务器模块实现 1. Buffer模块2. Socket模块3. Channel模块4. Poller模块5. EventLoop模块5.1 TimerQueue模块5.2 TimeWheel整合到EventLoop5.1 EventLoop与线程结合5.2 EventLoop线程池 6. Connection模块7. Acceptor模块8. TcpServer模块 1. Buffer模块 Buffer模块&…

uniapp h5接入地图选点组件

uniapp h5接入地图选点组件 1、申请腾讯地图key2、代码接入2.1入口页面 &#xff08;pages/map/map&#xff09;templatescript 2.2选点页面&#xff08;pages/map/mapselect/mapselect&#xff09;templatescript 该内容只针对uniapp 打包h5接入地图选点组件做详细说明&#x…

【随缘更新,免积分下载】Selenium chromedriver驱动下载(最新版135.0.7049.42)

目录 一、chromedriver概述 二、chromedriver使用方式 三、chromedriver新版本下载&#x1f525;&#x1f525;&#x1f525; 四、Selenium与Chrome参数设置&#x1f525;&#x1f525; 五、Selenium直接操控已打开的Chrome浏览器&#x1f525;&#x1f525;&#x1f525;…

jenkins批量复制Job项目的shell脚本实现

背景 现在需要将“测试” 目录中的所有job全部复制到 一个新目录中 test2。可以结合jenkins提供的apilinux shell 进行实现。 测试目录的实际文件夹名称是 test。 脚本运行效果如下&#xff1a; [qdevsom5f-dev-hhyl shekk]$ ./copy_jenkins_job.sh 创建文件夹 test2 获取源…

iOS Google登录

iOS Google登录 SDK下载地址在 Firebase 有下载&#xff0c;要下载整个SDK文件&#xff0c;然后拿其中的Google 登录SDK来使用 Firebase 官方文档 github 下载链接

嵌入式工程师( C / C++ )笔试面试题汇总

注&#xff1a;本文为 “嵌入式工程师笔试面试题” 相关文章合辑。 未整理去重。 如有内容异常&#xff0c;请看原文。 嵌入式必会 C 语言笔试题汇总 Z 沉浮 嵌入式之旅 2021 年 01 月 19 日 00:00 用预处理指令 #define 声明一个常数&#xff0c;用以表明 1 年中有多少秒&a…

重构便携钢琴专业边界丨特伦斯便携钢琴V30Pro定义新一代便携电钢琴

在便携电钢琴领域&#xff0c;特伦斯推出的V30Pro折叠钢琴以"技术革新场景适配"的双重升级引发关注。这款产品不仅延续了品牌标志性的折叠结构&#xff0c;更通过声学系统重构与智能交互优化&#xff0c;重新定义了便携乐器的专业边界。 ▶ 核心特点&#xff1a;技术…

DiffuRec: A Diffusion Model for Sequential Recommendation

DiffuRec: A Diffusion Model for Sequential Recommendation Background 序列推荐&#xff08;Sequential Recommendation, SR&#xff09;领域&#xff0c;主流方法是将用户与物品表示为fixed embedding。然而&#xff0c;这种静态向量表达方式难以全面刻画用户多样化的兴趣…

多模态大语言模型arxiv论文略读(三十三)

Jailbreaking Attack against Multimodal Large Language Model ➡️ 论文标题&#xff1a;Jailbreaking Attack against Multimodal Large Language Model ➡️ 论文作者&#xff1a;Zhenxing Niu, Haodong Ren, Xinbo Gao, Gang Hua, Rong Jin ➡️ 研究机构: Xidian Univer…