2010-09-21 21 views
6

Come si può invertire una stringa di numeri in R?cifre inverso nella R

per esempio, ho un vettore di circa 1000 a sei numeri a due cifre, e vorrei sapere se sono palindromi. Mi piacerebbe creare un secondo set che sia l'esatto contrario, quindi potrei fare un matchup.

+0

Se non ci sono duplicati diversi dai palindromi, è possibile prova: length (x) - length (unique (x)) –

+0

con che lingua stai lavorando? – EvanGWatkins

risposta

12

realtà è la rappresentazione decimial del numero che si sta testando essere un palindromo, non il numero stesso (255 è un palendrome in esadecimale e binario, ma non decimale).

È possibile farlo abbastanza semplicemente usando pattern matching:

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

è possibile convertire i numeri per carattere, divisa in singoli caratteri (strsplit), invertire ogni numero (sapply e giri), quindi incollare i valori di nuovo insieme (incolla) e di nuovo nascosto ai numeri (as.numeric). Ma penso che quanto sopra sia meglio se sei interessato solo ai paladromi a 6 cifre.

+1

Bella risposta Greg. Non ho potuto decidere se il metodo 'strsplit' o regex sarebbe stato più semplice ma, come te, preferisco il metodo regex. Può aiutare a spiegare * perché * funziona l'espressione regolare. –

+0

grazie - questo è bello - avevo provato la strsplit, era brutto – user446667

+0

Cosa significa il cappello in linea Grepl do - anche, che cosa le barre posteriore sdoppiabile fanno? – user446667

4

Edit: ho letto male la domanda. Ecco la mia risposta per i posteri.


È possibile utilizzare la funzione 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

puoi applicarlo a singoli indici? quindi prendi 1 2 3 ecc. 8 9 01 11 21 31 41 ecc. – user446667

+0

Vedi la risposta di Josh; la funzione 'strsplit' viene solitamente utilizzata per dividere una sottostringa. – Shane

3

Non credo rev tutto lo fa. Si inverte gli elementi del vettore, mentre la domanda è come invertire gli elementi in vettore.

> 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. Bel lavoro sulla lettura attenta (http://en.wikipedia.org/wiki/Close_reading)! – Shane

1

Se siete interessati alle inversioni di per se stessi, è possibile utilizzare sub con una versione più lunga di regexp di 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" 

Anche se è più veloce di questo split/giri/incolla?

+1

Sì, le espressioni regolari sono più veloci (~ 5-10 volte) rispetto a quelle di split/rev/paste/as.numeric. –

1

Questo dovrebbe funzionare nel caso generale, con qualsiasi scelta della 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

C'è funzione nella stringi pacchetto per questo - stri_reverse

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

funzione Now palindromo potrebbe così semplice come sembra :

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

Penso che questa sia la migliore risposta. Breve e semplice, +1 –