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;
}

运行结果:

相关推荐
Suckerbin1 分钟前
PHP 数组数据结构
开发语言·数据结构·php
hlsd#15 分钟前
go web单体项目 学习总结
开发语言·学习·golang
为什么每天的风都这么大17 分钟前
编译faiss的C++ API
开发语言·c++·faiss
nameofworld21 分钟前
前端面试笔试(五)
开发语言·前端·javascript·面试·递归
BIM云平台开发24 分钟前
关于return,yield 和 yield return
java·开发语言·数据结构·c#
小柯J桑_24 分钟前
C++:用红黑树封装map与set-2
开发语言·c++·set·map·红黑树
zwm_yy36 分钟前
Dockerfile && docker-compose
开发语言·docker
敲代码不忘补水1 小时前
Python Matplotlib 经典 3D 绘图类型:从二维到三维的可视化解析
开发语言·python·3d·数据分析·numpy·pandas·matplotlib
码农飞飞1 小时前
详解Rust字符串用法
开发语言·算法·rust·string·所有权·字符串用法
流着口水看上帝1 小时前
SAP开发语言ABAP开发入门
开发语言