2010-09-21 3 views
6

Как вы можете изменить строку чисел в R?Обратные цифры в R

например, у меня есть вектор около 1000 шестизначных чисел, и я хотел бы знать, являются ли они палиндромами. Я хотел бы создать второй набор, который является точным обратным, поэтому я мог бы сделать матч.

+0

Если нет дубликатов, кроме палиндромов, вы можете try: length (x) - length (unique (x)) –

+0

На каком языке вы работаете? – EvanGWatkins

ответ

12

Это на самом деле decimial представление числа, что вы проверяете быть палиндром, а не само число (255 является palendrome в шестнадцатеричном и двоичном, а не десятичную).

Вы можете сделать это довольно просто с помощью сопоставления с образцом:

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

можно преобразовать число в символ, разделить на отдельные символы (strsplit), обратный каждый номер (sapply и оборот), а затем вставить значение обратно (вставить) и скрытно вернуться к номерам (as.numeric). Но я думаю, что вышеизложенное лучше, если вас интересуют только 6-значные паландромы.

+1

Хороший ответ Грег. Я не мог решить, будет ли метод 'strsplit' или regex более прямым, но, как и вы, я предпочитаю метод regex. Это может помочь объяснить * почему * работает регулярное выражение. –

+0

спасибо - это приятно - я попробовал strsplit, это было уродливо – user446667

+0

Что делает шляпа в линии grepl - также, что делают двойные косые черты? – user446667

4

Редактировать: Я неправильно понял вопрос. Вот мой ответ для потомков.


Вы можете использовать функцию 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

можете ли вы применить это к отдельным индексам? поэтому получите 1 2 3 и т. д. 8 9 01 11 21 31 41 и т. д. – user446667

+0

См. ответ Джоша; функция 'strsplit' обычно используется для разделения подстроки. – Shane

3

Я не думаю, что rev вполне делает. Он меняет элементы вектора, в то время как вопрос заключается в том, как перевернуть элементы в вектор.

> 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 О, ничего себе. Хорошая работа по закрытому чтению (http://en.wikipedia.org/wiki/Close_reading)! – Shane

1

Если вы заинтересованы в разворотах ради них самого, вы можете использовать суб с более длинной версией регулярного выражения Грега:

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

Хотя это быстрее, чем разделенная/об/пасте?

+1

Да, регулярные выражения быстрее (~ 5-10x), чем split/rev/paste/as.numeric. –

1

Это должно работать в общем случае, при любом выборе базы:

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

Существует функция stringi пакета для этого - stri_reverse

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

Теперь палиндром функция может так просто :

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

Я думаю, что это лучший ответ. Короткий и простой, +1 – 2015-04-15 07:47:17

Смежные вопросы