问题
Here's my code-
$arr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-"
def scan(f)
begin
if f.size == 6
exit
end
$arr.each_char do |y|
t = f + y
puts t
scan(t)
end
end
end
I wish to print all permutations and lengths upto 6, I've tried this recursive approach. The output I get is -
A
AA
AAA
AAAA
AAAAA
However I seek something like this-
A
AA
AB
AC
.
.
AZ
AAA
AAB
.
.
AAZ
.
.
upto 6 chars
On commenting the recursive call I see that it prints
AA
AB
AC
.
.
Which is fine without recursion but not with recursion. Any kinds of suggestions are appreciated. Thank you.
回答1:
Array#repeated_permutation can do the heavy lifting for you here:
$arr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-"
def scan
characters = $arr.chars
(1..6).each do |length|
characters.repeated_permutation(length) do |sequence|
t = sequence.join
puts t
end
end
end
Or as a more reusable enumerator:
CHARACTERS = [*"A".."Z", *"a".."z", *"0".."9", "_", "-"]
def each_permuted_string(max_length = 6, &block)
sequences = (1..max_length).map { |n| CHARACTERS.repeated_permutation(n) }
if block_given?
sequences.each { |seq| seq.lazy.map(&:join).each(&block) }
else
enum_for(__method__, max_length) { sequences.map(&:size).inject(:+) }
end
end
each_permuted_string do |t|
puts t
end
It's going to take a very long time, though -- there are each_permuted_string.size => 69810262080 values. This sounds like it could be an XY Problem, and you might get a better solution by asking a question about the higher-level problem you're solving.
回答2:
Since you're expecting A, AA, AAA, etc... to be included in the resulted list, then you might find the repeated_permutations method to be useful, because you need permutations with repetitions.
Unfortunately, the number of permutations is extremely large ($arr contains 64 symbols) and permutations with up to 6 chars must be calculated. The number of permutations is:
64^7 = 4_398_046_511_104
But still, here's an example of calculating permutations of up to 6 chars:
(1..6).to_a.flat_map { |i| $arr.chars.repeated_permutation(i).map(&:join) }
Which is even for 4 is quite slow, but it's up to you.
来源:https://stackoverflow.com/questions/51692230/ruby-get-permutations-of-all-lengths-from-a-string-in-order