2016-03-06 103 views
3

一些我想編寫一個函數來扭轉任何數字的順序。這是我的,但它不起作用。請幫幫我!如何扭轉R中

n=123 
rev_number=function(n){ 
m=strsplit(as.character(n),"") 
if (m==rev(m)) print("reversed number") 
} 

所需的輸出是n=321

+0

你能否考慮發佈樣本輸入和期望的輸出?不僅僅是在改變秩序方面扭轉局面? – Konrad

+1

雖然它可能不是最好的方式,我猜你正在嘗試做的'糊(REV(strsplit(as.character(N), 「」)[[1]]),倒塌= 「」)'。雖然如上所述,但最好提供可重現的示例和期望的輸出。 –

+0

謝謝你們。我剛剛更新我的問題輸入和所需的輸出。 – Cypress

回答

7

我覺得像扭轉整數應該留在整數世界,而不是進入的字符串操作世界。看起來在R中沒有這種任務的內置函數,所以我們可以創建一個,例如使用Rcpp包。這裏有一個例子

library(Rcpp) 
cppFunction('int Reverse_CPP(int x) { 
    int reverse = 0; 
    while(x != 0) { 
     int remainder = x%10; 
     reverse = reverse*10 + remainder; 
     x/= 10; 
    } 
    return reverse ; 
}') 

Reverse_CPP(1234) 
# [1] 4321 

而這裏的向量化版本

cppFunction('IntegerVector Reverse_CPP2(IntegerVector x) { 
    int n = x.size(); 
    IntegerVector out(n); 
    IntegerVector xx = clone(x); // Will need this if you don"t want to modify x in place 

    for (int i = 0; i < n; ++i){ 
    int reverse = 0; 
    while(xx[i] != 0) { 
     int remainder = xx[i]%10; 
     reverse = reverse*10 + remainder; 
     xx[i]/= 10; 
    } 
    out[i] = reverse; 
    } 

    return out; 

}') 

Reverse_CPP2(c(12345, 21331, 4324234, 4243)) 
# [1] 54321 13312 4324234 3424 

注意,我不得不添加IntegerVector xx = clone(x);,從而大大減緩功能(見@alexis_laz評論)作爲RCPP將修改原x作爲參考。你並不需要,如果你是通過裸載體,或者如果你如果原來的矢量被modifyied


一些基準對其他矢量字符串處理函數不在乎

Stringi <- function(x) as.integer(stringi::stri_reverse(x)) 

Base <- function(x) { 
    as.integer(vapply(lapply(strsplit(as.character(x), "", fixed = TRUE), rev), 
        paste, collapse = "", FUN.VALUE = character(1L))) 
} 


library(microbenchmark) 
set.seed(123) 
x <- sample(1e3L:1e7L, 1e5, replace = TRUE) 

microbenchmark(
       Base(x), 
       Stringi(x), 
       Reverse_CPP2(x) 
) 

# Unit: milliseconds 
#   expr  min   lq  mean  median   uq   max neval cld 
#   Base(x) 855.985729 913.602215 994.60640 976.836206 1025.482170 1867.448511 100 c 
#  Stringi(x) 86.244426 94.882566 105.58049 102.962924 110.334702 179.918461 100 b 
# Reverse_CPP2(x) 1.842699 1.865594 2.06674 1.947703 2.076983 6.546552 100 a 
+0

只需要在第二個函數中註釋 - 如果輸入'x'確實是「整數」(我假設在傳遞給函數之前「double」將被自動強制),那麼原來的'x'將被修改。 –

+0

@alexis_laz我不確定你的意思。你怎麼能扭轉'12.3'?或者在這種情況下,你的'ff'工作,這不會?同樣'Reverse_CPP2(as.double(c(12,24)))'也能正常工作。雖然'Reverse_CPP2(as.double(12.3))'確實將轉換爲整數,而'FF(12.3)'會返回一些其他的結果。無論哪種方式,我都不理解你的評論。 –

+0

我指的是'typeof';參見 - 例如 - x1 = 12; Reverse_CPP2(X1); X1; x2 = 12L; Reverse_CPP2(2次); x2' –

0

對於整數n > 9this function可用於:

reverse_int <- function(n) { 
    t1 <- floor(log10(n)) 
    t2 <- 0 
    for (i in t1:1) t2 <- t2 + floor(n/10^i) * 10^(t1-i) 
    return(n*10^t1 - 99*t2) 
} 
reverse_int(678754) 
#[1] 457876 

注意,功能不是v ectorized;它只需要一個參數n作爲輸入。

0

的R功能基於整數除法與10連續權力這對迴文數有關學校的項目上來扭轉號碼。

Reverse_number <- function(x){ 
    n <- trunc(log10(x)) # now many powers of 10 are we dealing with 
    x.rem <- x # the remaining numbers to be reversed 
    x.out <- 0 # stores the output 
    for(i in n:0){ 
    x.out <- x.out + (x.rem %/% 10^i)*10^(n-i) # multiply and add 
    x.rem <- x.rem - (x.rem %/% 10^i)*10^i # multiply and subtract 
    } 
return(x.out) 
}