读书笔记三

《编程珠玑》第三章

 

问题一:请将一个具有n个元素的一维向量x向左旋转i个位置。
例如,假设n=8,i=3,那么向量abcdefgh旋转之后得到向量defghabc。
简单编码,使用一个具有n个元素的中间向量,分n步即可完成功能。
你可以仅用几十字节的微小内存,花费与n成比例的时间来旋转向量么?

 

方案一:实现一个函数,用来将向量向左旋转1个位置。循环调用此函数i次即可。

本方案节省空间(只需要一个元素的额外存储),但是浪费了时间(需要做很多次中间操作的搬迁)。

 
  
1 int MAIN(vector x, int i, int n)
2 {
3 for ( int ei = 0 ; ei < i; ei ++ )
4 x = leftshift1(x, n);
5
6 return OK;
7 }
8
9 vector leftshift1 (vector & x, int n)
10 {
11 element first = x[ 0 ];
12
13 for ( int ei = 0 ; ei < n; ei ++ )
14 x[ei] = x[ei + 1 ];
15
16 x[n - 1 ] = first;
17
18 return x;
19 }

 


方案二:将前i个元素复制到额外存储中,将后n-i个元素前移i个元素,再把额外存储中的数据拷贝到向量的最后i个空间里。

本方案使用了i个元素的额外存储,过于浪费空间。

 
  
1 int MAIN (vector x, int i, int n)
2 {
3 vector y = /* build vector with n elements */
4
5 // copy i elements from top x to y
6   memcpy(y, x, i * sizeof (x[ 0 ]));
7
8 // copy n-i elements from end x to y
9   memmove(x, x + i, (n - i) * sizeof (x[ 0 ]));
10
11 // copy i elements from y to end x
12   memcpy(x + (n - i), y, i * sizeof (x[ 0 ]));
13
14 return OK;
15 }

 

方案三:设前i个元素为a,后n-i个元素为b。则向量x可以表示为 ab,转换后的向量可以表示为 ba。
而只需要将a和b分别转置得到 a'b',再对整个向量进行转置,就可以得到最终的向量 ba。

本方案代码简洁清晰,只是计算量增加了一倍(多做了一次位移)。

 
  
1 int MAIN (vector x, int i, int n)
2 {
3 x = reserveVector(x, 0 , i - 1 );
4 x = reserveVector(x, i, n - 1 );
5 x = reserveVector(x, 0 , n - 1 );
6
7 return OK;
8 }
9
10 vector reserveVector(vector & x, int startPos, int endPos)
11 {
12 int s = startPos;
13 int e = endPos;
14
15 while (s < e)
16 {
17 swap(x[s], x[e]);
18 s ++ ;
19 e -- ;
20 }
21
22 return x;
23 }
24
25   int swap (element & s, element & e)
26 {
27 element t = s;
28 s = e;
29 e = t;
30 return OK;
31 }

 

方案四:直接计算各个元素的最终位置。
对于前i个元素,假设初始位置为t(0<=t<i),则最终位置应该是 (n - i + t)
对于后 n-i 个元素,假设初始位置为t(i<=t<n),则最终位置相当于前移了i,应该是 (t - i)

本方案的代码并没有前述方案的简洁,但是计算量最少,并且没有冗余的搬移。

 
  
1 int MAIN (vector x, int i, int n)
2 {
3 int s = 0 ;
4 int c = 0 ;
5 element f;
6
7 s = 0 ;
8 f = x[s];
9
10 while (c < n)
11 {
12 // get final position of current element s
13 int e = GetFinalPosition(s, i, n);
14
15 // store original value in current position to tmp value
16 element t = x[e];
17
18 // fill current element s into final position
19 x[e] = f;
20
21 // increase count
22 c ++ ;
23
24 // prepare for next
25 s = e;
26
27 // store original value from tmp value
28 f = t;
29 }
30
31 return OK;
32 }
33
34 int GetFinalPosition( int t, int i, int n)
35 {
36 if (t < i)
37 return (n - i) + t;
38
39 if ((t >= i) && (t < n))
40 return (t - i);
41
42 return t;
43 }

 

 

转载于:https://www.cnblogs.com/Gigabyte/archive/2010/05/20/Reader-Notes-03.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值