2010-09-21 32 views
6

Làm cách nào bạn có thể đảo ngược một chuỗi số trong R? Ví dụ:Số lùi trong R

Ví dụ: tôi có vectơ khoảng 1000 số có sáu chữ số và tôi muốn biết liệu chúng có phải là palindromes hay không. Tôi muốn tạo ra một tập thứ hai, đó là sự đảo ngược chính xác, vì vậy tôi có thể làm một trận đấu.

+0

Nếu không có bản sao nào khác ngoài palindromes, bạn có thể try: length (x) - length (unique (x)) –

+0

bạn đang làm việc với ngôn ngữ nào? – EvanGWatkins

Trả lời

12

Nó thực sự là đại diện decimial của số mà bạn đang thử nghiệm là một palindrome, không phải là số tự (255 là một palendrome trong hex và nhị phân, nhưng không phải thập phân).

Bạn có thể làm điều này khá đơn giản sử dụng mô hình phù hợp:

> tmp <- c(100001, 123321, 123456) 
> grepl('^([0-9])([0-9])([0-9])\\3\\2\\1$', tmp) 
[1] TRUE TRUE FALSE 
> 

bạn có thể chuyển đổi các con số để nhân vật, chia thành đặc điểm cá nhân (strsplit), đảo ngược mỗi số (sapply và rev), sau đó dán các giá trị trở lại với nhau (dán) và bí mật trở lại số (as.numeric). Nhưng tôi nghĩ rằng ở trên là tốt hơn nếu bạn chỉ quan tâm đến 6 chữ số palendromes.

+1

Câu trả lời hay Greg. Tôi không thể quyết định nếu phương pháp 'strsplit' hoặc regex sẽ thẳng tiến hơn nhưng, giống như bạn, tôi thích phương pháp regex hơn. Nó có thể giúp giải thích * tại sao * biểu thức chính quy hoạt động. –

+0

cảm ơn - điều này là tốt đẹp - Tôi đã thử các strsplit, nó là xấu xí – user446667

+0

Những gì các mũ trong dòng grepl làm - cũng có, những gì làm lại đôi slashes làm gì? – user446667

4

Chỉnh sửa: Tôi đã đọc sai câu hỏi. Đây là câu trả lời của tôi cho hậu thế.


Bạn có thể sử dụng chức năng rev:

> 1:10 
[1] 1 2 3 4 5 6 7 8 9 10 
> rev(1:10) 
[1] 10 9 8 7 6 5 4 3 2 1 
+0

bạn có thể áp dụng điều đó cho các chỉ mục riêng lẻ không? để có được 1 2 3 vv 8 9 01 11 21 31 41 vv – user446667

+0

Xem câu trả lời của Josh; Hàm 'strsplit' thường được sử dụng để chia chuỗi con. – Shane

3

Tôi không nghĩ rev khá hiện nó. Nó đảo ngược các phần tử của vectơ, trong khi câu hỏi là cách đảo ngược các phần tử trong vectơ.

> nums <- sapply(1:10,function(i)as.numeric(paste(sample(1:9,6,TRUE),collapse=""))) 
> nums 
[1] 912516 568934 693275 835117 155656 378192 343266 685182 298574 666354 
> sapply(strsplit(as.character(nums),""), function(i) paste(rev(i),collapse="")) 
[1] "615219" "439865" "572396" "711538" "656551" "291873" "662343" "281586" "475892" "453666" 
+1

+1 Ồ wow. Làm việc tốt trên đọc gần (http://en.wikipedia.org/wiki/Close_reading)! – Shane

1

Nếu bạn quan tâm đến các đảo chiều vì lợi ích riêng của họ, bạn có thể sử dụng phụ với một phiên bản dài hơn regexp của Greg:

> x 
[1] 123321 343324 563660 
> sub('^([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])','\\6\\5\\4\\3\\2\\1', x) 
[1] "123321" "423343" "066365" 

Mặc dù là này nhanh hơn split/rev/dán?

+1

Có, biểu thức chính quy nhanh hơn (~ 5-10x) so với sau đó chia/rev/dán/as.numeric. –

1

này nên làm việc trong trường hợp tổng quát, với bất kỳ lựa chọn cơ sở:

is.palindromic <- function(x, base=10) 
{ 
    p <- 0 
    m <- floor(log(x,base)) 
    sig <- -1 
    for (i in m:0) 
     { 
     tp <- floor(x/base^i) 
     a <- i+1 
     b <- m+1-i 
     if(a==b){c<-0}else{c<-a*b;sig<-sig*-1} 
     p <- p + tp*c*sig 
     x <- x - tp*base^i 
     } 
    return(!as.logical(p)) 
} 
1

Có chức năng trong stringi gói cho điều đó - stri_reverse

require(stringi) 
stri_reverse("123456") 
## [1] "654321" 

chức năng Bây giờ palindrome có thể như đơn giản như vậy :

palindrome <- function(x) stri_reverse(x)==x 
palindrome(c("651156","1234321")) 
## [1] TRUE TRUE 
+1

Tôi nghĩ đây là câu trả lời hay nhất. Ngắn và đơn giản, +1 –