C语言数组元素的左移、右移

想到数组元素的移动,我最初的想法是这样的。

贴代码:

	for(i = 0; i < it_Length - it_Steps; i++)
	{
		if(it_Direction == -1)
		{
			Array[i] = pt_Array[i + it_Steps];
		}
		else
		{
			Array[i + it_Steps] = pt_Array[i];
		}
	}

	for(i = 0; i < it_Steps; i++)
	{
		if(it_Direction == -1)
		{
			Array[it_Length - it_Steps + i] = pt_Array[i];

		}
		else
		{
			Array[i] = pt_Array[it_Length - it_Steps + i];
		}
	}

“-1”表示左移,“1”表示右移(会由用户选择输入)。

有两个数组,用用户选择的移动长度(it_Steps)作为一个分界点,将原数组pt_Array从[it_Steps]开始的元素赋值给一个新数组Array(第一个for),再将原数组pt_Array从[0]开始到[it_Steps - 1]的元素赋值给Array。

现在想起来,这个思路确实是过于麻烦,并且只是为了实现功能而设计的。(看不下去)

之后在前辈的指导下,我又写出了两种。

一个是速度最快,不考虑内存的情况下。

一个是占内存最少,速度会有损失的情况下。

速度最快

在我知道有memcpy这个函数时,发现之前自己写的简直就是辣鸡。

函数原型为:void *memcpy(void *dest, const void *src, size_t n)

引用头文件:#include

功能:从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中

(顺便说一句,大家如果想真正提高自己的编程水平,一定得学会自学,百度,MSDN什么的都利用起来)

如果还有什么不懂的就查吧,我就直接贴代码了。

int *Timest(int *pi_Array_in, 
            int i_Length_in, 
            int i_Steps_in, 
            int i_Direction_in, 
            int *piArray)
{
	if (i_Direction_in == -1)
	{
		memcpy(piArray, 
               &pi_Array_in[i_Steps_in], 
               sizeof(int)*(i_Length_in - i_Steps_in));

		memcpy(&piArray[i_Length_in - i_Steps_in], pi_Array_in, sizeof(int)*i_Steps_in);
	}
	else
	{
		memcpy(&piArray[i_Steps_in], 
               pi_Array_in, 
               sizeof(int)*(i_Length_in - i_Steps_in));

		memcpy(piArray, &pi_Array_in[i_Length_in - i_Steps_in], sizeof(int)*i_Steps_in);
	}

	return piArray;
}

还是定义了两个数组,利用memcpy这个函数,左移右移可谓是很容易了。

内存最少

这一种算法可能思考起来就没那么容易了,咱们首先来思考一件事。

要使内存最少,那么也即是只使用一个数组,那么又怎么实现移动呢?

首先咱们定义一个数组int* p_Array_in(int*是因为需要传参)

大家可以将整个数组看作为一个环。

再确定一个初始位置,一般就是数组下标为零的位置了。

然后,我来帮大家理一下:

中间变量 = 未来位置的值;

未来位置的值 = 初始位置的值;

初始位置的值 =  中间变量 ;

以上也就是这个算法的核心了。

有些同学会想了,未来位置的值我怎么知道呢?

不知道大家有没有听说过约瑟夫环,有兴趣的朋友可以去了解一下,这里的道理跟那个有些相似。

公式:

ArrayLength - L, Steps - S, Index - i

i(下次) = (i(这次) + L -S)%L             (左移)

i(下次) = (i(这次) + S)%L                  (右移)

这个时候有些同学又会想了,那万一这个公式整除了怎么办?

所以这里其实有两种情况:

整除和不整除

不整除当然很简单,只需要用到核心算法就可以了,整除是有点儿麻烦,简单点说就是如果下一次的情况会整除就将初始位置的下标加1,然后继续运算。

我直接贴代码了:

int *Roomest(int *p_Array_in, int i_Length_in, int i_Steps_in, int i_Direction_in)
{
	int iCount = 0;

	int i = 0;

	int iInitial = 0;//最初的

	int iTemp;

	int iSelect;

	if (i_Direction_in == -1) 
	{
		iSelect = i_Length_in - i_Steps_in;  //左移
	}
	else 
	{
		iSelect = i_Steps_in;  //右移
	}

	while(iCount < i_Length_in)
	{

		iTemp = p_Array_in[(i + iSelect) % i_Length_in];

		p_Array_in[(i + iSelect) % i_Length_in] = p_Array_in[iInitial];

		p_Array_in[iInitial] = iTemp;

		iCount++;

		i = ((i + iSelect) % i_Length_in);

		if (((i + iSelect) % i_Length_in) == iInitial)   //整除情况处理
		{
			iInitial += 1;

			i = iInitial;

			iCount++;
		}	
	}

	return p_Array_in;
}

还有一个问题就是计数问题了,这是控制循环结束的关键。

每做一次运算,这里的iCount就要加1,实在不明白的同学不嫌麻烦的话可以手写过程,当初我就是写了两遍才基本上明白了。

希望以上内容能给大家一些帮助,初次写blog,有哪里写得不好的地方希望大家多多包涵,当然,更希望大家给我指出来,咱们一起进步。

版权声明:原创文章,欢迎转载,转载请注明作者和链接。 https://blog.csdn.net/qq_42724600/article/details/82079247

你可能感兴趣的:(C相关)