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

运行结果:

相关推荐
枕星而眠3 小时前
数据结构八大排序详解(一):四大简单排序
c语言·数据结构·c++·后端
努力努力再努力wz3 小时前
【Qt入门系列】:按钮组件全解析:从 QAbstractButton 到快捷键事件、单选与复选机制
c语言·开发语言·数据结构·c++·git·qt·github
skywalk81634 小时前
言知(Yanzhi)系统提升建议报告和完工报告 by AutoCoder
开发语言·编程
yunn_4 小时前
单例模式两种实现方法
开发语言·c++·单例模式
我材不敲代码4 小时前
Python基础:列表详解、增删改查及常用高阶操作
开发语言·windows·python
AI玫瑰助手4 小时前
Python运算符:成员运算符(in/not in)的使用场景
开发语言·python·信息可视化
AI人工智能+电脑小能手5 小时前
【大白话说Java面试题 第77题】【Mysql篇】第7题:回表查询与全表扫描的区别?
java·开发语言·数据库·mysql·面试
水木流年追梦5 小时前
大模型入门-大模型分布式训练2
开发语言·分布式·python·算法·正则表达式·prompt
口袋里のInit5 小时前
基础知识——ARM M核入栈出栈流程
开发语言·arm开发
罗超驿6 小时前
5.Java线程创建全攻略:5种写法 + 高频面试题解析
java·开发语言·java-ee