• 软件
  • 看到一个有意思的题目:a~z,0:9,所有3位的密码组合

显然 这里要求可以重复的 .

比如取 aaa ,aab ,abb,aba,bbb 都是可以的

combn 是排列组合 ,不放回的取样.

弄个小点的样本说明问题

<br />
> combn(c('a','b','c','d','e'),3)<br />
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]<br />
[1,] "a"  "a"  "a"  "a"  "a"  "a"  "b"  "b"  "b"  "c"<br />
[2,] "b"  "b"  "b"  "c"  "c"  "d"  "c"  "c"  "d"  "d"<br />
[3,] "c"  "d"  "e"  "d"  "e"  "e"  "d"  "e"  "e"  "e"<br />
</p>

回复 第5楼 的 zjgslxh:

outer 函数:

<br />
function (X, Y, FUN = "*", ...)<br />
{<br />
    if (is.array(X)) {<br />
        dX <- dim(X)<br />
        nx <- dimnames(X)<br />
        no.nx <- is.null(nx)<br />
    }<br />
    else {<br />
        dX <- length(X)<br />
        no.nx <- is.null(names(X))<br />
        if (!no.nx)<br />
            nx <- list(names(X))<br />
    }<br />
    if (is.array(Y)) {<br />
        dY <- dim(Y)<br />
        ny <- dimnames(Y)<br />
        no.ny <- is.null(ny)<br />
    }<br />
    else {<br />
        dY <- length(Y)<br />
        no.ny <- is.null(names(Y))<br />
        if (!no.ny)<br />
            ny <- list(names(Y))<br />
    }<br />
    if (is.character(FUN) && FUN == "*") {<br />
        robj <- as.vector(X) %*% t(as.vector(Y))<br />
        dim(robj) <- c(dX, dY)<br />
    }<br />
    else {<br />
        FUN <- match.fun(FUN)<br />
        Y <- rep(Y, rep.int(length(X), length(Y)))<br />
        if (length(X))<br />
            X <- rep(X, times = ceiling(length(Y)/length(X)))<br />
        robj <- FUN(X, Y, ...)<br />
        dim(robj) <- c(dX, dY)<br />
    }<br />
    if (no.nx)<br />
        nx <- vector("list", length(dX))<br />
    else if (no.ny)<br />
        ny <- vector("list", length(dY))<br />
    if (!(no.nx && no.ny))<br />
        dimnames(robj) <- c(nx, ny)<br />
    robj<br />
}<br />
<bytecode: 0x07f2d728><br />
<environment: namespace:base><br />


不好意思,知识浅薄 我也看不粗来 它是不是向量化运算.
</p>

回复 第6楼 的 doctorjxd:

combn(rep(mystr,3), 3)会将重复的三个1,当成三个不同的字符处理。

题中要求的结果是36^3个,而combn(rep...)之后结果的个数为choose(36*3, 3)个。

x = c(letters, 0:9)
do.call(paste0, expand.grid(x, x, x))

回复 第9楼 的 namgalsip:

确实,会造成很多重复的。

还是肖版的方法简捷。

苹果楠童鞋 call然后拿来do 果然高端大气上档次!

回复 第12楼 的 zjgslxh:

买苹果吧,买了以后你也能写出来 [s:11]

回复 第13楼 的 肖楠:

[s:15]为什么我用苹果也写不出来……

回复 第14楼 的 yanlinlin82:[s:11]说明您不是用5s,果断换。[s:13]

回复 第14楼 的 yanlinlin82:

要用最新的顶配版,这样灵感才够足 [s:17]

回复 第10楼 的 肖楠:

大神的世界 好难懂 [s:12]

求解释 ,直接调用paste0 和do.call 调用 居然不一样:

<br />
> z<-expand.grid(c(1,2,3),c(1,2))<br />
> z<br />
  Var1 Var2<br />
1    1    1<br />
2    2    1<br />
3    3    1<br />
4    1    2<br />
5    2    2<br />
6    3    2<br />
> paste0(z)<br />
[1] "c(1, 2, 3, 1, 2, 3)" "c(1, 1, 1, 2, 2, 2)"<br />
> do.call(paste0,z)<br />
[1] "11" "21" "31" "12" "22" "32"<br />


另外 ,追问一句 outer函数 到底是向量化运算不?上面贴了代码 但我看不出来..
</p>

如果l=list(a=c(1:4),b=c(2:3))

那么第一个子表个数为4,第二个子表的个数为2,则对各子表按照下面这样来组合,应该怎么实现呢?

do.call(paste0, expand.grid(l[[1]], l[[1]], l[[1]], l[[1]] ))

do.call(paste0, expand.grid(l[[2]], l[[2]]))

回复 第17楼 的 simbabest:

do.call(paste0, z) 的目的是把列表中的值,分别作为参数,传递给目标函数。

相当于 paste0(z$Var1, z$Var2)

你直接paste0(z),那么就只有z一个参数。

怎么感觉这个情境跟我的两篇日志有关(肖帮主当时还帮我纠正了一个错误):

http://yihui.name/en/2013/01/find-out-available-usernames-with-r/

http://yihui.name/en/2012/08/stupid-iastate-password-rules/

回复 第20楼 的 谢益辉:哈哈,看了看,是的.上面的题目传说是网易2013年数据挖掘实习生的一道题目!

vec<-c(letters,seq(0,9,1))

com_matrix<-combn(36,3)

mima<-apply(com_matrix,2,function(x) print(paste(vec[x[1]],vec[x[2]],vec[x[3]],sep=",")))

rm(vec,com_matrix)

回复 第22楼 的 nuomin:这不是一个组合问题,是一个排列问题。