我有一个类似
的向量x = [20 11 12 13 14 15 16 17 18 19]
我想将矢量值移动到给定的
if (i = 1)
X = [11 12 13 14 15 16 17 18 19 20]
if (i = 2)
X = [12 13 14 15 16 17 18 19 20 11]
if (i = 3)
X = [13 14 15 16 17 18 19 20 11 12]
目前我使用for
循环来执行此操作,但需要花费大量时间
x = [20 11 12 13 14 15 16 17 18 19];
in = x;
C1 = x;
for lt = 1:1:length(in)
C1 = x ;
if (lt > 1)
for tt = 1:1:lt-1
swap = C1(1);
for pt = 1:1:length(in)-1
C1(pt) = C1(pt+1);
end
C1(length(in)) = swap;
end
end
disp(C1);
end
有人可以建议我更快的算法吗?
答案 0 :(得分:5)
让s
表示您想要转移的职位数量。您可以使用circshift
:
x_shifted = circshift(x, [1 -s]);
第二个参数是[1 -s]
,因为您希望将s
位置转移到 second 维度(列)中的 left 。
您也可以使用mod
手动执行此操作:
x_shifted = x(mod((1:numel(x))+s-1, numel(x))+1);
答案 1 :(得分:4)
circshift
是要走的路,但你也可以通过非常简单的索引来实现:
x_shifted = x([(i+1):end , 1:(i-1)])
然而,假设1 < i && i < length(x)
。
答案 2 :(得分:2)
您可以在循环开始之前一次性预先计算所有C1
(矢量化方式),并在循环内直接使用它们的值,仅使用索引和从而节省了计算它们的时间 -
N = numel(x);
C1_all = x(mod(bsxfun(@plus,[0:N-1]',0:N-1),N)+1)
针对给定x
的代码运行 -
C1_all =
20 11 12 13 14 15 16 17 18 19
11 12 13 14 15 16 17 18 19 20
12 13 14 15 16 17 18 19 20 11
13 14 15 16 17 18 19 20 11 12
14 15 16 17 18 19 20 11 12 13
15 16 17 18 19 20 11 12 13 14
16 17 18 19 20 11 12 13 14 15
17 18 19 20 11 12 13 14 15 16
18 19 20 11 12 13 14 15 16 17
19 20 11 12 13 14 15 16 17 18
答案 3 :(得分:1)
我还建议使用hankel
。您可以使用hankel
生成一组索引,用于索引x
,其中每行为您提供您要查找的循环移位金额。像这样:
x = [20 11:19];
c = x(hankel([1:numel(x)], [numel(x) 1:numel(x)-1]))
c =
20 11 12 13 14 15 16 17 18 19
11 12 13 14 15 16 17 18 19 20
12 13 14 15 16 17 18 19 20 11
13 14 15 16 17 18 19 20 11 12
14 15 16 17 18 19 20 11 12 13
15 16 17 18 19 20 11 12 13 14
16 17 18 19 20 11 12 13 14 15
17 18 19 20 11 12 13 14 15 16
18 19 20 11 12 13 14 15 16 17
19 20 11 12 13 14 15 16 17 18