
C语言学习笔记20260627字符串左旋的四种解法一、学习目标通过经典的“字符串左旋”问题掌握处理字符串变换类问题的四种核心算法思想。深入理解暴力移位法的底层逻辑学习分段拷贝与指针截取的库函数技巧并探究“三次反转法”这一原地算法的数学之美体会从“模拟操作”到“空间换时间”再到“极致优化”的思维跃迁。二、问题拆解与核心逻辑本题要求实现一个函数将字符串中的前 K 个字符整体挪到字符串末尾。例如字符串abcdef左旋 2 位变为cdefab。核心约束条件为周期性如果左旋次数 K 大于字符串长度 len实际有效旋转次数为K % len。空间与效率需要在时间复杂度与空间复杂度之间做出权衡部分解法允许使用额外空间部分解法要求原地In-place操作。三、方法一暴力移位法逐位模拟3.1 核心思路将左旋 K 位拆解为“左旋 1 位”的重复操作。单次左旋 1 位的逻辑是将首字符暂存将剩余字符整体向前移动一位最后将暂存的首字符放到末尾。重复此过程 K 次即可。3.2 完整代码实现#define_CRT_SECURE_NO_WARNINGS#includestdio.h#includestring.h// 单次左旋1位voidleftRotateOne(charstr[],intlen){chartempstr[0];// 整体左移一位for(inti0;ilen-1;i){str[i]str[i1];}str[len-1]temp;}// 左旋k位voidleftRotateK(charstr[],intk){intlenstrlen(str);if(len0)return;kk%len;// k超过长度取模for(inti0;ik;i){leftRotateOne(str,len);}}intmain(){chararr[]abcdef;intk2;leftRotateK(arr,k);printf(%s\n,arr);// 输出 cdefabreturn0;}3.3 方法优缺点分析优点逻辑极其直观完全模拟了物理上的“挪动”过程不需要任何额外的数组空间。缺点时间复杂度为 O(K × N)。当字符串长度 N 很大且 K 接近 N 时需要进行大量的字符移动效率极低。四、方法二分段拷贝法空间换时间4.1 核心思想左旋 K 位本质上就是将字符串从第 K 个位置“切开”把后半段放到前面前半段放到后面。我们可以申请一个临时数组按顺序先拷贝后半段再拷贝前半段最后一次性拷回原数组。4.2 完整代码实现#define_CRT_SECURE_NO_WARNINGS#includestdio.h#includestring.hvoidleftRotateK(charstr[],intk){intlenstrlen(str);if(len0)return;kk%len;chartmp[1000]{0};// 临时数组需保证足够大intidx0;// 1. 先拷贝后半段 str[k] ~ str[len-1]for(intik;ilen;i)tmp[idx]str[i];// 2. 再拷贝前k个字符for(inti0;ik;i)tmp[idx]str[i];// 3. 复制回原字符串strcpy(str,tmp);}intmain(){chararr[]abcdef;leftRotateK(arr,2);printf(%s\n,arr);return0;}4.3 核心细节解析该方法将时间复杂度降低到了 O(N)因为每个字符只被拷贝了一次。缺点需要消耗 O(N) 的额外空间临时数组 tmp。在内存受限的嵌入式开发中需谨慎使用。五、方法三三次反转法原地算法5.1 核心思想数学与逻辑的巧妙结合这是解决字符串旋转最经典的原地算法。以abcdef左旋 2 位为例翻转前 k 个字符abcdef-bacdef翻转剩余字符bacdef-bafedc翻转整个字符串bafedc-cdefab通过三次局部与整体的翻转完美实现了旋转且不需要任何额外空间。5.2 完整代码实现#define_CRT_SECURE_NO_WARNINGS#includestdio.h#includestring.h// 翻转字符串 [left,right] 区间voidreverse(charstr[],intleft,intright){while(leftright){chartstr[left];str[left]str[right];str[right]t;left;right--;}}voidleftRotateK(charstr[],intk){intlenstrlen(str);if(len0)return;kk%len;reverse(str,0,k-1);// 翻转前k个reverse(str,k,len-1);// 翻转后半段reverse(str,0,len-1);// 整体翻转}intmain(){chararr[]abcdef;leftRotateK(arr,2);printf(%s\n,arr);return0;}5.3 方法优缺点分析优点时间复杂度为 O(N)空间复杂度为 O(1)。既高效又节省内存是面试与工程实践中的首选解法。难点需要较强的逻辑推导能力初次接触较难想到这种“以翻转代移动”的巧妙思路。六、方法四指针 / 字符串截取法库函数巧用6.1 核心思想利用 C 语言标准库中的字符串处理函数strcpy,strncat以及指针运算极大地简化代码编写量。核心逻辑依然是“先取后半段再拼前半段”。6.2 完整代码实现#define_CRT_SECURE_NO_WARNINGS#includestdio.h#includestring.hvoidleftRotateK(charstr[],intk){intlenstrlen(str);kk%len;chartmp[1000];// 临时缓冲区// 1. 利用指针运算直接复制后半段从 strk 开始到结束strcpy(tmp,strk);// 2. 利用 strncat 拼接前k个字符strncat(tmp,str,k);// 3. 复制回原字符串strcpy(str,tmp);}intmain(){chararr[]abcdef;leftRotateK(arr,2);printf(%s\n,arr);return0;}6.3 核心细节解析指针运算str k直接定位到了需要左旋的分割点省去了手动写循环拷贝后半段的代码。库函数优势strncat能够自动在拼接后添加字符串结束符\0避免了手动管理字符串结尾的繁琐与潜在错误。七、总结总结暴力移位法是理解字符串底层操作的基石分段拷贝与指针截取法展示了标准库函数在提升开发效率上的巨大优势而三次反转法则体现了算法在时间与空间双重约束下的极致优化。在实际开发中若对性能要求不高且追求代码可读性推荐使用库函数法若在嵌入式底层或算法面试中三次反转法则是展现扎实功底的最佳选择。