一个在关于数组内的数据交换的问题

lgdgyd2 2008-06-06 02:03:52
最近在工作中遇到了一个的问题,想破脑袋,也没有个解决办法,还是拿上来,牛人们帮帮偶吧,可能问题挺简单,见笑了!问题如下:
现在有一个数组:如何实现数组中的数据能够进行整块整块的交换。
比如有个数组a[12],如何让数组中的第2-5的元素跟数组第8-10的元素互换位置,其余的元素的顺序不变,交换的两个块之间内部的顺序也不变?若是用链表实现起来,应该不费事,但是用数组该如何实现呢!
例如:a[] = {1,3,5,6,7,8,10,12,13,14},交换之后数据变成
{1,3,12,13,14,10,5,6,7,8}.
...全文
288 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
whycadi 2008-06-07
  • 打赏
  • 举报
回复
dlyme在2楼的方法其实很简单了,就是最后一步没说明白。
如果要移动的两块数量一样的话,直接交换两个块里的内容就完了。如果数量不一样,把不受影响的头尾去掉,分为三部分,s1-e1,s2-e2,s3-e3,分别反转各部分,变为e1-s1,e2-s2,e3-s3,再整个反转,就成了s3-e3,s2-e2,s1-e1.比如 1 2 3 4 5 6 7 8 9 10 11 12 13 14,要交换2-4 和8-11,
第一步:1 {4 3 2} {7 6 5 } {11 10 9 8 } 12 13 14
第二步:1 {8 9 10 11 , 5 6 7 ,2 3 4 } 12 13 14
至于dlyme后来说的“更好”的算法,其实无论哪个算法,至少还是要移动受到影响的元素的个数那么多次数,而两轮反转,每次交换操作移动两个数,所以两轮反转交换的次数也仅为受到影响的元素的个数,操作的次数一样,而交换操作又简单开销又小,何乐而不为呢?
zym11 2008-06-07
  • 打赏
  • 举报
回复
把数组中不需要移动的头尾去掉不考虑,这个问题就转换成x个,m个,y个共n=x+m+y个对象,交换x,y。令t=min(x, y)。
首先用 swap 交换 t 个 x, y的对象。需要 t 次 swap。若 x=y 则结束。
当 x!=y 时。若 x>y, 则需把 x 的尾巴移动到原y的末端;若 x<y, 则需把 y 的尾巴移动到原x的末端,
也就相当于把前面(m+t)个对象移动到y的末端。
这个问题也就转化为把N个对象的前M的对象移动到末端。这个问题我在http://blog.csdn.net/zym11/archive/2008/06/06/2517659.aspx 中有代码。最多需要N-1次swap。
这个问题最多总共需 t + m + t + 尾巴的大小 - 1, 既 n-1 次swap既可。不知是否可满足要求。
rover___ 2008-06-06
  • 打赏
  • 举报
回复
想到一个方法不知道是否可行:
{1,3,5,6,7,8,10,12,13,14},交换之后数据变成
{1,3,12,13,14,10,5,6,7,8}.
只需要记住3个整型参数:插入点位置;被移动段开始位置;被移动段长度;
原数组加上这3个参数就可以表示任何一个对原数组经过移动后的数组。
lgdgyd2 2008-06-06
  • 打赏
  • 举报
回复
哦,好的,谢谢 dlyme 兄
  • 打赏
  • 举报
回复
http://topic.csdn.net/u/20071212/16/165a5b9b-ba1c-41da-be6f-50718bccf6c1.html
看一下这个帖子,会对你有帮助,实际上你说的问题就是这个问题的变种。
帖子最后的方法基本上就已经是最高效的了
lgdgyd2 2008-06-06
  • 打赏
  • 举报
回复
是啊,其实 实际中的数组不是整形数组,如果频繁的交换赋值,可能效率会低
lgdgyd2 2008-06-06
  • 打赏
  • 举报
回复
先谢谢大家帮忙哈!

To 数学兄:我按照您的方法,将0-11的数组进行了处理,但是处理后的结果为:
0,7,8,9,10,5,6,2,3,4,11 跟希望出现的结果不太一样,不知道是我在处理中出现了失误,还是我对您的
描述理解的不对 。

To 眼镜兄:可能是我描述不准确,因为数据是变化的,所以要交换哪两块也是不一定的,两块之间的大小不
一定相等,您的方法对于相等的两块数据是可以的,不知道我说的对不对,呵呵!
oo 2008-06-06
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 tailzhou 的回复:]
to : oo

两个块的个数不一样的;

lz的例子里就是一个块4个,一个块3个元素;
[/Quote]

多谢提醒
  • 打赏
  • 举报
回复
两块的大小可能不一样,所以不能用同一个num来表示

还有比多次翻转更高效的法子,有点象mathe一楼说的,不过没有额外开辟新空间.
tailzhou 2008-06-06
  • 打赏
  • 举报
回复
to : oo

两个块的个数不一样的;

lz的例子里就是一个块4个,一个块3个元素;
oo 2008-06-06
  • 打赏
  • 举报
回复
要搞这么复杂吗?还是我理解错了

void swap_block(int *a, int s1, int s2, int num)
{
if(s1+num > s2)
{
//这个需要特殊处理
return;
}
for(int i=0;i<num;i++)
{
swap(a[s1+i], a[s2+i]);
}
}
  • 打赏
  • 举报
回复
可通过多次翻转来实现。
比如想交换s1~e1和s2~e2这两块数据(e1<s2):
1)将s1~e1这部分倒序(可通过头尾对换实现);
2)将s2~e2这部分倒序;
3)将s1~e2这部分倒序;
4)将s1+e2-s3+1 ~ s1+e2-e1-1 这部分倒序
mathe 2008-06-06
  • 打赏
  • 举报
回复
0 1 2 3 4 5 6 7 8 9 10 11
=>
0 1 8 9 10 6 7 2 3 4 5 11

所以
2->8->3->9->4->10->5->6->7->2
于是可以写程序

int index[]={7,6,5,10,4,9,3,8,2};
int temp=a[index[0]];
for(i=0;i<sizeof(index)/sizeof(index[0])-1;i++){
a[index[i]]=a[index[i+1]];
}
a[index[i]]=temp;

33,010

社区成员

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

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