大写排列
我想编写一个 ruby 片段,它接受一个字符串并输出所有可能的大写排列。基本上,我有一个我记得的密码,但我不记得它是如何大写的。
到目前为止,我有以下内容:
def permute(str)
perms = Array.new
(2 ** str.size).times { perms << str }
perms.each_index do |i|
binary = i.to_s(2)
str_arr = perms[i].split(//)
bin_arr = binary.split(//)
while ( bin_arr.size < str_arr.size )
bin_arr.unshift('0')
end
bin_arr.each_index do |b|
str_arr[b].upcase! if bin_arr[b] == '1'
end
puts str_arr.to_s
end
end
这工作得很好,但我想知道是否有任何红宝石专家可以帮助我改进它,这样它就不必在带有数字的字符串上不必要地工作。
例如,字符串“tst1”生成:
tst1
tst1
tsT1
tsT1
tSt1
tSt1
tST1
tST1
Tst1
Tst1
TsT1
TsT1
TSt1
TSt1
TST1
TST1
我正在寻找的输出是:
tst1
tsT1
tSt1
tST1
Tst1
TsT1
TSt1
TST1
有什么想法吗?
I wanted to write a snippet of ruby that would take a string and output all possible permutations of capitalizations. Basically, I have a password that I remember, but I don't remember how it is capitalized.
I have the following so far:
def permute(str)
perms = Array.new
(2 ** str.size).times { perms << str }
perms.each_index do |i|
binary = i.to_s(2)
str_arr = perms[i].split(//)
bin_arr = binary.split(//)
while ( bin_arr.size < str_arr.size )
bin_arr.unshift('0')
end
bin_arr.each_index do |b|
str_arr[b].upcase! if bin_arr[b] == '1'
end
puts str_arr.to_s
end
end
This works well enough, but I was wondering if any rubyists out there could help me refine it so that it doesn't have to work needlessly on strings with numbers.
For example, the string "tst1" generates:
tst1
tst1
tsT1
tsT1
tSt1
tSt1
tST1
tST1
Tst1
Tst1
TsT1
TsT1
TSt1
TSt1
TST1
TST1
The output I'm looking for is:
tst1
tsT1
tSt1
tST1
Tst1
TsT1
TSt1
TST1
Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
这是一个将大学时代的“算法推导”课程(Dijkstra 方法)付诸实践的绝佳机会。这是“干净”版本
编辑:Dijkstra 教我们不要过早优化,所以我认为数组版本最好单独添加:-) :
并且使在额外的方法参数的帮助下,它转换成尾递归的速度非常快:
现在这实际上非常慢,但是尾递归允许简单地重写(自己看看)到优化版本:
这有多重要?好吧,为了好玩,让我们运行一些定时测试:
在我的机器上,这显示了差异:
速度的提高和性能优势从不平凡的字符串中变得可见; “tst1”在干净版本中运行得很快。因此,Dijkstra 是对的:不需要优化。但无论如何,这样做很有趣。
What a great opportunity to put my classes of "Derivation of algorithms", the Dijkstra method, back from the days of University into practice here. This is the 'clean' version
EDIT: Dijkstra taught us not to optimize prematurely, so I figured the Array-version would better be added separately :-) :
And to make it blazing fast one converts into tail recursion, with the help of an extra method argument:
Now this is actually very slow, but tail recursion allows for a simple re-write (see for yourself) into the optimized version:
How much does this matter? Well let's run some timed tests, for the fun of it:
On my machine this shows the difference:
The speed increase and performance benefits become visible from non-trivial strings; "tst1" will run fast in the clean version. Hence, Dijkstra was right: no need to optimize. Though it was just fun to do it anyway.
尝试 john the ripper、cain andable 或任何密码破解软件
try john the ripper, or cain and able, or any password cracking software
您应该创建另一个数组,而不是
put
,如果数组尚未包含它们,则只需将它们包含到数组中。然后在循环之后,用\n
或您喜欢的任何内容将它们连接起来。输出:
You should make another array and instead of
put
just include them into the array if it isn't already included in the array. Then after your loop, join them with a\n
or whatever you like.The Output:
还有另一种解决方案(谁能抗拒尝试呢?):
return ["tst1", "tsT1", "tSt1", "tST1", "Tst1", "TsT1", "TSt1", "TST1"]
Yet another solution (who can resist to try it?):
returns ["tst1", "tsT1", "tSt1", "tST1", "Tst1", "TsT1", "TSt1", "TST1"]
好吧,我不了解 ruby,所以我可能是错的,但在我看来,代码是有效的。只是因为您在进行大小写排列时没有考虑数字。数字一只有一个版本,因此大小写看起来相同。因此:“tst1”和“tst1”,“tsT1”和“tsT1”等等。
您是否尝试过使用“acb”的代码?这工作正常还是你遇到同样的问题?
Well, I don't know ruby so I may be wrong but it seems to me the code works. It's just that for you are not taking digits into account when you do the capitalization permutations. The digit one only has one version so the capitalization looks the same. Hence: "tst1" and "tst1", "tsT1" and "tsT1" and so forth..
Have you tried the code with "acb"? Does that work fine or do you get the same problem?
一种简单的方法可能是从字符串中删除数字,将结果传递给您已经编写的函数,然后将数字放回到同一索引处。
A simple approach may be to remove the numbers from the string, pass the results to the function you already wrote, and then put the numbers back in at the same index.
也许不是最优雅的解决方案,但您可以更改
为
循环后
Maybe not the most elegant solution but you could change
to
and after the loop
对原始程序进行轻微修改
Slight Mod to Original Program
像这样?
like this?