'Find all upper, lower and mixed case combinations of a string
I want to write a program that would take a string, let's say "Fox", then it would display:
fox, Fox, fOx, foX, FOx, FoX, fOX, FOX
My code so far:
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
Output so far:
Enter String: fox
Fox
fOx
foX
>>>
Solution 1:[1]
import itertools
s = 'Fox'
map(''.join, itertools.product(*zip(s.upper(), s.lower())))
>>> ['FOX', 'FOx', 'FoX', 'Fox', 'fOX', 'fOx', 'foX', 'fox']
Solution 2:[2]
I always wanted to try this.
No idea if this fits your qualifications(it does work though).
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)
The idea is that as you increment in binary, you get every possible permutation of 1s and 0s.
Then you simply convert this list of 1s and 0s to a string, 1 meaning uppercase, 0 meaning lowercase.
Solution 3:[3]
This is the excellent, accepted answer by @ephemient modified a little bit.
Changes:
lower-case before upper-case, just so the list starts with "fox" instead of "FOX" (the question's example sequence starts with "fox")
use of a list comprehension instead of
map()(either way is fine, really)broke out the code that generates the lower/upper case pairs to make it more clear
packaged it up into a function.
The code:
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)]
Solution 4:[4]
One liner using list comprehension:
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']
Using a for loop:
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
Solution 5:[5]
Use product (False, True) to find any permutations of change char in string for upper & lower:
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
Solution 6:[6]
Although what I tried is in c++, I guess you will get the logic. I was stuck in the same question so I searched around and this is what I ended up writing...I know it is not perfect and I would love if someone helps me make this code better and point out my mistakes.
#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;
}
}
Suppose the word "dog"...so, there will be 2^(number of letters) i.e. 2^3=8 combination. So, in this program, we iterate from 0-7 and convert the iterator(i in this case) to binary, for example, take the fifth iteration the binary would be 101 then the resultant word would be DoG (taking 1 as upper case and 0 as the lower case)..like this you can get all 2^n resultant words.
Solution 7:[7]
I combined @ephemient's solution, @steveha's solution, and my own tweak.
def allcasecombinations(s):
return list({''.join(x) for x in itertools.product(*zip(s.upper(), s.lower()))})
my improvement is using a set and then converting it to a list. the set is to remove duplicates: for example if your string had punctuation, the original function would have duplicates (because " ".upper() == " ".lower()). I incorporated @steveha's work cause I figured using list comprehension inside a set is cleaner than list(set(map(itertoolsmagic))). the list conversion probably isn't necessary for most use cases, but I added it to be safe.
>>> allcasecombinations("hi!")
['HI!', 'hI!', 'Hi!', 'hi!']
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | iacob |
| Solution 2 | |
| Solution 3 | steveha |
| Solution 4 | iacob |
| Solution 5 | iacob |
| Solution 6 | |
| Solution 7 | melody_florum |
