Печать всех перестановок в верхнем регистре строки в нижнем регистре

#ruby #algorithm

#ruby #алгоритм

Вопрос:

Я пытаюсь распечатать все перестановки увеличенной версии строки в нижнем регистре в Ruby. Например:

исходная строка: aaa,

вывод:

aaa
aaA
aAa
aAA
AaA
AAa
AAA

Любая помощь или подсказки приветствуются.

Комментарии:

1. Пожалуйста, покажите нам код, который вы написали для решения этой проблемы. Исправить ваши ошибки намного проще, чем нам писать несколько версий, а вам вставлять их на место.

Ответ №1:

 str = 'aaa'

(0...1<<str.length).map { |i|
    str.chars.map.with_index { |a,b| ((i>>b)amp;1).zero? ? a : a.upcase }.join
}

# => aaa Aaa aAa AAa aaA AaA aAA AAA
  

Основная идея заключается в том, что будет 2 в степени n ( 2**n == 1<<n ) выходных строк, где n=str.length . Поэтому вы можете использовать индекс i от 0 до 2**n-1 в качестве битового поля, для которого буквы будут увеличены. Например.

 000 -> aaa
001 -> aaA
010 -> aAa
011 -> aAA
etc.
  

Комментарии:

1. Мэтт, (0...1<<str.length) это очень круто! Я постараюсь запомнить это для комбинаторных задач.

Ответ №2:

Вы можете использовать repeated_permutation , чтобы делать то, что хотите:

 %w(a A).repeated_permutation(3).map(amp;:join)
# => ["aaa", "aaA", "aAa", "aAA", "Aaa", "AaA", "AAa", "AAA"]
  

для произвольной строки вы можете создать перестановки вопроса, следует ли вводить букву в верхнем регистре или нет, что-то вроде:

 str = 'abcde'
chars = str.chars

[false, true].repeated_permutation(str.length).map do |permutation|
  chars.zip(permutation).map do |char, upcase|
    upcase ? char.upcase : char
  end.join
end

# => ["abcde", "abcdE", "abcDe", "abcDE", "abCde", "abCdE", "abCDe", "abCDE", 
#     "aBcde", "aBcdE", "aBcDe", "aBcDE", "aBCde", "aBCdE", "aBCDe", "aBCDE",
#     "Abcde", "AbcdE", "AbcDe", "AbcDE", "AbCde", "AbCdE", "AbCDe", "AbCDE",
#     "ABcde", "ABcdE", "ABcDe", "ABcDE", "ABCde", "ABCdE", "ABCDe", "ABCDE"]
  

Ответ №3:

Я предпочитаю решение @Uri для конкретного случая, но предложил бы это для произвольных строк строчных букв:

 str = "abad"

arr = str.chars.map { |c| [c,c.upcase] }
arr.shift.product(*arr).map(amp;:join)
  #=> ["abad", "abaD", "abAd", "abAD", "aBad", "aBaD", "aBAd", "aBAD",
  #    "Abad", "AbaD", "AbAd", "AbAD", "ABad", "ABaD", "ABAd", "ABAD"]
  

Комментарии:

1. @Casimar (он же гуру регулярных выражений?), Я пробовал это, но не мог видеть такой сжатый код.

2. Никому не говорите об этом, но я чувствую себя совершенно ошеломленным на этом сайте!