修改对象而不使用R函数中的return

时间:2019-06-03 13:26:26

标签: r

我试图在不使用R中多余空间的情况下反转字符串。以下是相同代码。我的问题是如何在不使用额外空间的情况下使ReverseString函数更改输入。我什至没有运气就尝试使用<<-

ReverseString <- function(TestString){
  TestString <- unlist(strsplit(TestString, ""))
  Left <- 1
  Right <- length(TestString)
  while (Left < Right){
    Temp <- TestString[Left]
    TestString[Left] <- TestString[Right]
    TestString[Right] <- Temp
    Left <- Left + 1
    Right <- Right - 1
  }
  return(paste(TestString, collapse = ""))

}
## Input
a = "StackOverFlow"
## OutPut
ReverseString(a)
"wolFrevOkcatS"
## 
a
"StackOverFlow"

4 个答案:

答案 0 :(得分:4)

总是最好利用R中的向量化(而不是for或while循环)。因此,在base-R中,如果没有任何包,它将类似于:

ReverseString <- function(x) {
  #splitstring splits every character, and rev reverses the order
  out <- rev(strsplit(x, split = '')[[1]])
  #paste to paste them together
  paste(out, collapse = '')
}

a <- "StackOverFlow"
ReverseString(a)
#[1] "wolFrevOkcatS"

答案 1 :(得分:2)

使用stringi

可以轻松完成
library(stringi)
a <- "StackOverFlow"
stri_reverse(a)
#[1] "wolFrevOkcatS"

答案 2 :(得分:2)

根据您的评论,您想在不调用任何进行反转的函数的情况下反转字符串,即不使用rev和co。以下两种解决方案都可以做到这一点。

我认为您也在尝试从函数内部修改全局a,因此您尝试了<<-。我不确定为什么它对您不起作用,但是您可能未正确使用它。

您应该知道,单独使用<<-并不意味着您使用的空间更少。要真正节省空间,您必须在调用或修改a的函数的每个步骤中调用或修改全局TestString。这将需要assigndo.callevalparse的某种组合-更不用说要访问元素中的所有pastea按整数位置。尽管由于不存储a的副本而节省了可忽略的空间,但由于调用了无数函数,您的函数最终会变得笨拙,几乎不可读并且效率非常低下。如果您对创建此类可憎对象一无所知,那么请看一下我刚刚列出的功能,并弄清楚如何使用它们。

通过以其他方式改善字符串反转功能,可以更好地花费您的精力。例如,您可以使用诸如13:1中的sapply这样的数字序列来将其缩短很多时间:

reverse_string <- function(string) {
    vec <- str_split(string, "")[[1]]
    paste(sapply(length(vec):1, function(i) vec[i]), collapse = "")
}

reverse_string("StackOverFlow")

#### OUTPUT ####

[1] "wolFrevOkcatS"

如果您的面试官也对反向序列有疑问,那么这是另一个更接近您的原始代码的选择,只是更清洁一点。我还尽力消除了其他使用“多余空间”的区域(索引存储在单个向量中,不再使用Temp):

reverse_string2 <- function(string){
    vec <- str_split(string, "")[[1]]
    i_vec <- c(1, length(vec))

    while(i_vec[1] < i_vec[2]) {
        vec[i_vec] <- vec[c(i_vec[2], i_vec[1])]
        i_vec <- i_vec + c(1, -1)
    }

    paste(vec, collapse = "")
}

reverse_string2("StackOverFlow")

#### OUTPUT ####

[1] "wolFrevOkcatS"

答案 3 :(得分:2)

我不确定我是否确切地理解了问题,但是我认为您正在寻找一种方法来反转字符串对象并将其自动分配给原始对象,而不必执行a <- ReverseString(a)(假设这是您尝试使用<<-的原因)。我对此的解决方案是使用deparse(substitute())读取函数中的原始变量名称,然后使用assign(使用envir = .GlobalEnv)将结果分配给原始变量。

ReverseString <- function(TestString){

  nm <- deparse(substitute(TestString))

  TestString <- unlist(strsplit(TestString, ""))
  Left <- 1
  Right <- length(TestString)
  while (Left < Right){
    Temp <- TestString[Left]
    TestString[Left] <- TestString[Right]
    TestString[Right] <- Temp
    Left <- Left + 1
    Right <- Right - 1
  }

  assign(nm, paste(TestString, collapse = ""), envir = .GlobalEnv)

}

## Input
a = "StackOverFlow"

ReverseString(a)

a
#[1] "wolFrevOkcatS"