C语言代码随想录刷题计划 Day4

LVGL v8.3 图片显示与解码缓存实战:PNG 上屏、C 数组与文件双方案 LVGL v8.3 图片两种存储方式、PNG/JPG 上屏解码器挂载、LV_IMG_CACHE_DEF_SIZE 缓存调优、手动预解码头像有效性判断,及"缓存被动画清空"真实踩坑。 阅读详情

先附上地址方便对照着看:代码随想录

四、字符串

C语言中字符串通常是常量字符串或字符数组,可以用数组下标读取字符串的某一字符

常用库函数整理:

strlen(str):返回str字符串的字符长度,返回结果为 unsigned int

strcpy(str1,str2):将 str2 的复制到 str1 中去,注意不会检查 str1 是否够长,所以需要注意 str1 的长度是否能够容纳,str2 可以是字符数组也可以是字符串常量。

strncpy(str1,str2,n):将 str2 的前n个字符复制到 str1 ,会检查 str1 容量

strcmp(str1,str2):比较两个字符串的ASCII码大小,若出现不相同的字符,则以第一对不相同的字符比较结果为准,相等时返回0

strncmp(str1,str2,n):比较两个字符串前n个字符的ASCII码大小,返回值同上

strcat(str1,str2):将 str2 连接到 str1 的后面,结果保存在 str1 中,也要注意 str1 的长度

strstr(str1,str2):判断 str2 是否是 str1 的子串,如果是,返回 str2 在 str1 中首次出现的地址,否则返回NULL

strlwr(str):将 str 中的大写字母转为小写字母

strupr(str):将str中的小写字母转为大写字母

以上库函数都在string.h头文件中,dev c++可以ctrl加鼠标左键点击头文件进入,然后用ctrl + F搜索函数则可以看到函数需要传入的参数值,机试的时候很好用。

1、反转字符串:没啥好说的,直接莽就完了,注意字符串末尾是以 '\0' 结尾的,别把这个也反转了就行

void reverseString(char* s, int sSize) {
    char tmp;
    for(int i=0;i<sSize/2;i++){
        tmp = s[sSize-i-1];
        s[sSize-i-1] = s[i];
        s[i] = tmp;
    }
}

2、反转字符串II:思维有点僵化了,看到这种一段一段的处理应该就要想到改变for循环的变量处理,i++用多了确实会让人习惯啊。

基本思路:题目每2k个字符判断一次,那么在循环体里应该是 i+=(2*k),然后再根据题意判断情况,如果剩余字符少于k,那么反转右边界应该是 strlen(s)-1,否则就是 i+k-1

步骤如下:

step 1:设置外层for循环,注意 i+=(2*k)

step 2:设置反转两端,left 始终是 i ,但 right 需要根据剩余字符数是否小于 k 来判断

step 3:设置内部 while 循环用于反转字符串,反转思路同上一题,用 for 循环也可以,但是没有while 循环这么好的易读性

char* reverseStr(char* s, int k) {
    int left,right;
    for(int i=0;i<strlen(s);i+=(2*k)){ //step 1
        if(strlen(s)-i<k)  // step 2
            right = strlen(s)-1;
        else right = i+k-1;
        left = i; 
        while(left < right){ //step 3
            char tmp = s[left];
            s[left++] = s[right];
            s[right--] = tmp;
        }
    }
    return s;
}

3、替换数字:看完代码随想录的思路感觉不太适合机试,机试不需要这么多技巧,能够暴力就暴力,就算因为暴力解法扣掉一两个测试点的分也无伤大雅,考试最重要的就是用最短的时间拿到最多的分数,完全没必要追求极致的解法。

所以我选择暴力解法:创建一个足够大的新数组,遍历题目给的数组,遇到小写字母就直接存进去,遇见数字就用 strcat 函数拼上 number 字符串,我的机试建议是:能多用库函数就用库函数,不然机试的时候根本想不起来就麻烦了。注意结尾添一个 '\0' ,否则无法打印。

#include <stdio.h>
#include <string.h>

int main(){
    char s[10000];
    char res[100000];
    int cnt=0;
    scanf("%s",&s);
    for(int i=0;i<strlen(s);i++){
        if('a'<= s[i] && s[i] <= 'z')
            res[cnt++]=s[i];
        else if('0'<=s[i] && s[i]<='9'){
            strcat(res,"number");
            cnt += 6;
        }
    }
    res[cnt]='\0';
    printf("%s",res);
    return 0;
}

4、反转字符串中的单词:这道题很好,但不适合机试,因为机试采用的是输入输出的形式,所以用简单的 scanf 外面套一层循环其实就能去除字符串前后和中间的多余空格,然后存入一个二维字符串数组直接倒序输出,输出的时候每个单词中间输出一个空格就好。

但这道题还是很好的,可以学习一下如何处理多余空格。

理一下这道题的完整思路:首先去除多余空格,然后将整个字符串进行翻转,再依次翻转其中的每个单词。

去除多余空格步骤如下:

step 1:设置头指针和尾指针分别指向字符串开头和结尾,注意尾指针指向是 '\0'前面那个字符

step 2:分别移动头尾指针,找到第一个不是空格的字符,这一步其实就是去除两端多余空格

step 3:设定一个写入指针并从头指针所指位置开始遍历,直至尾指针,其中要注意去除中间多余空格。如何去除:注意到中间的多余空格一定是≥2个,所以当前字符如果是空格且下一个字符也是空格时就不予理会,直到当前是空格但下一个字符不是空格时再存入空格。

step 4:新写入的字符串尾部添加 '\0'

// 删除字符串两端和中间多余的空格
void removeExtraSpace(char* s) {
    int start = 0;  //step 1
    int end = strlen(s) - 1; 
    while (s[start] == ' ') start++; //step 2
    while (s[end] == ' ') end--;
    int slow = 0; // 指向新字符串的下一个写入位置的指针
    for (int i = start; i <= end; i++) { //step 3
        if (s[i] == ' ' && s[i+1] == ' ')  { // 如果当前字符是空格,并且下一个字符也是空格,则跳过
            continue;
        }
        s[slow] = s[i]; // 否则,将当前字符复制到新字符串的 slow 位置
        slow++; // 将 slow 指针向后移动
    }
    s[slow] = '\0'; //step 4
}

反转部分只要设置一个函数,传入待反转的字符串,反转起始位置和结束位置就行

// 翻转字符串中指定范围的字符
void reverse(char* s, int start, int end) {
    for (int i = start, j = end; i < j; i++, j--) {
        int tmp = s[i];
        s[i] = s[j];
        s[j] = tmp;
    }
}

最后实现题目要求的方法,注释很详细就不多赘述了

// 翻转字符串中的单词
char * reverseWords(char * s){
    removeExtraSpace(s); // 先删除字符串两端和中间的多余空格
    reverse(s, 0, strlen(s) - 1); // 翻转整个字符串
    int slow = 0; // 指向每个单词的开头位置的指针
    for (int i = 0; i <= strlen(s); i++) { // 遍历整个字符串
        if (s[i] ==' ' || s[i] == '\0') { // 如果当前字符是空格或空字符,说明一个单词结束了
            reverse(s, slow, i-1); // 翻转单词
            slow = i + 1; // 将 slow 指针指向下一个单词的开头位置
        }
    }
    return s; // 返回处理后的字符串
}

5、右旋字符串:

如果不限制空间复杂度的话,这道题我有两个思路:一个正儿八经的做一个新字符串,一个直接取巧输出

如果限制空间复杂度不能申请额外空间的话:就是代码随想录的思路和取巧输出

先看第一种:解法是先申请一个额外字符串,然后复制原本字符串的最后 n 个字符到新字符串的开头,然后利用 strcat 库函数将原来字符串的前 n 个拼接到新字符串后面,这种解法适合力扣这种需要返回值的刷题平台。

#include <stdio.h>
#include <string.h>

int main(){
    int num,i;
    char str[10000],res[10000];
    scanf("%d",&num);
    scanf("%s",&str);
    for(i=0;i<num;i++){
        res[i] = str[strlen(str)-num+i]; //将后n个字符放到新字符串开头
    }
    res[i]='\0'; 
    str[strlen(str)-num]='\0'; //注意截断原来的字符串再拼接
    strcat(res,str); //拼接
    printf("%s",res);
    
    return 0;
}

第二种就是直接取巧输出,先输出后n个字符,再输出前面 strlen(str)-n 个字符,适用于机试或一些给定输入让你输出的平台

#include <stdio.h>
#include <string.h>

int main(){
    int num,i;
    char str[10000];
    scanf("%d",&num);
    scanf("%s",&str);
    for(i=0;i<num;i++)
        printf("%c",str[strlen(str)-num+i]);
    for(i=0;i<strlen(str)-num;i++)
        printf("%c",str[i]);
    return 0;
}

如果限制空间复杂度为O(1)的话,那就等同于2010年的408算法题最优解

思路也很简单:先反转整个字符串,再分别反转前 n 个字符和后 strlen(str)-n 个字符

演示如下:设 n 为 2

abcdefg -> gfedcba -> fgedcba -> fgabcde,三次反转即可,由于C语言没有现成的反转函数,上一题中的reverse函数就可以拿来用

#include <stdio.h>
#include <string.h>

// 翻转字符串中指定范围的字符
void reverse(char* s, int start, int end) {
    for (int i = start, j = end; i < j; i++, j--) {
        int tmp = s[i];
        s[i] = s[j];
        s[j] = tmp;
    }
}

int main(){
    int num,i;
    char str[10000];
    scanf("%d",&num);
    scanf("%s",&str);
    reverse(str,0,strlen(str)-1);
    reverse(str,0,num-1);
    reverse(str,num,strlen(str)-1);
    printf("%s",str);
    return 0;
}

6、实现strStr():应付机试的话没必要手搓KMP算法,虽然它相对其他来说比较好写,也不需要暴力逐个字符进行比对,只需要用到库函数 strncmp 就好,代码非常简单,一看就会。

也是暴力的一种思路,但无需逐个字符比对,机试的时候多利用库函数总是没错的。

int strStr(char* haystack, char* needle) {
    int length=strlen(needle);
    for(int i=0;i<strlen(haystack);i++)
    {
        if(strncmp(haystack+i,needle,length)==0)
        return i;
    }
    return -1;
}

7、重复的子字符串:我的建议是直接暴力,尽量不要去手搓算法,这对C语言一点也不友好,对于机试的话你算法如果写错了调试都很麻烦。

bool repeatedSubstringPattern(char* s) {
    int n = strlen(s);
    for (int i = 1; i * 2 <= n; ++i) {
        if (n % i == 0) {
            bool match = true;
            for (int j = i; j < n; ++j) {
                if (s[j] != s[j - i]) {
                    match = false;
                    break;
                }
            }
            if (match) {
                return true;
            }
        }
    }
    return false;
}

总结:字符串类型的题目多用库函数,等到想学算法的再来手写算法也不迟。

【Godot】实现对话系统 在 Godot 中实现对话系统(Dialogue System)是游戏开发中的常见需求。Godot本身自带的的灵活性和轻量级脚本语言 GDScript 使得实现对话系统变得相对简单。以下是实现一个基础对话系统的示例。(语言为GDScript但高亮选择Python因为类似)通过 Godot 和 GDScript,我们可以给我们的游戏实现一个对话系统。从简单的文本显示到复杂的分支对话,Godot 提供了足够的灵活性来满足我们的需求。如果需要更高级的功能,可以尝试使用现成的插件如 Dialogic。 阅读详情

相关推荐

UDS服务应该支持哪些否定响应码

UDS服务应该支持哪些否定响应码所有服务都需支持的否定响应码具体的服务需要支持的否定响应码否定响应码定义及其取值 USD诊断服务的否定响应中包含有导致否定响应原因的编码,称为否定响应码(NRC, Negative Response Code)。否定响应码的取值范围为0x00 - 0xFF,被分为三组: 0x00:服务器内部实现否定响应码判断逻辑时使用,表示要给出肯定响应。 0x01 – 0x7F:诊断通信相关的否定响应码。 0x80 – 0xFF:服务器收到诊断服务请求时,由于某些条件不满足要求而给出的否定

闲聊汽车软件开发 4万+

代码随想录(C)DAY2

c语言day2 数组(2)

m0_73412849的博客 376

Redis【实战篇】---- 分布式锁-redission

重入问题:重入问题是指 获得锁的线程可以再次进入到相同的锁的代码块中,可重入锁的意义在于防止死锁,比如HashTable这样的代码中,他的方法都是使用synchronized修饰的,假如他在一个方法内,调用另一个方法,那么此时如果是不可重入的,不就死锁了吗?所以可重入锁他的主要意义是防止死锁,我们的synchronized和Lock锁都是可重入的。不可重试:是指目前的分布式只能尝试一次,我们认为合理的情况是:当线程在获得锁失败后,他应该能再次尝试获得锁。

是微风,是晚霞,是无可替代 1万+

C语言代码随想录刷题计划 Day3

考研复试有机试,写点东西记录下技巧啥的,等机试前一天晚上拿出来看看

SepMiranda的博客 975

从 SM30 到 Fiori:在 SAP BTP ABAP Environment 里创建 Business Configuration 配置维护对象的完整路径

摘要 在SAP BTP的ABAP环境中,传统SAP GUI和SM30配置方式被Business Configuration (BC)替代。BC通过Fiori应用维护配置,支持传输和权限控制。配置表需满足可维护性条件,如允许数据维护、包含技术字段等。通过ADT生成Maintenance Object和Transport Object,实现配置发布与治理。权限管理需创建IAM App和Business Catalog,确保配置可维护。BC在云端延续了可控、可追溯、可发布的治理原则。 (字数:150)

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 242

STM32CubeMX之DAC产成正弦波

“在之前的文章中曾经介绍过用TIM产生PWM做DAC用,STM32定时器输出PWM做DAC。部分型号的STM32单片机内部有专用的DAC,本篇文章将介绍如何用内部DAC+DMA产生正弦波...

zhang062061的专栏 1513

C语言代码随想录刷题计划 Day2

考研复试有机试,写点东西记录下技巧啥的,等机试前一天晚上拿出来看看

SepMiranda的博客 1177

团体程序设计天梯赛竞赛题--登顶题【L3-039 攀岩】

登顶级 3 道题,每道题 30 分,满分为 90 分。

Pretty Boy Fox的博客 653

LeetCode学习记录(数组篇)

leetcode数组相关算法

qq_60488118的博客 287

Codex 接入国产大模型完整指南:CC-Switch 与 Codex++ 的工程化选型

Codex 默认走 OpenAI Responses API,而 DeepSeek、GLM、Kimi 等国产模型只提供 OpenAI-compatible 的 Chat Completions——两套协议在消息结构、流式响应、reasoning 字段、tool call 上都不兼容,所以"改个 Base URL + 填国产 Key"这种朴素操作根本跑不通。本文从架构师视角出发,把 Codex 接入国产大模型这件事讲透:先剖析协议链路到底卡在哪,再对比 CC-Switch和 Codex++两套主流方案的差异

少说,多做 3855

OSG第三方库编译之二十一:minizip编译(Windows、Linux、Macos环境下编译)

OSG编译;第三方库;跨平台编译;minizip编译(Windows、Linux、Macos环境下编译)

LuckyHanMo的博客 2621

C语言代码随想录刷题计划 Day1

考研复试有机试,写点东西记录下技巧啥的,等机试前一天晚上拿出来看看

SepMiranda的博客 2188

使用Python爬虫抓取政府网站政务信息:公告、通知的自动化抓取与分析

通过结合Requests、BeautifulSoup、Selenium等技术,你能够高效地抓取政府网站的数据,并通过MySQL存储与Pandas分析这些数据。通过自动化手段抓取这些信息,不仅可以提高数据收集的效率,还能够实时获取最新的政务动态,为政策研究、舆情分析等提供宝贵数据。我们将通过Python的Requests、BeautifulSoup、Selenium等工具,结合最新的技术实现一个完整的爬虫系统,帮助你轻松抓取并分析政务信息。通过爬虫,我们可以自动化地从指定网站上抓取公告、新闻、通知等信息。

2201_76125261的博客 1907

C语言代码随想录刷题计划 Day5

考研复试有机试,写点东西记录下技巧啥的,等机试前一天晚上拿出来看看

SepMiranda的博客 738

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

【Day65】代码随想录总结篇

今天是代码随想录刷题训练营的最后一天,没有题目只是写感想。

格子格鸽的个人博客 800

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Day64|代码随想录二刷总结

数组与链表,本科数据结构的常客了,学习的更多是List和数组的区别,怎么更好的操作数组,list转数组,数组转list等;栈与队列,声明优先队列的方法,范型,包装类。哈希表与字符串,学会了java中map和一些字符串函数的用法,题目其实不是很难,以及java怎么更方便的操作字符串,StringBuilder的使用。二叉树部分,之前的递归框架也没忘,能ac的题更加多了,更重要的是学会了调试。

weixin_43303286的博客 747

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

代码随想录|day 3

我的边界条件就会出问题。其实是考察一个链表的基础,呃,对于就是关键操作我都没问题,因为平常在书上有练过,这样的写法就是关键的。以及下面的初始化对呃,公有函数和呃,私有这些东西啊,出现了一些打架的情况,我觉得需要把C的一些基础知识需要补一下,嗯,这是这一点的问题。然后还有这个while里面写变量剪剪,然后上一题也说过了,嗯,这道题更多教会我的就是一个规范的一个写法,呃,我需要把C的一些基础内容补习一下。总结一下, 我发现我刷题的时候很容易走神儿,就是遇到难的我不会的时候就很容易走神儿,我觉得这样不是很好。

donge520的博客 432

@ 代码随想录算法训练营第8周(C语言)|Day51(动态规划)

打家劫舍。两种打家劫舍。二叉树加动态规划。

fu1034810010的博客 954

力扣学习day5

原学习目标: 1.争取在2021年2月底刷完力扣10%题目。 2.从零开始学习C,C++,python。 3.用多种方法写出解题思路,以及理解代码。 稍微做点调整,随着学习的深入,越来越觉得盲目做题无针对性是不认真的学习,要有专注点才行,目标在day5之后进行调整,改成对专项学习,学习计划按照公众号「代码随想录」中刷题攻略进行。 新学习目标: 1.按照如下类型来刷:数组-> 链表-> 哈希表->字符串->栈与队列->树->回溯->贪心->动态规划-

写点有意思的博客 431

day1-704. 二分查找 27. 移除元素(C++)

今天的训练结束啦,大概花费3-4h,由于是第一天,在选择看视频,看文章,做题三件事情的顺序上有一些纠结,由于同样一个题有多种解法,比如第一题,可以直接遍历求解(虽然不太明智,但也能解决),所以我认为第一次做可以先看视频了解一下这道题的优解,再自己写代码实现,会增加解题的效率。

weixin_68533516的博客 470

哈希表实战:从原理到高频面试题解析

哈希表作为数据结构中的核心组件,通过哈希函数实现O(1)时间复杂度的快速查询。其原理是将任意长度输入映射到固定大小的地址空间,结合开链法或开放寻址法处理哈希碰撞。在工程实践中,哈希表常用于字符串处理、数组去重、频率统计等场景,是优化算法效率的利器。以LeetCode经典题为例,有效的字母异位词和两个数组的交集展示了哈希表在算法竞赛中的典型应用。掌握哈希表底层实现差异(如Java的HashMap与Python的dict)及性能调优技巧(如负载因子设置),能显著提升代码质量。代码随想录Day7专题更系统性地梳理

weixin_30471561的博客 310

代码随想录--数组--c语言详解

使用前缀和方法,可以在 O(1)O(1)O(1) 时间内快速回答区间和查询,代价是需要 O(n)O(n)O(n) 时间预处理数组并存储前缀和信息。这种方法非常适合在需要频繁查询区间和的情况下使用。这个问题的关键在于通过遍历所有可能的分割线,并计算出最小的差值。通过横向和纵向的分割,可以得到最小的两个子区域之间的差值,从而保证了公平的分配。

2301_77256810的博客 814

代码随想录 01数组

个人笔记

lepensur的博客 434

代码随想录|leetcode刷题|C语言|Day1|704二分查找|27移除元素

leetcode刷题|704二分查找|27移除元素

m0_57857068的博客 382

static 的三种用法:C 语言里一个关键字的三张面孔

本文系统讲解 C 语言中 static 关键字的三种用法:修饰局部变量延长生命周期、修饰全局变量与函数限制作用域到本文件。通过一个包含三个文件的完整工程示例对照演示,并从存储期、作用域与链接性三个属性解释其统一原理,最后补充单元测试框架偏爱 static 函数的工程实践。

大模型全栈工程师 · Thanks_ks 318

视频隐私脱敏工程化:CSRT/KCF追踪算法在本地推理中的实现与边界

在短视频内容合规审查中,动态遮挡(Dynamic Masking)是高频且高耗时的环节。传统手动关键帧打码不仅效率低下,且在目标快速移动或遮挡时极易出现遮罩漂移。本文从计算机视觉工程角度,解析基于CSRT与KCF算法的目标追踪方案在视频隐私处理中的技术路径、性能权衡及落地实践。

Mysssone的博客 228
上一篇: C语言代码随想录刷题计划 Day3
下一篇: C语言代码随想录刷题计划 Day5
南亭叙
博客等级 码龄6年 119粉丝 7原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值