2014-02-09 45 views
0

以下C代碼從給定的左側索引和給定的右側索引中搜索數組a [], j)的其中左手食指之間的每一個數組值和i小於v和j和右索引之間的每一個數組值大於v:在R中應用「while(a [++ i] <v)」

i= leftindex - 1 ; 
j = rightindex ; 
while(TRUE) { 
while(a[++i] < v) ; 
while(a[--j] > v) ; 
if (i >= j) { break } 
... } 

此構建體可以在快速的各種實現方式中可以看出排序算法。

我的問題是這樣的:當a是矢量時,下面是在語言R中完成同樣事情的最有效方法嗎?

i = leftindex - 1 ; 
j = rightindex ; 
v = a[rightindex] 
while(TRUE) { 
    while (a[i <- i+1] < v) { } # R doesn't get the ++ operator 
    while (a[j <- j-1] > v) { } # R doesn't get the -- operator 
    if (i >= j) { break } 
    ... 
} 

所以,作爲一個例子,如果 'A' 是:

a <- c('a','s','o','r','t','i','n','g','e','x','a','m','p','l','e') 

...和

left.index = 1; right.index = 15 

...此代碼運行後,然後我會期待值v,i和j爲:

v = e 
i = 2 
j = 11 

我找不到任何在R中定義運算符「++」或「 - 」的東西。

R中的優先級保證「a [i <-i + 1] < v」的計算順序嗎?我的RStudio實現?

我在適當的地方對向量a應用匿名函數(遞減和比較),但這樣寫起來更簡單。

任何想法,將不勝感激。

+0

我懷疑'which'和'diff'的組合可以做一個R向量操作,比'while循環會更有效率。爲什麼不放入數據示例和正確答案的規範? –

+0

好的,謝謝,我編輯了原始問題以包含一個示例。對不起,我在初始化j的代碼片段中有一個拼寫錯誤,所以我也糾正了這個錯誤。 –

回答

2

據我瞭解,你想有R版本替換以下行:

while(a[++i] < v); 
while(a[--j] > v); 

一種簡單的方式來寫這兩條線將是:

i <- i + min(which(a[(i+1):length(a)] >= v)) 
j <- max(which(a[1:(j-1)] <= v)) 

在每種情況下,該函數正在計算a的某些子集具有適當值的所有索引,所以它可能比在自定義C/C++代碼中循環直到找到第一個這樣的條目效率更低。

如果效率對您很重要,您可以爲此操作編寫一個非常簡單的Rcpp函數。在這裏,我已經定義incrementdecrement其中執行兩個操作,在C++代碼,應特別小心轉換ij,我假定在R代碼1索引,爲0索引值:

library(Rcpp) 
increment <- cppFunction(" 
    int increment(NumericVector a, int i, const double v) { 
    while(a[(++i)-1] < v) ; 
    return i; 
    }") 

decrement <- cppFunction(" 
    int decrement(NumericVector a, int j, const double v) { 
    while(a[(--j)-1] > v) ; 
    return j; 
    }") 

然後你可以將你的兩行轉換爲i <- increment(a, i, v)j <- decrement(a, j, v)

+0

感謝您的Rcpp參考。我不知道這個包(對R世界來說很新),並會研究它。 –

+0

我喜歡你的答案。我同意,min(哪個(...))會比符合標準的第一個元素停止的while(..)做更多的比較。因爲比較是排序時的「硬幣」,我喜歡將它們最小化的想法。 –

相關問題