R中的反转数字

时间:2010-09-21 18:59:29

标签: r reverse palindrome

如何反转R中的一串数字?

例如,我有一个大约1000个六位数字的向量,我想知道它们是否是回文。我想创建一个完全相反的第二组,所以我可以做一场对决。

7 个答案:

答案 0 :(得分:12)

它实际上是你正在测试的数字的十分表示,而不是数字本身(255是十六进制和二进制的古代综合症,但不是十进制)。

您可以使用模式匹配相当简单地完成此操作:

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

您可以将数字转换为字符,拆分为单个字符(strsplit),反转每个数字(sapply和rev),然后将值粘贴在一起(粘贴)并转换回数字(as.numeric)。但我认为如果您只对6位数的古代物质感兴趣,上述情况会更好。

答案 1 :(得分: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

答案 2 :(得分:4)

我认为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"

答案 3 :(得分:1)

如果你对逆转感兴趣,你可以使用更长版本的Greg正则表达式的sub:

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

虽然这比分裂/转/粘贴更快吗?

答案 4 :(得分: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))
}

答案 5 :(得分: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

答案 6 :(得分:0)

使用 intToUtf8 进行拆分,然后反转:

tmp <- c(100001, 123321, 123456)

res <- sapply(tmp, function(i) intToUtf8(rev(utf8ToInt(as.character(i)))))

res
# [1] "100001" "123321" "654321"

要检查它是否是回文:

tmp == res
# [1]  TRUE  TRUE FALSE

基准

# bigger vector
tmpBIG <- rep(c(100001, 123321, 123456), 4000)

bench::mark(
  GregSnow = { grepl( '^([0-9])([0-9])([0-9])\\3\\2\\1$', tmpBIG) },
  bartektartanus = { tmpBIG == stringi::stri_reverse(tmpBIG) },
  Spacedman = { tmpBIG == sub( '^([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])','\\6\\5\\4\\3\\2\\1', tmpBIG) },
  Joshua = { tmpBIG == sapply(strsplit(as.character(tmpBIG),""), function(i) paste(rev(i),collapse="")) },
  zx8754 = { tmpBIG == sapply(tmpBIG, function(i) intToUtf8(rev(utf8ToInt(as.character(i))))) },
  relative = TRUE)[, 1:9]

# expression         min median `itr/sec` mem_alloc `gc/sec` n_itr  n_gc total_time
# <bch:expr>       <dbl>  <dbl>     <dbl>     <dbl>    <dbl> <int> <dbl>   <bch:tm>
# 1 GregSnow        1      1         6.82      1         NaN    23     0      517ms
# 2 bartektartanus  1.38   1.34      5.02      2.33      NaN    17     0      520ms
# 3 Spacedman       1.58   1.55      4.52      2.33      NaN    15     0      509ms
# 4 Joshua          5.82   5.56      1.24      5.29      Inf     5     6      617ms
# 5 zx8754          6.06   6.17      1         3.98      Inf     4     4      614ms