惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 叶小钗
云风的 BLOG
云风的 BLOG
G
Google Developers Blog
S
SegmentFault 最新的问题
罗磊的独立博客
Hugging Face - Blog
Hugging Face - Blog
美团技术团队
爱范儿
爱范儿
博客园 - 三生石上(FineUI控件)
H
Hackread – Cybersecurity News, Data Breaches, AI and More
D
DataBreaches.Net
F
Fortinet All Blogs
TaoSecurity Blog
TaoSecurity Blog
D
Docker
C
Cybersecurity and Infrastructure Security Agency CISA
K
Kaspersky official blog
宝玉的分享
宝玉的分享
腾讯CDC
Google Online Security Blog
Google Online Security Blog
Recorded Future
Recorded Future
T
The Exploit Database - CXSecurity.com
T
The Blog of Author Tim Ferriss
V
V2EX
S
Securelist
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
C
CERT Recently Published Vulnerability Notes
A
Arctic Wolf
Scott Helme
Scott Helme
L
LINUX DO - 热门话题
Y
Y Combinator Blog
P
Proofpoint News Feed
T
Tor Project blog
AWS News Blog
AWS News Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
The Last Watchdog
The Last Watchdog
博客园 - 聂微东
T
Threat Research - Cisco Blogs
B
Blog
Attack and Defense Labs
Attack and Defense Labs
L
Lohrmann on Cybersecurity
C
CXSECURITY Database RSS Feed - CXSecurity.com
阮一峰的网络日志
阮一峰的网络日志
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
IT之家
IT之家
N
News and Events Feed by Topic
博客园 - 司徒正美
H
Help Net Security
C
Cisco Blogs
C
Check Point Blog
S
Secure Thoughts

博客园 - 香依香偎孤旅独行的驿站

读书笔记二 读书笔记一 计算机加法 简繁体转换 所未见的2009 质数筛选器 让自己闪亮 去医院看病 新手训练课 其言也善哉 伟大的央视 25岁,成人礼 成长的寓言 登梧桐者说 合理或违规 Code 的价值 阿贾克斯踵 来玩个游戏 界面和细节
读书笔记三
香依香偎孤旅独行的驿站 · 2010-05-20 · via 博客园 - 香依香偎孤旅独行的驿站

《编程珠玑》第三章

问题一:请将一个具有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 }