All possible combinations of selected character substitution in a string in ruby

允我心安 提交于 2019-12-29 07:14:16

问题


I was wondering if there is a simple way to do every combination of selected character substitutions in ruby in a simple way.

An example:

    string = "this is a test"
    subs = ['a'=>'@','i'=>'!','s'=>'$']
    subs.combination.each { |c|
        string.gsub c
    }

would yield

    "this is @ test"
    "th!s !s a test"
    "thi$ i$ a te$t"
    "th!s !s @ test"
    "thi$ i$ @ te$t"
    "th!$ !$ a te$t"
    "th!$ !$ @ te$t"

Thanks for the help!


回答1:


string = "this is a test"
subs = ['a'=>'@','i'=>'!','s'=>'$']

subs = subs.first.map(&:to_a)
1.upto(subs.length).each do |n|
  subs.combination(n).each do |a|
    p a.each_with_object(string.dup){|pair, s| s.gsub!(*pair)}
  end
end



回答2:


I'd do as below :

string = "this is a test"
subs = {'a'=>'@','i'=>'!','s'=>'$'}

keys = subs.keys
combinations = 1.upto(subs.size).flat_map { |i| keys.combination(i).to_a }

combinations.each do |ary|
  new_string = string.dup
  ary.each { |c| new_string.gsub!(c,subs) }
  puts new_string
end

output

this is @ test
th!s !s a test
thi$ i$ a te$t
th!s !s @ test
thi$ i$ @ te$t
th!$ !$ a te$t
th!$ !$ @ te$t



回答3:


I'd do as follows using String#gsub(pattern, hash) :

string = "this is a test"
subs = {'a'=>'@','i'=>'!','s'=>'$'} # copied from @ArupRakshit
keys = subs.keys

And core code:

1.upto(keys.length).flat_map { |i| 
  keys.combination(i).flat_map { |c| string.gsub(/[#{c.join}]/, subs) } 
}

Output:

=> ["this is @ test",
 "th!s !s a test",
 "thi$ i$ a te$t",
 "th!s !s @ test",
 "thi$ i$ @ te$t",
 "th!$ !$ a te$t",
 "th!$ !$ @ te$t"]



回答4:


Another way:

string = "this is a test"
subs   = [{"a"=>"@"}, {"i"=>"!"}, {"s"=>"$"}]

subs.repeated_combination(subs.size)
    .map {|e| string.gsub(/./) {|c| (g = e.find {|h| h.key?(c)}) ? g[c] : c}}
    .uniq
  #=> ["this is @ test", "th!s !s @ test", "thi$ i$ @ te$t", "th!$ !$ @ te$t",
  #    "th!s !s a test", "th!$ !$ a te$t", thi$ i$ a te$t"]

Explanation:

a = subs.repeated_combination(subs.size)
  # Enumerator...
  a.to_a 
  # [[{"a"=>"@"},{"a"=>"@"},{"a"=>"@"}], [{"a"=>"@"},{"a"=>"@"},{"i"=>"!"}],
  #  [{"a"=>"@"},{"a"=>"@"},{"s"=>"$"}], [{"a"=>"@"},{"i"=>"!"},{"i"=>"!"}],
  #  [{"a"=>"@"},{"i"=>"!"},{"s"=>"$"}], [{"a"=>"@"},{"s"=>"$"},{"s"=>"$"}],
  #  [{"i"=>"!"},{"i"=>"!"},{"i"=>"!"}], [{"i"=>"!"},{"i"=>"!"},{"s"=>"$"}],
  #  [{"i"=>"!"},{"s"=>"$"},{"s"=>"$"}], [{"s"=>"$"},{"s"=>"$"},{"s"=>"$"}]]

b = a.map {|e| string.gsub(/./) {|c| (g = e.find {|h| h.key?(c)}) ? g[c] : c}}
  #=> ["this is @ test", "th!s !s @ test", "thi$ i$ @ te$t", "th!s !s @ test",
  #    "th!$ !$ @ te$t", "thi$ i$ @ te$t", "th!s !s a test", "th!$ !$ a te$t",
  #    "th!$ !$ a te$t", "thi$ i$ a te$t"]

To see how b is computed, consider the second element of a that is passed to the block:

    e = [{"a"=>"@"},{"a"=>"@"},{"i"=>"!"}]

Because of the regex, /./, gsub passes each character c of string to the block

    {|c| (g = e.find {|h| h.key?(c)}) ? g[c] : c}

A search is made of e to determine if any of the three hashes has c as a key. If one is found, namely, g, the character c is replaced with g[c]; else, the character is left unchanged.

Notice that the first two elements of e are the same. Efficiency could be improved by changing the first line to:

    subs.repeated_combination(subs.size).map(&:uniq)

but efficiency is not one of the virtues of this approach.

Returning to the main calculation, the final step is:

b.uniq
  #=> ["this is @ test", "th!s !s @ test", "thi$ i$ @ te$t", "th!$ !$ @ te$t",
  #    "th!s !s a test", "th!$ !$ a te$t", "thi$ i$ a te$t"]



回答5:


A one-line functional solution

string = "this is a test"
subs = {'a'=>'@','i'=>'!','s'=>'$'}

(1..subs.size).flat_map { |n| subs.keys.combination(n).to_a }.map { |c| string.gsub(/[#{c.join}]/, subs) }
# => ["this is @ test", "th!s !s a test", "thi$ i$ a te$t", "th!s !s @ test", "thi$ i$ @ te$t", "th!$ !$ a te$t", "th!$ !$ @ te$t"]


来源:https://stackoverflow.com/questions/22067184/all-possible-combinations-of-selected-character-substitution-in-a-string-in-ruby

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