循环移位向量

3

我有一个向量,其格式如下:

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

请问有没有人能建议一个更快的算法?

4个回答

5

s表示您想要移动的位置数。您可以使用circshift

x_shifted = circshift(x, [1 -s]);

第二个参数是[1 -s],因为您想在第二维(列)中向左移动 s 个位置。
您也可以使用mod手动完成:
x_shifted = x(mod((1:numel(x))+s-1, numel(x))+1);

我想我刚刚做了一个 bsxfun 版本的你的 mod 解决方案... 希望没问题! - Divakar

4

circshift 是一种方法,但您也可以使用相当简单的索引来完成:

x_shifted = x([(i+1):end , 1:(i-1)])

这假设了一个条件:1 < i && i < length(x)

比使用 mod 更简单 - Luis Mendo

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

好的解决方案。我认为有趣的是,在hankel内部(就像rayryeng的解决方案一样),它做了和你一样的事情。 - chappjc
很有趣的发现!虽然我并不是一个“汉克尔”人;)感谢分享。 - Divakar

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

比“bsxfun”解决方案更加简洁,但有趣的是,“hankel”在内部使用了类似于Divakar的“bsxfun(@plus,...)”方法,但没有繁琐的语法。对于新手来说可能有些困难。 :) 对你和Divakar都点个赞。 - chappjc
@chappjc - 哦!你知道什么。我从来没有机会查看源代码。这绝对是一个好消息。谢谢 :) - rayryeng

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接