我有一个字符串“ECET”,我想创建所有可能的字符串,其中我用“X”替换一个或多个字母(除第一个外)。
在这种情况下,我的结果是:
> result
[1] "EXET" "ECXT" "ECEX" "EXXT" "EXEX" "ECXX" "EXXX"
关于如何处理这个问题有什么想法吗?
这不仅仅是创建“X”的可能组合/排列,还包括如何将它们与现有字符串组合。
为了使用二进制逻辑添加另一个选项:
假设字符串长度始终为4个字符:
input<-"ECET"
invec <- strsplit(input,'')[[1]]
sapply(1:7, function(x) {
z <- invec
z[rev(as.logical(intToBits(x))[1:4])] <- "X"
paste0(z,collapse = '')
})
[1] "ECEX" "ECXT" "ECXX" "EXET" "EXEX" "EXXT" "EXXX"
如果字符串必须更长,可以用2的幂计算值,类似这样的事情应该可以做到:
input<-"ECETC"
pow <- nchar(input)
invec <- strsplit(input,'')[[1]]
sapply(1:(2^(pow-1) - 1), function(x) {
z <- invec
z[rev(as.logical(intToBits(x))[1:(pow)])] <- "X"
paste0(z,collapse = '')
})
[1] "ECETX" "ECEXC" "ECEXX" "ECXTC" "ECXTX" "ECXXC" "ECXXX" "EXETC" "EXETX" "EXEXC" "EXEXX" "EXXTC" "EXXTX" "EXXXC"
[15] "EXXXX"
这个想法是要知道可能的变化的数量,它是一个由3个位置组成的二进制,所以2^3减1,因为我们不想保留无替换字符串:7
intToBits返回整数的二进制值,对于5:
> intToBits(5)
[1] 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
默认情况下,R使用32位,但我们只需要一个对应于字符串长度的逻辑向量,所以我们只保留原始字符串的nchar。然后我们将其转换为逻辑值并反转这4个布尔值,因为我们永远不会触发最后一位(8代表4个字符),所以它永远不会为真:
> intToBits(5)
[1] 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> tmp<-as.logical(intToBits(5)[1:4])
> tmp
[1] TRUE FALSE TRUE FALSE
> rev(tmp)
[1] FALSE TRUE FALSE TRUE
为了避免覆盖原始向量,我们将其复制到z中,然后使用此逻辑向量替换z中的位置。
为了获得一个好的输出,我们返回带有折叠的paste0作为nothing来重新创建单个字符串并检索字符向量。
这是一个递归解决方案:
f <- function(x,pos=2){
if(pos <= nchar(x))
c(f(x,pos+1), f(`substr<-`(x, pos, pos, "X"),pos+1))
else x
}
f(x)[-1]
# [1] "ECEX" "ECXT" "ECXX" "EXET" "EXEX" "EXXT" "EXXX"
或者使用expand.grid
:
do.call(paste0, expand.grid(c(substr(x,1,1),lapply(strsplit(x,"")[[1]][-1], c, "X"))))[-1]
# [1] "EXET" "ECXT" "EXXT" "ECEX" "EXEX" "ECXX" "EXXX"
或使用combn减少
combs <- unlist(lapply(seq(nchar(x)-1),combn, x =seq(nchar(x))[-1],simplify = F),F)
sapply(combs, Reduce, f= function(x,y) `substr<-`(x,y,y,"X"), init = x)
# [1] "EXET" "ECXT" "ECEX" "EXXT" "EXEX" "ECXX" "EXXX"
第二种解决方案解释
pairs0 <- lapply(strsplit(x,"")[[1]][-1], c, "X") # pairs of original letter + "X"
pairs1 <- c(substr(x,1,1), pairs0) # including 1st letter (without "X")
do.call(paste0, expand.grid(pairs1))[-1] # expand into data.frame and paste
使用combn的参数:
a <- "ECET"
fun <- function(n, string) {
combn(nchar(string), n, function(x) {
s <- strsplit(string, '')[[1]]
s[x] <- 'X'
paste(s, collapse = '')
} )
}
lapply(seq_len(nchar(a)), fun, string = a)
[[1]]
[1] "XCET" "EXET" "ECXT" "ECEX"
[[2]]
[1] "XXET" "XCXT" "XCEX" "EXXT" "EXEX" "ECXX"
[[3]]
[1] "XXXT" "XXEX" "XCXX" "EXXX"
[[4]]
[1] "XXXX"
取消列出以获取单个向量。可能有更快的解决方案。
保持第一个字符不变:
paste0(
substring(a, 1, 1),
unlist(lapply(seq_len(nchar(a) - 1), fun, string = substring(a, 2)))
)
[1] "EXET" "ECXT" "ECEX" "EXXT" "EXEX" "ECXX" "EXXX"
问题内容: 我有一个字符串,我想用一个星号替换任何不是标准字符或数字的字符,例如(az或0-9)。例如,“ h ^&ell`。,| ow] {+ orld”被替换为“ h * ell * o * w * orld”。请注意,多个字符(例如“ ^&”)将替换为一个星号。我将如何去做呢? 问题答案: 正则表达式可以解救! 例:
问题内容: 我尝试使用此功能,但没有成功- 问题答案: 使用。 注意:删除了空格,因为通常不将其视为字母数字。
我想用x(下划线)替换特殊字符(regex\W),但我不想用下划线替换空白,也不想用单个下划线替换多个连续的特殊字符 示例字符串:输出: 字符串:输出: 我试过,但并不准确
这应该只得到数字和返回,但不做它作为预期的!有什么建议吗?
我试图找出我的字符串是否包含从a到z的所有字母 我们可以通过其他方法解决这个问题,但我正在尝试仅使用模式和匹配器来解决它。
问题内容: 对于穷人在客户端上实现近似排序规则正确排序的实现,我需要一个JavaScript函数,该函数可以 有效地 替换字符串中的单个字符。 这就是我的意思(请注意,这适用于德语文本,其他语言则有不同的排序方式): 基本上,我需要将给定字符串的所有出现的“ä”替换为“ a”(依此类推)。这样,本机排序的结果将非常接近用户的期望(或数据库将返回的结果)。 其他语言也具有执行此操作的功能:Pytho