Ruby get permutations of all lengths from a string in order

风流意气都作罢 提交于 2019-12-31 05:50:27

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!