cte*_*a01 3 r converters letters
我编写了一个函数,该函数适用于从 1 到 702 的整数,以非常具体的方式将数字转换为字母。以下是我希望刻字功能如何工作的一些示例:
我们使用此功能对报告中的附录进行“编号”/“字母”。我希望使其更加通用,以便它可以处理任何大小的正整数。如果我可以轻松地将原始数字转换为基数 26,这会更容易,但我在 R 中没有看到一种简单的方法。
appendix_lettering <- function(number) {
if (number %in% 1:26) {
return(LETTERS[[number]])
} else if (number %in% 27:702) {
first_digit <- (floor((number - 1) / 26))
second_digit <- ((number - 1) %% 26) + 1
first_letter <- LETTERS[[first_digit]]
second_letter <- LETTERS[[second_digit]]
return(paste0(first_letter, second_letter))
}
}
Run Code Online (Sandbox Code Playgroud)
有谁对我如何最轻松地改进此函数以处理任何正整数(或至少更多)有建议?
以下是一些替代方案:
1) 编码设 b 为基数。这里 b = 26。那么有 b^k 个具有 k 个字母的附录,因此对于具有数字 x 的特定附录,如果 n 是 b + b^2 + ... + b^n >= 的最小整数,则它有 n 个字母X。该不等式的 LHS 是一个几何级数,因此具有封闭形式的解。用该表达式替换 LHS 并求解 n 的结果方程,给出下面代码中 n 的公式。然后,我们从 k < n 的数字中减去所有 b^k 项,并使用此处(以及网络上其他地方)encode找到的类似 APL 的函数。进行基数转换,给出, 基数中的数字向量。最后给每个数字加 1 并将其用作 的查找。encodedigitsbaseLETTERS
app2 <- function(number, base = 26) {
n <- ceiling(log((1/(1 - base) - 1 - number) * (1 - base), base = base)) - 1
digits <- encode(number - sum(base^seq(0, n-1)), rep(base, n))
paste(LETTERS[digits + 1], collapse = "")
}
sapply(1:29, app2) # test
Run Code Online (Sandbox Code Playgroud)
给予:
[1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O"
[16] "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z" "AA" "AB" "AC"
Run Code Online (Sandbox Code Playgroud)
另一个要尝试的测试是:
sapply(1:60, app2, base = 3)
Run Code Online (Sandbox Code Playgroud)
2) 递归解决方案这是一种递归解决方案。它计算附录编号的最后一个字母,然后将其删除并递归计算其左侧的部分。
app2r <- function(number, base = 26, suffix = "") {
number1 <- number - 1
last_digit <- number1 %% base
rest <- number1 %/% base
suffix <- paste0(LETTERS[last_digit + 1], suffix)
if (rest > 0) Recall(rest, base, suffix) else suffix
}
# tests
identical(sapply(1:29, app2r), sapply(1:29, app2))
## [1] TRUE
identical(sapply(1:60, app2r, base = 3), sapply(1:60, app2, base = 3))
## [1] TRUE
Run Code Online (Sandbox Code Playgroud)