2012-03-26 48 views

回答

2

可以使用my vectorized answer to the previous question首先複製你的矩陣:

>> mat = [2009 3; 2010 2]; 
>> index = zeros(1, sum(mat(:, 2))); 
>> index([1; cumsum(mat(1:end-1, 2))+1]) = 1; 
>> Ansmat = mat(cumsum(index), :) 

Ansmat = 

     2009   3 
     2009   3 
     2009   3 
     2010   2 
     2010   2 

接下來,您可以創建偏移的列向量添加到日期中的第一列。這是你如何以矢量化的方式做到這一點。

>> offset = ones(size(Ansmat, 1), 1); 
>> offset([1; cumsum(mat(1:end-1, 2))+1]) = [0; 1-mat(1:end-1, 2)]; 
>> Ansmat(:, 1) = Ansmat(:, 1)+cumsum(offset) 

Ansmat = 

     2009   3 
     2010   3 
     2011   3 
     2010   2 
     2011   2 
+1

哇,這是一個瘋狂的聰明和聰明的方式,榮譽:)一個小調整;因此這適用於需要在您的[1 ...]上下文中使用它的三個位置轉置mat(1:end-1,2)的多於兩行的矩陣。 – GummiV 2012-03-27 18:12:06

+0

@GummiV:很好。我添加了一些分號來糾正對於較大矩陣會發生的尺寸不匹配。 – gnovice 2012-03-27 18:17:19

+0

@Gnovice謝謝。我已經注意到了GummiV提到的錯誤,並用一個簡單的方法加以糾正;謝謝..這真的很快,聰明:) – Maddy 2012-03-28 00:04:31

0

我不確定是否有一種方法可以在沒有循環的情況下執行此操作,因爲這是我們正在執行的有點模糊的操作。如果我理解你的算法正確這裏是使用一個單一的for循環兩種方法:

B = zeros(sum(A(:,2)), 2); 
counter = 1; 
for i = 1:size(A,2) 
    n = A(i,2); 
    B(counter:counter+n-1,1) = A(i,1)+(0:n-1)'; 
    B(counter:counter+n-1,2) = n; 
    counter = counter+n; 
end 

你可以做廢除了預分配。如果counter變量令人困惑,那麼你可以檢查出每一次迭代都追加矩陣B的變量,但需要一個初始起始事件。

n = A(1,2); 
B = [A(1,1)+(0:n-1)', n*ones(n,1)]; 
for i = 2:size(A,2) 
    n = A(i,2); 
    B = [B; A(i,1)+(0:n-1)', n*ones(n,1)]; 
end 
0
incr = (0 : max(mat(:, 2)))'; 
incr = [incr, 0 * incr]; 
Ansmat = []; 
for k = 1 : size(mat, 1) 
    Ansmat = cat(1, Ansmat, repmat(mat(k, :), mat(k, 2), 1) + incr(1 : mat(k, 2), :)); 
end 

但如果矩陣Ansmat的預期大小大,GummiV的第一個解決方案會更快。