2010-09-21 7 views
6

Wie können Sie eine Zeichenkette von Zahlen in R umkehren?Reverse digits in R

zum Beispiel habe ich einen Vektor von etwa 1000 sechsstelligen Zahlen, und ich würde gerne wissen, ob sie Palindrome sind. Ich würde gerne einen zweiten Satz erstellen, der genau umgekehrt ist, also könnte ich ein Matchup machen.

+0

Wenn es keine Duplikate außer den Palindromen gibt, könnten Sie versuchen Sie: Länge (x) - Länge (einzigartig (x)) –

+0

mit welcher Sprache arbeiten Sie? – EvanGWatkins

Antwort

12

Es ist eigentlich die decimial Darstellung der Zahl, die Sie ein Palindrom zu testen, nicht die Zahl selbst (255 ist ein palendrome in hex und binär, sondern Dezimalzahlen nicht).

Sie können dies recht einfach Mustervergleich mit:

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

Sie die Zahlen zum Charakter umwandeln könnte, aufgeteilt in einzelne Zeichen (strsplit), Reverse jede Zahl (sapply und rev), dann die Werte einfügen zurück zusammen (einfügen) und zurück zu Zahlen (wie.numerisch). Aber ich denke, das obige ist besser, wenn Sie nur an 6-stelligen Palädromen interessiert sind.

+1

Schöne Antwort Greg. Ich konnte mich nicht entscheiden, ob die Strsplit- oder Regex-Methode einfacher wäre, aber wie Sie bevorzuge ich die Regex-Methode. Es kann helfen zu erklären, warum der reguläre Ausdruck funktioniert. –

+0

danke - das ist nett - ich hatte versucht die strsplit, es war hässlich – user446667

+0

Was macht der Hut in der grepl-Linie - auch, was tun die Doppel-Back-Schrägstriche tun? – user446667

4

Edit: Ich habe die Frage falsch gelesen. Hier ist meine Antwort für die Nachwelt.


können Sie verwenden, um die rev Funktion:

> 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

können Sie das auf einzelne Indizes anwenden? Also: 1 2 3 usw. 8 9 01 11 21 31 41 usw. – user446667

+0

Siehe Joshs Antwort; Die "strsplit" -Funktion wird normalerweise verwendet, um eine Teilzeichenfolge zu teilen. – Shane

3

Ich glaube nicht rev recht tut es. Es kehrt die Elemente des Vektors um, während die Frage ist, wie man die Elemente in den Vektor umkehrt.

> 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 Oh wow. Gute Arbeit beim Lesen (http://en.wikipedia.org/wiki/Close_reading)! – Shane

1

Wenn Sie in den Umkehrungen um ihrer selbst willen interessiert sind, können Sie Unter mit einer längeren Version von Gregs regexp verwenden:

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

Obwohl dies schneller als Split/U/Paste?

+1

Ja, reguläre Ausdrücke sind schneller (~ 5-10x) als dann split/rev/paste/as.numeric. –

1

Diese im allgemeinen Fall funktionieren soll, bei jeder Wahl der Base:

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

Es Funktion in stringi Paket für das ist - stri_reverse

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

Jetzt Palindrom Funktion könnte so einfach wie die :

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

Ich denke, das ist die beste Antwort. Kurz und einfach, +1 –