C语言——小知识和小细节16

一、左旋字符串

例如字符串 abcd ,左旋一个就是 bcda ,左旋两个就是 cdab 。

方法一:循环

cpp 复制代码
#include <stdio.h>
#include <string.h>

void func(char* str, int n)
{
	int i = 0;
	int j = 0;
	int len = (int)strlen(str);
	n %= len;//超出字符串长度的次数就不用再左旋,左旋len次就相当于字符串没变
	for (i = 0; i < n; i++)
	{
		char c = *str;
		for (j = 0; j < len - 1; j++)
		{
			str[j] = str[j + 1];
		}
		str[len - 1] = c;
	}
}

int main()
{
	char str[] = "abcd";
	func(str,2);
	printf("%s\n", str);
	return 0;
}

用n控制左旋次数,用c作为临时变量存储第一个字符,然后将字符串整体向左移一个元素大小,然后将临时变量存储的字符放到最后。

运行结果:

方法二:递归

cpp 复制代码
#include <stdio.h>
#include <string.h>

void func(char* str, int n)
{
	char c = *str;
	int len = (int)strlen(str);
    n %= len;
	int i = 0;
	for(i = 0;i < len - 1;i++)
	{
		*(str + i) = *(str + i + 1);
	}
	*(str + len - 1) = c;
	if (n > 1)
	{
		func(str, n - 1);
	}
}

int main()
{
	char str[] = "abcd";
	func(str,2);
	printf("%s\n", str);
	return 0;
}

与循环相似,这里使用n控制递归深度。

运行结果:

方法三:三次逆序

通过需要左旋的个数,将字符串分为两步分,分别对两部分进行逆序,然后在对整个字符串进行逆序,经过三次逆序就完成了对字符串的左旋。

cpp 复制代码
#include <stdio.h>
#include <string.h>

void reverse(char* left, char* right)
{
	char tmp = 0;
	while (left < right)
	{
		tmp = *left;
		*left = *right;
		*right = tmp;
		left++;
		right--;
	}
}

void func(char* str, int n)
{
	int len = (int)strlen(str);
	n %= len;
	reverse(str, str + n - 1);
	reverse(str + n, str + len - 1);
	reverse(str, str + len - 1);
}

int main()
{
	char str[] = "abcdef";
	func(str,2);
	printf("%s\n", str);
	return 0;
}

运行结果:

二、判断一个字符串可不可以通过另一个字符串左旋得到

方法一:穷举

cpp 复制代码
#include <stdio.h>
#include <string.h>

int foo(char* string1, char* string2)
{
	int len = (int)strlen(string1);
	int i = 0,j = 0;
	char tmp = 0;
	for (i = 0; i < len; i++)
	{
		tmp = string1[0];
		for (j = 0; j < len - 1; j++)
		{
			string1[j] = string1[j + 1];
		}
		string1[j] = tmp;
		if (strcmp(string1, string2) == 0)
		{
			return 1;
		}
	}
	return 0;
}

int main()
{
	char str1[] = "abcd";
	char str2[] = "abcd";
	if (foo(str1, str2))
	{
		printf("yes\n");
	}
	else
	{
		printf("no\n");
	}
	return 0;
}

将第一个字符串一次一次左旋,然后与第二个字符串比较,字符串左旋自己的长度次就变回了原样,所以只用循环 len 次。

运行结果:

方法二、库函数

当我们使用 strcat 库函数在第一个字符串的后面再追加一个第一个字符串,我们就能发现我们可以在这个字符串中找到所有自旋的情况。

这样我们就可以使用 strstr 库函数来找第二个字符串是否在这个字符串中存在了。

这种方法要在函数里判断两个字符串长度是否相等,以防第二个字符串大于或小于第一个字符串,而且是第一个字符串追加后的字符串的子字符串。

而且 string1 还要有足够的空间以供后续追加。

cpp 复制代码
#include <stdio.h>
#include <string.h>

int foo(char* string1, char* string2)
{
	if (strlen(string1) != strlen(string2))
	{
		return 0;
	}
	int len = strlen(string1);
	strncat(string1, string1,len);
	if (strstr(string1, string2) != NULL)
	{
		return 1;
	}
	return 0;
}

int main()
{
	char str1[20] = "abcd";
	char str2[20] = "abcd";
	if (foo(str1, str2))
	{
		printf("yes\n");
	}
	else
	{
		printf("no\n");
	}
	return 0;
}

运行结果:

相关推荐
Yao.Li2 分钟前
python-pcl 安装排障流程
开发语言·python
SuperEugene3 分钟前
Vue3 组合式函数(Hooks)封装规范实战:命名 / 输入输出 / 复用边界 + 避坑|Vue 组件与模板规范篇
开发语言·前端·javascript·vue.js·前端框架
ShineWinsu5 分钟前
对于Linux:git版本控制器和cgdb调试器的解析
linux·c语言·git·gitee·github·调试·cgdb
雨师@10 分钟前
多个golang版本如何切换的办法
开发语言·后端·golang
春日见14 分钟前
自动驾驶的四个演进阶段
开发语言·人工智能·驱动开发·matlab·docker·计算机外设
m0_7167652321 分钟前
C++提高编程--STL初识、string容器详解
java·开发语言·c++·经验分享·学习·青少年编程·visual studio
楼田莉子24 分钟前
高并发内存池项目:内存池性能分析及其优化
开发语言·c++·后端·学习
是翔仔呐30 分钟前
第6章 UART串口通信!掌握单片机与外界的双向数据通道,实现跨设备交互
c语言·开发语言·单片机·嵌入式硬件·gitee
带娃的IT创业者32 分钟前
从本地开发到 PyPI发布:WeClaw 的 Python 包标准化之旅
开发语言·python
2201_7586426433 分钟前
自定义内存检测工具
开发语言·c++·算法