我想编写一个函数来反转任何数字的顺序。以下是我所拥有的,但它不起作用。请帮助我!
n=123
rev_number=function(n){
m=strsplit(as.character(n),"")
if (m==rev(m)) print("reversed number")
}
期望的输出是
n=321
。我想编写一个函数来反转任何数字的顺序。以下是我所拥有的,但它不起作用。请帮助我!
n=123
rev_number=function(n){
m=strsplit(as.character(n),"")
if (m==rev(m)) print("reversed number")
}
n=321
。我觉得反转整数应该留在整数世界,而不是进入字符串操作的世界。在R中似乎没有内置函数来完成这个任务,因此我们可以使用Rcpp包创建一个函数。下面是一个例子:
library(Rcpp)
cppFunction('int Reverse_CPP(int x) {
int reverse = 0;
while(x != 0) {
int remainder = x%10;
reverse = reverse*10 + remainder;
x/= 10;
}
return reverse ;
}')
Reverse_CPP(1234)
# [1] 4321
cppFunction('IntegerVector Reverse_CPP2(IntegerVector x) {
int n = x.size();
IntegerVector out(n);
IntegerVector xx = clone(x); // Will need this if you don"t want to modify x in place
for (int i = 0; i < n; ++i){
int reverse = 0;
while(xx[i] != 0) {
int remainder = xx[i]%10;
reverse = reverse*10 + remainder;
xx[i]/= 10;
}
out[i] = reverse;
}
return out;
}')
Reverse_CPP2(c(12345, 21331, 4324234, 4243))
# [1] 54321 13312 4324234 3424
IntegerVector xx = clone(x);
,因此大大减慢了函数的速度(请参见@alexis_laz的评论),否则Rcpp会通过引用修改原始的x
。如果您传递一个裸向量或者您不关心原始向量是否被修改,那么您不需要这个。
Stringi <- function(x) as.integer(stringi::stri_reverse(x))
Base <- function(x) {
as.integer(vapply(lapply(strsplit(as.character(x), "", fixed = TRUE), rev),
paste, collapse = "", FUN.VALUE = character(1L)))
}
library(microbenchmark)
set.seed(123)
x <- sample(1e3L:1e7L, 1e5, replace = TRUE)
microbenchmark(
Base(x),
Stringi(x),
Reverse_CPP2(x)
)
# Unit: milliseconds
# expr min lq mean median uq max neval cld
# Base(x) 855.985729 913.602215 994.60640 976.836206 1025.482170 1867.448511 100 c
# Stringi(x) 86.244426 94.882566 105.58049 102.962924 110.334702 179.918461 100 b
# Reverse_CPP2(x) 1.842699 1.865594 2.06674 1.947703 2.076983 6.546552 100 a
coerceVector
(返回一个不同的对象)当输入的'typeof'与期望的不匹配时,而当匹配时,相同指向R对象的指针被操作。(我想在这种情况下,只需将x [i]
保存到tmp
中即可解决这个问题)。 - alexis_lazIntegerVector xx = Rcpp::clone(x) ;
或者其他什么... - David Arenburgx[i]
保存到临时“int”中并修改即可。 - alexis_laz这是我通过扩展您的代码尝试的结果
n=-123
rev_number=function(n){
if(n>0)
return(as.integer(paste0(rev(unlist(strsplit(as.character(n), ""))), collapse = "")))
else{
return(-as.integer(paste0(rev(unlist(strsplit(as.character(abs(n)), ""))), collapse = "")))
}
}
rev_number(n)
如果要处理负数,可以使用if else语句。首先将整数转换为字符,然后使用strsplit函数将数字拆分。接着使用unlist函数将列表转换为向量。然后我们可以使用rev函数反转向量并使用paste函数合并向量。最后使用as.integer函数将字符串转换为整数。
如果不想将数字转换为字符,下面的方法不需要任何额外的包,但只适用于正整数。
reverse_number <- function(n){
rev <- 0
while (n > 0) {
r <- n %% 10
rev <- rev * 10 + r
n <- n %/% 10
}
return(rev)
}
reverse_number(134576)
对于大于9的整数,可以使用这个函数:
reverse_int <- function(n) {
t1 <- floor(log10(n))
t2 <- 0
for (i in t1:1) t2 <- t2 + floor(n/10^i) * 10^(t1-i)
return(n*10^t1 - 99*t2)
}
reverse_int(678754)
#[1] 457876
n
作为输入。一个R函数,基于10的连续幂次的整数除法来反转数字。这是在与回文数字相关的学校项目中出现的。
Reverse_number <- function(x){
n <- trunc(log10(x)) # now many powers of 10 are we dealing with
x.rem <- x # the remaining numbers to be reversed
x.out <- 0 # stores the output
for(i in n:0){
x.out <- x.out + (x.rem %/% 10^i)*10^(n-i) # multiply and add
x.rem <- x.rem - (x.rem %/% 10^i)*10^i # multiply and subtract
}
return(x.out)
}
以下是使用 utf8ToInt
或 substring
的其他基本 R 选项
> n <- 123478634
> as.integer(intToUtf8(rev(utf8ToInt(as.character(n)))))
[1] 436874321
> as.integer(paste0(substring(n, nchar(n):1, nchar(n):1), collapse = ""))
[1] 436874321
paste(rev(strsplit(as.character(n),"")[[1]]), collapse = "")
。但正如提到的那样,最好提供一个可重现的示例和期望的输出。 - David Arenburgff = function(x) x * 10^floor(log10(x)) - 99 * sum(floor(x * 10^(-seq_len(floor(log10(x))))) * 10^(floor(log10(x)) - seq_len(floor(log10(x))))); ff(4568742)
。你可以存储一些计算以避免重复。 - alexis_laz