左旋字符串

简介: 左旋字符串

/***********************************************************************

目的:实现一个函数,可以左旋字符串中的k个字符。例如:

ABCD左旋一个字符得到BCDA

ABCD左旋两个字符得到CDAB

分析:假设一个字符串里要左旋2次:

▶ 第一种方法(暴力移位法):

▶ 第二种方法(三步翻转法):

平台:Visual studio 2017 && windows

*************************************************************************/

📝 实现代码1

#include<stdio.h>
#include<assert.h>
#include<string.h>
void string_left_rotation(char* str, int k)
{
  assert(str);
  int len = strlen(str);
  int i = 0;
  //一次循环左旋一个字符
  for(i = 0; i < k; i++) 
  {
    //拷贝
    char temp = *str;
    //覆盖字符
    int j = 0;
    for(j = 0; j < len - 1; j++)
    {
      *(str + j) = *(str + j + 1); 
    }
    //将拷贝的字符拿上来
    *(str + len - 1) = temp;
  }
}
int main()
{
  char arr[10] = "ABCDEF";
  int k = 2;
  string_left_rotation(arr, k);
  printf("%s\n", arr); 
  return 0;
}

📝 实现代码2

#include<stdio.h>
#include<assert.h>
#include<string.h>
void reverse(char* left, char* right)
{
  assert(left && right);
  while(left < right)
  {
    char temp = *left;
    *left = *right;
    *right = temp;
    left++;
    right--;
  }
}
void string_left_rotation(char* str, int k)
{
  assert(str);
  int len = strlen(str);
  reverse(str, str + k - 1);//第一部分
  reverse(str + k, str + len - 1);//第二部分
  reverse(str, str + len - 1);//整体
}
int main()
{
  char arr[10] = "ABCDEF";
  int k = 10;
  //我们当前写的这个代码是不适用于旋转的字符k大于目标数组的arr,所以如果k大于arr时,我们需要看看k有几个arr,并把它排除掉
  k %= strlen(arr);
  string_left_rotation(arr, k);
  printf("%s\n", arr);
  return 0;
}

🧿抛砖引玉

/***********************************************************************

目的:写一个函数判断一个字符串是否为另外一个字符串旋转(左旋或右旋)之后的字符串。例如:

1、 S1 = AABCD 和 S2 = BCDAA,返回1

2、 S1 = abcd和 S2 = ABCD,返回0

分析:

▶ 第一种方法:

只要每左旋一次字符串并比较两字符串是否相等即可

▶ 第二种方法(库函数yyds):

我们发现字符串追加自己后,可以找到所以旋转后的可能性

平台:Visual studio 2017 && windows

*************************************************************************/

📝 实现代码1

#include<stdio.h>
#include<assert.h>
#include<string.h>
int is_string_rotation1(char* str1, char* str2)
{
  assert(str1 && str2);
  int len = strlen(str1);
  int i = 0;
  //一次循环左旋一个字符
  for(i = 0; i < len; i++) 
  {
    //拷贝
    char temp = *str1;
    //覆盖字符
    int j = 0;
    for(j = 0; j < len - 1; j++)
    {
      *(str1 + j) = *(str1 + j + 1); 
    }
    //将拷贝的字符拿上来
    *(str1 + len - 1) = temp;
    //每次旋转一个字符后比较一次
    if(strcmp(str1, str2) == 0)
    {
      return 1;
    }
  }
  return 0;
}
int main()
{
  char arr1[] = "AABCD";
  char arr2[] = "BCDAA";
  int ret = is_string_rotation1(arr1, arr2);
  if(1 == ret)
  {
    printf("Yes\n");
  }
  else
  {
    printf("No\n");
  }
  return 0;
}

📝 实现代码2

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<assert.h>
#include<string.h>
int is_string_rotation2(char* str1, char* str2)
{
  assert(str1 && str2);
  //str1追加str1(注意字符串自己追加自己时不能用strcat,应为它会将'\0'覆盖掉;而strncat在追加完后会补'\0')
  int len = strlen(str1);
  strncat(str1, str1, len);
  //判断str2是否为str1的子串
  char* ret = strstr(str1, str2);
  return ret != NULL;//同下
  /*if(ret == NULL)
  {
    return 0;
  }
  else
  {
    return 1;
  }*/
}
int main()
{
  char arr1[20] = "AABCD";
  char arr2[] = "BCDAA";
  int ret = is_string_rotation2(arr1, arr2);
  if(1 == ret)
  {
    printf("Yes\n");
  }
  else
  {
    printf("No\n");
  }
  return 0;
}

❓❔ 代码2其实是有问题的:

str1:A A B C D A A B C D

str2:B C D

Yes

str2一定是str1的子串,但是str1一定不是str2旋转得来的

/***********************************************************************

目的:修改代码2中的bug

分析:我们发现当str2与str1长度不相等时,那么一定不可能是旋转得来的

平台:Visual studio 2017 && windows

*************************************************************************/

📝 修改代码2

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<assert.h>
#include<string.h>
int is_string_rotation2(char* str1, char* str2)
{
  assert(str1 && str2);
  //修改处
  if(strlen(str1) != strlen(str2))
  {
    return 0;
  }
  //str1追加str1(注意字符串自己追加自己时不能用strcat,应为它会将'\0'覆盖掉;而strncat在追加完后会补'\0')
  int len = strlen(str1);
  strncat(str1, str1, len);
  //判断str2是否为str1的子串
  char* ret = strstr(str1, str2);
  return ret != NULL;//同下
  /*if(ret == NULL)
  {
    return 0;
  }
  else
  {
    return 1;
  }*/
}
int main()
{
  char arr1[20] = "AABCD";
  char arr2[] = "BCDAA";
  int ret = is_string_rotation2(arr1, arr2);
  if(1 == ret)
  {
    printf("Yes\n");
  }
  else
  {
    printf("No\n");
  }
  return 0;
}


相关文章
|
人工智能 算法
从RLHF到DPO再到TDPO,大模型对齐算法已经是token-level
【7月更文挑战第1天】在AI领域的语言模型对齐研究中,新提出的TDPO算法实现了Token-level的直接优化。不同于以往在答案级别评估的方法,TDPO利用前向KL散度和Bradley-Terry模型,直接在生成过程的Token层面上调整对齐,提高微调精度和多样性。实验显示,TDPO优于DPO和RLHF,在某些任务上表现出色,但也面临计算资源需求高、处理复杂任务时局限性等问题,需要进一步验证和改进。[论文链接](https://arxiv.org/abs/2404.11999)
481 8
|
存储 C++
C++实现树 - 04 二叉树的构建(数组)
通过前面两讲的学习,大家可能对二叉树有了比较深的感悟,但可能会发现一个小问题,我们在构建二叉树的时候都是一个个插入的,非常的不方便。那么这节课我们就来看看,如何通过输入一个数组来快速构建起一个二叉树。这里会介绍通过顺序数组、前序数组和后序数组如何构建二叉树。
958 0
C++实现树 - 04 二叉树的构建(数组)
|
2天前
|
弹性计算 运维 搜索推荐
三翼鸟携手阿里云ECS g9i:智慧家庭场景的效能革命与未来生活新范式
三翼鸟是海尔智家旗下全球首个智慧家庭场景品牌,致力于提供覆盖衣、食、住、娱的一站式全场景解决方案。截至2025年,服务近1亿家庭,连接设备超5000万台。面对高并发、低延迟与稳定性挑战,全面升级为阿里云ECS g9i实例,实现连接能力提升40%、故障率下降90%、响应速度提升至120ms以内,成本降低20%,推动智慧家庭体验全面跃迁。
|
3天前
|
数据采集 人工智能 自然语言处理
3分钟采集134篇AI文章!深度解析如何通过云无影AgentBay实现25倍并发 + LlamaIndex智能推荐
结合阿里云无影 AgentBay 云端并发采集与 LlamaIndex 智能分析,3分钟高效抓取134篇 AI Agent 文章,实现 AI 推荐、智能问答与知识沉淀,打造从数据获取到价值提炼的完整闭环。
346 91
|
10天前
|
人工智能 自然语言处理 前端开发
Qoder全栈开发实战指南:开启AI驱动的下一代编程范式
Qoder是阿里巴巴于2025年发布的AI编程平台,首创“智能代理式编程”,支持自然语言驱动的全栈开发。通过仓库级理解、多智能体协同与云端沙箱执行,实现从需求到上线的端到端自动化,大幅提升研发效率,重塑程序员角色,引领AI原生开发新范式。
832 156
|
3天前
|
数据采集 缓存 数据可视化
Android 无侵入式数据采集:从手动埋点到字节码插桩的演进之路
本文深入探讨Android无侵入式埋点技术,通过AOP与字节码插桩(如ASM)实现数据采集自动化,彻底解耦业务代码与埋点逻辑。涵盖页面浏览、点击事件自动追踪及注解驱动的半自动化方案,提升数据质量与研发效率,助力团队迈向高效、稳定的智能化埋点体系。(238字)
250 156
|
4天前
|
域名解析 人工智能
【实操攻略】手把手教学,免费领取.CN域名
即日起至2025年12月31日,购买万小智AI建站或云·企业官网,每单可免费领1个.CN域名首年!跟我了解领取攻略吧~