这样想的:8种情况:
Letter代表字母,Num代表数字:
1:LLL
2:LLN
3:LNL等等
<br />
Letter=letters<br />
Num=0:9<br />
LLL=outer(outer(Letter,Letter,"paste"),Letter,"paste")<br />
等等:<br />
NNN=outer(outer(Num,Num,"paste"),Num,"paste")<br />
算法有点暴力,期待更好的算法!
</p>
这样想的:8种情况:
Letter代表字母,Num代表数字:
1:LLL
2:LLN
3:LNL等等
<br />
Letter=letters<br />
Num=0:9<br />
LLL=outer(outer(Letter,Letter,"paste"),Letter,"paste")<br />
等等:<br />
NNN=outer(outer(Num,Num,"paste"),Num,"paste")<br />
<br />
result=array(NA,dim=c(36,36,36))<br />
str=c(letters,0:9)<br />
for(i in 1:36){<br />
for(j in 1:36){<br />
for(k in 1:36){<br />
result[i,j,k]=outer(outer(str[i],str[j],"paste"),str[k],"paste")<br />
}<br />
}<br />
}<br />
抱歉,1楼,2楼算法太过脑残:
<br />
str=c(letters,0:9)<br />
result=outer(outer(str,str,"paste"),str,"paste")<br />
</p>是的 要避免使用循环,尽可能使用R内置的向量化运算函数.outer应该就是.
如何把 result [36x36x36 的一个超大矩阵.] 按元素 取出来 按行写入到文本文件呢 ?
回复 第4楼 的 simbabest:outer应该不是向量化运算函数。至于怎样写入文本文件,还没有想到。
回复 第7楼 的 simbabest:
确实
另外,既然是生成密码,那么你的例子里面用paste0函数,比paste函数更好。
显然 这里要求可以重复的 .
比如取 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 />
回复 第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 />
如果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/