想到数组元素的移动,我最初的想法是这样的。
贴代码:
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