数组右移K位

xeniums 2004-06-24 05:06:27
设有一个线性表,存放在一维数组a[0...n-1]中,编程将数组中每一个元素循环右移k位,要求只用一个辅助单元,时间复杂度O(n)。
...全文
439 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
gwsongdeer 2004-08-08
  • 打赏
  • 举报
回复
o
BlueAllRise 2004-08-01
  • 打赏
  • 举报
回复
我的每次移动至需要计算移动后数组的第一个位置的最初始的数组位置就可以了..不需要全部移动,全部移动是到最后需要输出的时候再移动...
levinjoe 2004-07-30
  • 打赏
  • 举报
回复
没看懂你说的?什么意思?
除非修改数组指针,否则你还是要全移动一次阿!而修改指针明显不满足题目要求!
BlueAllRise 2004-07-30
  • 打赏
  • 举报
回复
我的方法好的地方就是在程序中多次移动的时候,可以快速的完成,只需要在最后面加个数组就可以了...
例如 风云剑客 的程序就是每次要移的时候就要全部移一次,如果程序要移的次数很多的话,效率就不是很高了
我的那个在移的次数很多的时候效率就高些了,空间换时间 :)
xeniums 2004-07-01
  • 打赏
  • 举报
回复
风云剑客的程序果然好用
BlueAllRise的想法给我不少启示,但这样又会多一个数组的辅助空间,如果没这种限制我想那是一个高效的方法

谢谢大家!
levinjoe 2004-07-01
  • 打赏
  • 举报
回复
呜呼,由于某种原因,只好省略了一个最小公约数的函数名,相信大家都知道了!
实在没想到他的过滤器这么傻!
levinjoe 2004-07-01
  • 打赏
  • 举报
回复
其实没那么复杂,利用数论知识,或者群中的生成源方法,当(n,k)=1 时
0,k,...,(n-1)*k与0,1,2,...,n-1是同一集合。
(n,k)=m时,将其分成n/m个子循环群.
levinjoe 2004-07-01
  • 打赏
  • 举报
回复

代码如下:
#include <iostream>
using namespace std;

void shiftK(int *a, int n, int k)
{
int i=0,j=0, start=0, count=0;
int temp=a[i];
while (count < n)
{
j = (j-k+n) % n;
if ( j==start)
{
a[i]=temp;
start++;
count++;
j=i=start;
temp=a[start];
}
else
{
count++;
a[i]=a[j];
i=j;
}
}

}
int _tmain(int argc, _TCHAR* argv[])
{
int n,k,*a=NULL;
while (cin>>n > 0)
{
delete a;
a=new int[n];
for (int i=0; i < n; i++)
a[i]=i;
cin>> k;
if (k==0)
break;
while (k<0)
k += n;
shiftK(a,n,k);
for (int i=0; i < n; i++)
cout << a[i] << " ";
cout << endl;
}
return 0;
}

programfanny 2004-06-30
  • 打赏
  • 举报
回复
我的是移 k 个 bit 的过程。
你是要这样的吗?
abcdefghijkl ==>(3) jklabcdefghi
abcdefghijkl ==>(5) hijklabcdefg

BlueAllRise 2004-06-30
  • 打赏
  • 举报
回复
可以阿,当你要生成新的数组的时候...你可以设置一个辅助数组...比如temp为辅助数组.j表示当时第一个元素所在的位置..
j:=j-1;
for i:=1 to n do
begin
inc(j);
if j>n then j:=1;
temp[i]:=a[j];
end;
最后只要把Temp和A这两个数组互换一下..这个是最直观的方法,当然还有麻烦一点点地,但是可以节省内存..
xeniums 2004-06-30
  • 打赏
  • 举报
回复
BlueAllRise(BlueAllRise)
我知道你算法的意思了,但这样好象移过之后数组还是不变的,有没办法让数组移成新的顺序?
xeniums 2004-06-30
  • 打赏
  • 举报
回复
Pascal也行啊........
我学过Delphi,看起来应该差不多的吧。。。。。
xeniums 2004-06-30
  • 打赏
  • 举报
回复
谁能贴出一个完整的函数?

上面的那个好象不行,这是结果:
原来的数:
0,1,2,3,4,5,6,7,8,9,
循环右移四位:
201326592,0,67108864,134217728,4,5,6,7,8,9,

应该是6,7,8,9,0,1,2,3,4,5,
programfanny 2004-06-30
  • 打赏
  • 举报
回复
rolleverybit(int a[],int k,int n)
{int i,bk, buf;
buf=a[n-1];bk=sozeof(int)-k;
for(i=n-1;i>0;i--)a[i]=(a[i]>>k)|(a[i-1]<<bk);
a[0]=(a[0]>>k)|(buf<<bk);
}
BlueAllRise 2004-06-30
  • 打赏
  • 举报
回复
用我上面那个方法绝对可行,只是我只能给出Pascal的源代码...我不会C的-_-b~
xeniums 2004-06-29
  • 打赏
  • 举报
回复
是2003年南航硕士研究生入学考试试题

如果程序员考试也有这题的话,有谁方便的请帮忙把答案贴出来好吗?
我只找到2002前的程序员考卷
BlueAllRise 2004-06-29
  • 打赏
  • 举报
回复
设置一个变量,保存移动后第一个元素的原来位置就可以了...
在通过这个变量来输出移动后的数组..
就看这个样例
原来是
a b c d e f g
移后是
f g a b c d e
移动后这个变量就应该是 6 ,因为 f 在原来那个数组里是处于第6位,以后只要用加减法计算这个位置就可以了...计算的时间复杂度可以省去...然后再把他输出来,复杂度就是 n 了..
lld2001 2004-06-29
  • 打赏
  • 举报
回复
去年的程序员试题,好像是第三题吧
xeniums 2004-06-29
  • 打赏
  • 举报
回复
好象还是不行
DarthVader 2004-06-26
  • 打赏
  • 举报
回复
// ShiftSample.cpp : Defines the entry point for the console application.
// 设有一个线性表,存放在一维数组a[0...n-1]中,编程将数组中每一个元素循环右移k位,
// 要求只用一个辅助单元,时间复杂度O(n)。

#include "stdafx.h"
#include "ShiftSample.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif

#define ARRAY_SIZE(x) sizeof(x)/sizeof(x[0])
#define ELEM_TYPE UCHAR


////////////////////////////////////////////////////////////////////////////////////////////////////

// The one and only application object

CWinApp theApp;

using namespace std;

ELEM_TYPE g_array[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xff};

////////////////////////////////////////////////////////////////////////////////////////////////////

void DoShift(ELEM_TYPE array[],int nSize,UINT nShift);
void ShowContent(ELEM_TYPE array[],int nSize);


////////////////////////////////////////////////////////////////////////////////////////////////////

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;

// initialize MFC and print and error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
_tprintf(_T("Fatal Error: MFC initialization failed\n"));
nRetCode = 1;
}
else
{
DoShift(g_array,ARRAY_SIZE(g_array),4);
ShowContent(g_array,ARRAY_SIZE(g_array));
}

return nRetCode;
}

// 移位操作
void DoShift(ELEM_TYPE array[],int nSize,UINT nShift)
{
// 计算元素大小
int n = sizeof(ELEM_TYPE)*8;

// 一个辅助变量 存放最后一个元素
ELEM_TYPE temp = array[nSize - 1];

// 逆序进行移位操作(如果是左移则相反)
for(int i = nSize - 1;i > 0;i--)
{
array[i] = ( array[i-1] << (n - nShift) ) + ( array[i] >> nShift );
}

// 处理第一个元素,应该将最后一个元素的部分位移到第一个元素的头部
array[0] = ( temp << (n - nShift) ) + ( array[0] >> nShift );
}

// 显示结果
void ShowContent(ELEM_TYPE array[],int nSize)
{
for(int i = 0;i < nSize;i++)
{
char buffer[64];
sprintf(buffer,"%x ",array[i]);
printf("%s",buffer);
}
}
加载更多回复(4)

33,008

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧