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

运行结果:

相关推荐
Qter_Sean10 分钟前
自己动手写Qt Creator插件
开发语言·qt
何曾参静谧14 分钟前
「QT」文件类 之 QIODevice 输入输出设备类
开发语言·qt
爱吃生蚝的于勒1 小时前
C语言内存函数
c语言·开发语言·数据结构·c++·学习·算法
小白学大数据3 小时前
Python爬虫开发中的分析与方案制定
开发语言·c++·爬虫·python
冰芒猓4 小时前
SpringMVC数据校验、数据格式化处理、国际化设置
开发语言·maven
失落的香蕉4 小时前
C语言串讲-2之指针和结构体
java·c语言·开发语言
红中马喽4 小时前
JS学习日记(webAPI—DOM)
开发语言·前端·javascript·笔记·vscode·学习
杜杜的man5 小时前
【go从零单排】Closing Channels通道关闭、Range over Channels
开发语言·后端·golang
java小吕布5 小时前
Java中Properties的使用详解
java·开发语言·后端
versatile_zpc6 小时前
C++初阶:类和对象(上)
开发语言·c++