2010-09-21 16 views
6

Jak można odwrócić ciąg liczb w R?Odwróć cyfry w R

Na przykład, mam wektor około 1000 cyfr sześciocyfrowych i chciałbym wiedzieć, czy są to palindromy. Chciałbym stworzyć drugi zestaw, który jest dokładnie odwrotny, więc mógłbym wykonać pojedynek.

+0

Jeśli nie ma duplikatów innych niż palindromy, można spróbuj: length (x) - length (unique (x)) –

+0

z jakim językiem współpracujesz? – EvanGWatkins

Odpowiedz

12

To jest rzeczywiście decimial reprezentacją liczby, które testujemy być palindrom, a nie sam numer (255 to palendrome w formacie binarnym i szesnastkowym, ale nie po przecinku).

Można to zrobić dość łatwo stosując dopasowanie Wzór:

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

można przekonwertować numery do charakteru, podzielony na poszczególne znaki (strsplit), rewers każdego numeru (sapply i rev), a następnie wkleić wartości z powrotem (wklej) i ukryj z powrotem do liczb (jako numeryczne). Ale myślę, że powyższe jest lepsze, jeśli interesujesz się tylko 6-cyfrowymi palendromami.

+1

Dobra odpowiedź Grega. Nie mogłem zdecydować, czy metoda 'strsplit' lub regex będzie bardziej prosta, ale tak jak Ty, wolę metodę wyrażeń regularnych. Może pomóc wyjaśnić, dlaczego * działa wyrażenie regularne. –

+0

dziękuję - to jest miłe - próbowałem podciągnąć, to było brzydkie – user446667

+0

Co robi kapelusz w linii grepl - także, co robią podwójne nacięcia? – user446667

4

Edytuj: Wprowadziłem błędne pytanie. Oto moja odpowiedź dla potomności.


Można użyć rev funkcję:

> 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

czy można to zastosować do poszczególnych indeksów? więc pobierz 1 2 3 itd. 8 9 01 11 21 31 41 itd. – user446667

+0

Zobacz odpowiedź Josha; funkcja 'strsplit' jest zwykle używana do dzielenia podłańcucha. – Shane

3

Nie sądzę rev całkiem prawda. Odwraca elementy wektora, a pytanie o to, jak odwrócić elementy wektora.

> 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 O wow. Dobra robota przy bliskiej lekturze (http://en.wikipedia.org/wiki/Close_reading)! – Shane

1

Jeśli jesteś zainteresowany odwrócenia ich własnego dobra, można użyć sub z dłuższą wersją regexp Grega:

> 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" 

Chociaż jest to szybciej niż Split/obr/wklej?

+1

Tak, wyrażenia regularne są szybsze (~ 5-10x) niż wtedy split/rev/paste/as.numeric. –

1

To powinno działać w ogólnym przypadku, z dowolnego wyboru podstawy:

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

istnieje funkcja w stringi opakowaniu tego - stri_reverse

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

Teraz palindrom funkcja może tak proste :

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

Myślę, że to najlepsza odpowiedź. Krótkie i proste, +1 –