2010-09-21 7 views
6

Comment inverser une suite de nombres dans R? Par exemple, j'ai un vecteur d'environ 1000 nombres à six chiffres, et je voudrais savoir si ce sont des palindromes. Je voudrais créer un second set qui soit exactement l'inverse, donc je pourrais faire un match.Inverser les chiffres dans R

+0

S'il n'y a pas de doublons autres que les palindromes, vous pouvez essayez: longueur (x) - longueur (unique (x)) –

+0

dans quelle langue travaillez-vous? – EvanGWatkins

Répondre

12

Il est en fait la représentation decimial du nombre que vous testez d'être un palindrome, pas le nombre lui-même (255 est un palendrome en hexadécimal et binaire, mais pas décimal).

Vous pouvez le faire en utilisant assez simplement correspondance de motif:

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

vous pouvez convertir le nombre de caractères, divisé en caractères individuels (StrSplit), inverser chaque numéro (sapply et rev), puis coller les valeurs retournez ensemble (coller) et retournez aux chiffres (as.numeric). Mais je pense que ce qui précède est préférable si vous êtes juste intéressé par palendromes 6 chiffres.

+1

Belle réponse Greg. Je ne pouvais pas décider si la méthode 'strsplit' ou regex serait plus simple mais, comme vous, je préfère la méthode regex. Cela peut aider à expliquer pourquoi l'expression régulière fonctionne. –

+0

merci - c'est bien - j'avais essayé le strsplit, c'était moche – user446667

+0

Que fait le chapeau dans la ligne grepl - aussi, que font les doubles barres obliques? – user446667

4

Modifier: J'ai mal lu la question. Voici ma réponse pour la postérité.


Vous pouvez utiliser la fonction 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

pouvez-vous appliquer cela à des indices individuels? alors obtenez 1 2 3 etc. 8 9 01 11 21 31 41 etc – user446667

+0

Voir la réponse de Josh; la fonction 'strsplit' est généralement utilisée pour diviser une sous-chaîne. – Shane

3

Je ne pense pas rev ne tout à fait. Il inverse les éléments du vecteur, alors que la question est de savoir comment inverser les éléments dans le vecteur.

> 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. Beau travail sur la lecture rapprochée (http://en.wikipedia.org/wiki/Close_reading)! – Shane

1

Si vous êtes intéressé par les renversements pour leur propre bien, vous pouvez utiliser sous avec une version plus longue de regexp 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" 

Bien que c'est plus rapide que split/rev/coller?

+1

Oui, les expressions régulières sont plus rapides (~ 5-10x) que split/rev/paste/as.numeric. –

1

Cela devrait fonctionner dans le cas général, avec le choix de la 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

Il est fonction dans le paquet stringi pour que - stri_reverse

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

fonction Maintenant palindrome pourrait aussi simple que cela :

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

Je pense que c'est la meilleure réponse. Court et simple, +1 –