让我说我有一个号码:
Line2
我想列出恰好1位数不同的所有其他长度a<-11121
的数字。
另外假设值只能取1和2
理想的解决方案是:
a
答案 0 :(得分:4)
以下是一些解决方案:
1) replace_ith
将a
中的第i个数字替换为1,如果它是2,则替换为2,如果是1,则将其应用于每个数字:
replace_ith <- function(i, a) {
ch <- strsplit(as.character(a), "")[[1]]
ch[i] <- if (ch[i] == "1") "2" else "1"
as.numeric(paste(ch, collapse = ""))
}
a <- 11121
sapply(1:nchar(a), replace_ith, a)
,并提供:
[1] 21121 12121 11221 11111 11122
2)以下是replace_ith
的第二种可能实施方式:
replace_ith <- function(i, a) {
a <- as.character(a)
substr(a, i, i) <- if (substr(a, i, i) == "1") "2" else "1"
as.numeric(a)
}
3)这是第三种实现。这三个术语是第i个数字时间10^i
之前的数字,反转的第i个数字时间10^(i-1)
和第i个数字之后的数字:
replace_ith <- function(i, a) {
(a %/% 10^i) * 10^i + 10^(i-1) * ( 3 - (a %% 10^i) %/% 10^(i-1) ) + a %% 10^(i-1)
}
答案 1 :(得分:1)
这里的答案纯粹以数字方式完成,并作为单行进行矢量化:
(2 * a %/% (b <- 10^(1:5))) * b +
((2 * a) %% (b / 10)) +
0.3 * b - a
它的工作原理是将2 * a
的每个数字依次归零并放入3而不是将其从2翻转为1,反之亦然。它确实创建了一个变量b
来略微缩短代码。可以通过将每个b
替换为其定义或通过调用local()
中的表达式来删除。
这是另一个使用来自magrittr
和矩阵的管道运算符:
a %>% as.character %>% strsplit("") %>%
unlist %>% as.numeric %>% matrix(5, 5) %>%
`diag<-`(., 3 - diag(.)) %>% t %>% `%*%`(10 ^ (4:0))
这是第二种使用纯数字方法的整洁版本:
a %>% rep(5) %>% outer(4:0, function(x, y) x %/% (10 ^ y) %% 10) %>%
`diag<-`(., 3 - diag(.)) %>% `%*%`(10 ^ (0:4))
另一个使用二进制文件并使用包R.utils
:
as.character(a) %>% strsplit("") %>% {.[[1]] == "2"} %>%
multiply_by_matrix(2 ^ (4:0)) %>% bitwXor(2 ^ (4:0)) %>%
intToBin %>% as.integer(.) + 11111