【C语言】左旋字符串

题目:

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

例如:

ABCD左旋一个字符得到BCDA 

ABCD左旋两个字符得到CDAB

法一(用两个循环):

//实现一个函数,可以左旋字符串中的k个字符。
#include<stdio.h>
void reverse(char arr[4], int k)
{
	while (k--)
	{
		char start = arr[0];    //先保存最后一个字符
		for(int i = 0; i <4 ; i++)
		{
			arr[i] = arr[i +1];    //每个字符往后移一位
		}
		arr[3] = start;    //最后一个字符移到第一个位置
	}
}
int main()
{
	char arr[4] = {'A', 'B', 'C', 'D'};
	int k = 0;
	printf("请输入要左旋的字符数:\n");
	scanf("%d", &k);
	reverse(arr, k);
	for (int i = 0; i < 4; i++)
	{
		printf("%c ", arr[i]);
	}
	return 0;
}

法二(建一个新的数组): 

//实现一个函数,可以左旋字符串中的k个字符。
#include<stdio.h>
void reverse(char* arr, int k)
{
	char newarr[4] = { 0 };
	for(int i=0;i<4;i++)
	{
		newarr[i] = arr[(i + k) % 4];
	}
	for (int i = 0; i < 4; i++)
	{
		arr[i] = newarr[i];
		printf("%c ", arr[i]);
	}
}
int main()
{
	char arr[4] = {'A','B','C','D'};
	int k = 0;
    printf("请输入要左旋的字符数:\n");
	scanf("%d", &k);
	reverse(arr, k);

	return 0;
}

 

改进:

但是仍然有一个小问题。在 reverse 函数中,固定了新数组的长度为4,这意味着这个函数只能处理长度为4的字符串。为了使函数更通用,应该传递字符串的长度作为参数。 

另外,代码中没有处理当 k 大于字符串长度的情况。在这种情况下,我们应该将 k 对字符串长度取模,以确保 k 在正确的范围内。

修改如下:

#include <stdio.h>
#include <string.h>

void reverse(char* arr, int n, int k) 
{
    k = k % n;    // 如果k大于n,只旋转k%n个字符
    char newarr[n];     // 这里还是有问题,[]中应该是常量表达式,而不是变量
    for (int i = 0; i < n; i++)
    {
       newarr[i] = arr[(i + k) % 4];   
    }
    for (int i = 0; i < n; i++) 
    {
        arr[i] = newarr[i];
    }
}

int main()
 {
    char arr[] = {'A', 'B', 'C', 'D'};    // 不再固定长度为4
    int k;
    printf("请输入要左旋的字符数: \n");
    if (scanf("%d", &k) != 1) 
    {
        printf("输入错误,请输入一个整数。\n");
        return 1;
    }
    int n = sizeof(arr) / sizeof(arr[0]);    // 计算数组长度
    reverse(arr, n, k);     // 传递数组、数组的实际长度和k
    
    // 打印旋转后的数组
    for (int i = 0; i < n; i++) 
    {
        printf("%c ", arr[i]);
    }
    printf("\n");
    return 0;
}

但是程序报错。

在C语言中,数组的大小必须在编译时是一个已知常量。这意味着我们不能使用一个变量来定义数组的长度,除非我们使用动态内存分配

在上面那个代码中, char newarr[n] 这行代码想在栈上创建一个大小为 n 的数组,其中 n 是一个变量。这在 C 语言中是不合法的,因为数组的大小必须是一个常量表达式

为了解决这个问题,我们可以使用 malloc 或 calloc来动态地分配内存,这样就可以在运行时确定数组的大小。

  1.  下面是一个使用 malloc 的例子:

#include <stdio.h>
#include <stdlib.h>    // calloc和free要包含这个头文件

void reverse(char* arr, int n, int k)
{
    k = k % n;     // 如果k大于n,只旋转k%n个字符
    char* newarr = (char*) malloc(n * sizeof(char));    // 动态分配内存
    if (newarr == NULL) 
    {
        // 分配失败,处理错误
        printf("内存分配失败\n");
        return;
    }
    
    for (int i = 0; i < n; i++)  
    {
        newarr[i] = arr[(i + k) % 4];
    }
    for (int i = 0; i < n; i++) 
    {
        arr[i] = newarr[i];
    }
    
    free(newarr);     // 释放内存
    newarr = NULL;     // 将指针置为 NULL
}

int main()   
{
    char arr[] = {'A', 'B', 'C', 'D'};
    int k;
    printf("请输入要左旋的字符数: \n");
    if (scanf("%d", &k) != 1) 
    {
        printf("输入错误,请输入一个整数。\n");
        return 1;
    }
    int n = sizeof(arr) / sizeof(arr[0]);     // 计算数组长度
    reverse(arr, n, k);     // 传递数组、数组的实际长度和k
   
    // 打印旋转后的数组
    for (int i = 0; i < n; i++) 
    {
        printf("%c ", arr[i]);
    }
    printf("\n");
    return 0;
}

使用 malloc 来动态地分配一个大小为 n 的数组 newarr 。使用 malloc  返回的指针来访问分配的内存。在reveerse  函数的最后,我们使用 free 来释放 newarr 所指向的内存,以避免内存泄漏。

  2. 下面是一个使用 calloc 的例子:

calloc 需要两个参数:要分配的元素数量和每个元素的大小。

#include <stdio.h>
#include <stdlib.h>    // calloc和free要包含这个头文件

void reverse(char* arr, int n, int k) 
{
    k = k % n;    // 如果k大于n,只旋转k%n个字符
    char* newarr = (char*) calloc(n, sizeof(char));    // 动态分配内存并初始化为0
    if (newarr == NULL) 
    {
        // 分配失败,处理错误
        printf("内存分配失败\n");
        return;
    }
    
    for (int i = 0; i < n; i++) 
    {
        newarr[i] = arr[(i + k) % 4];
    }
    for (int i = 0; i < n; i++) 
    {
        arr[i] = newarr[i];
    }
    
    free(newarr);   // 释放内存
    newarr = NULL;    // 将指针置为 NULL
}

int main() 
{
    char arr[] = {'A', 'B', 'C', 'D'};
    int k;
    printf("请输入要左旋的字符数:\n");
    if (scanf("%d", &k) != 1)
    {
        printf("输入错误,请输入一个整数。\n");
        return 1;
    }
    int n = sizeof(arr) / sizeof(arr[0]);   // 计算数组长度
    reverse(arr, n, k);      // 传递数组、数组的实际长度和k
    
    // 打印旋转后的数组
    for (int i = 0; i < n; i++)
    {
        printf("%c ", arr[i]);
    }
    printf("\n");
    return 0;
}

 我们使用 calloc 来替代 malloc 分配 newarr 数组。 calloc 的第一个参数是元素的数量,第二个参数是每个元素的大小,这里是 sizeof(char) 。这样 calloc 会分配 n 个字符大小的内存,并将其全部初始化为 0。

在其他方面,使用 calloc 的代码与使用 malloc 的代码相同。我们仍然需要在操作完成后使用 free 来释放内存,以避免内存泄漏。

宝子们,动动你们发财的小手点点赞吧 

  • 25
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值