【问题标题】:Find all upper, lower and mixed case combinations of a string查找字符串的所有大写、小写和混合大小写组合
【发布时间】:2012-06-21 18:22:30
【问题描述】:

我想写一个程序接受一个字符串,比如说"Fox",然后它会显示:

fox, Fox, fOx, foX, FOx, FoX, fOX, FOX

到目前为止我的代码:

string = raw_input("Enter String: ")
length = len(string)
for i in range(0, length):
    for j in range(0, length):
        if i == j:
            x = string.replace(string[i], string[i].upper())
            print x

目前的输出:

Enter String: fox
Fox
fOx
foX
>>> 

【问题讨论】:

  • 你可以为此使用库函数吗?
  • @thg:他没有说这是作业,所以显然他想要最优雅的解决方案(可能涉及itertools;)
  • 我实际上查看了 itertools 模型..但这给出了一个排列,我在 stackoverflow 的其他帖子中看到了它......但我需要在这里输出所有可能的大写字母和小写组合。
  • 这个问题几乎是重复的:stackoverflow.com/questions/6792803/… 但是,这里的答案比另一个答案要好得多,所以我很高兴有人问了这个问题! itertools 为胜利。
  • 这能回答你的问题吗? Finding all possible case permutations in Python

标签: python string


【解决方案1】:
import itertools

s = 'Fox'
map(''.join, itertools.product(*zip(s.upper(), s.lower())))
>>> ['FOX', 'FOx', 'FoX', 'Fox', 'fOX', 'fOx', 'foX', 'fox']

【讨论】:

  • 这也不错..简单的解决方案..谢谢大家:)
  • @NiklasB。也许吧,但是对于那些不熟悉每个元素的作用的人来说,这并没有使阅读变得更容易。
  • @Marcin:请随意添加解释。但是,我怀疑它是否会包含比所涉及功能的文档已经包含的内容更具启发性的信息。
  • @Marcin:不,你可能知道,我经常回答 Python 问题,如果我觉得有必要,我也会添加有用的解释。到目前为止,没有人抱怨。通常人们需要的是必要的工具。通过在这个出色的答案中提供单线,人们可以通过检查解决方案的作用来了解如何使用这些工具来实现目标。他们需要做的研究来理解解决方案是一种非常好的学习体验。当然,如果他们有不明白的地方,他们总是可以回来要求解释。
  • @Marcin:我不同意。对于像我这样通常回答问题的人来说,这一定很有趣。对于学习一门新编程语言的人来说,它必须既有趣又有教育意义。我觉得探索新的语言结构很有趣,所以有时我不想破坏这种体验。但这只是我个人的观点和对 SO 的看法,我觉得其他人不一样。同样,SO 是协作的,因此如果您认为有必要,您应该添加解释。
【解决方案2】:

我一直想试试这个。

不知道这是否符合你的资格(虽然它确实有效)。

str = raw_input()

def getBit(num, bit):
   return (num & 1 << bit) != 0

for i in xrange(0,2**len(str)):
   out = ""
   for bit in xrange(0,len(str)):
      if getBit(i,bit):
         out += str[bit].upper()
      else:
         out += str[bit].lower()

   print(out)

这个想法是,当你以二进制递增时,你会得到 1 和 0 的所有可能排列。

然后你只需将这个 1 和 0 的列表转换为字符串,1 表示大写,0 表示小写。

【讨论】:

    【解决方案3】:

    这是@ephemient 的优秀、公认的答案,稍作修改。

    变化:

    • 小写在大写之前,所以列表以“fox”而不是“FOX”开头(问题的示例序列以“fox”开头)

    • 使用列表推导而不是 map()(无论哪种方式都可以,真的)

    • 分解生成小写/大写对的代码,使其更清晰

    • 将其打包成一个函数。

    代码:

    import itertools as it
    
    def cap_permutations(s):
        lu_sequence = ((c.lower(), c.upper()) for c in s)
        return [''.join(x) for x in it.product(*lu_sequence)]
    

    【讨论】:

    • 对这个答案不够尊重。感谢您发布它。
    【解决方案4】:

    使用列表理解的一个衬线:

    from itertools import permutations
    
    strs='fox'
    combin=[''.join(x) for x in permutations(list(strs)+list(strs.upper()),3) if ''.join(x).lower()=='fox']
    print(combin)
    >>> ['fox', 'foX', 'fOx', 'fOX', 'Fox', 'FoX', 'FOx', 'FOX']
    

    使用 for 循环:

    from itertools import permutations
    
    strs='fox'
    lis2=list(strs)+list(strs.upper())
    
    for x in permutations(lis2,3):
        if ''.join(x).lower()=='fox':
            print(''.join(x))
    
    >>> fox
        foX
        fOx
        fOX
        Fox
        FoX
        FOx
        FOX
    

    【讨论】:

      【解决方案5】:

      使用 product (False, True) 查找字符串中更改字符的任何排列方式:

      def capitalize_char_permutation (string:str) -> str :
          conditions = product((0,1), repeat=len(string))
          for i in conditions:
              result = ''
              for j in range(len(i)):
                  if i[j]==0 :
                      result+= string[j].lower()
                  else:
                      result+= string[j].upper()
              yield result
      

      【讨论】:

        【解决方案6】:

        虽然我尝试的是 C++,但我想你会明白其中的逻辑。我被困在同一个问题上,所以我四处搜索,这就是我最终写的......我知道它并不完美,如果有人帮助我改进这段代码并指出我的错误,我会很高兴。

        #include <bits/stdc++.h>
        
        using namespace std;
        
        string decToBinary(int n,int l) 
        { 
            string ret="";
            for (int i = l-1; i >= 0; i--) { 
                int k = n >> i; 
                if (k & 1) 
                    ret=ret+"1"; 
                else
                    ret=ret+"0";
            }
            return ret; 
        }
        
        int main()
        {
            string x;
            cin>>x;
            transform(x.begin(), x.end(), x.begin(), ::tolower); 
            int size=x.length();
            string bin;
            for(int i=0;i<pow(2,size);i++)
            {
                bin=decToBinary(i,size);
                for(int j=0;j<size;j++)
                {
                    if(bin[j]=='1')
                        cout<<(char)(x[j]-32);
                    else
                        cout<<x[j];
                }
                cout<<endl;
            }
        }
        

        假设“狗”这个词……那么,将有 2^(字母数),即 2^3=8 组合。因此,在这个程序中,我们从 0 到 7 进行迭代,并将迭代器(在本例中为 i)转换为二进制,例如,第五次迭代二进制为 101,则结果单词为 DoG(以 1 为大写和 0 作为小写)..这样你可以得到所有 2^n 结果词。

        【讨论】:

          【解决方案7】:

          我结合了@ephemient's solution@steveha's solution 和我自己的调整。

          def allcasecombinations(s):
              return list({''.join(x) for x in itertools.product(*zip(s.upper(), s.lower()))})
          

          我的改进是使用集合,然后将其转换为列表。设置是删除重复项:例如,如果您的字符串有标点符号,则原始函数将有重复项(因为" ".upper() == " ".lower())。我合并了@steveha 的工作,因为我认为在集合中使用列表理解比list(set(map(itertoolsmagic))) 更干净。大多数用例可能不需要列表转换,但为了安全起见,我添加了它。

          >>> allcasecombinations("hi!")
          ['HI!', 'hI!', 'Hi!', 'hi!']
          

          【讨论】:

            猜你喜欢
            • 2015-03-15
            • 2012-01-03
            • 2017-11-27
            • 2012-07-20
            • 2011-01-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多