8

我有一个字符串“abc”。置换字符串的程序(如果可能,在 Java 中)会是什么样子?

例如:

abc
ABC
Abc
aBc
abC
ABc
abC
AbC
4

6 回答 6

14

这样的事情应该可以解决问题:

void printPermutations(String text) {
  char[] chars = text.toCharArray();
  for (int i = 0, n = (int) Math.pow(2, chars.length); i < n; i++) {
    char[] permutation = new char[chars.length];
    for (int j =0; j < chars.length; j++) {
      permutation[j] = (isBitSet(i, j)) ? Character.toUpperCase(chars[j]) : chars[j];
    }
    System.out.println(permutation);
  }
}

boolean isBitSet(int n, int offset) {
  return (n >> offset & 1) != 0;
}
于 2011-07-22T04:24:43.503 回答
10

您可能已经知道,可能的不同组合的数量是 2^ n,其中n等于输入字符串的长度。

由于n理论上可能相当大,因此 2^ n有可能超过原始类型(例如int )的容量。(用户可能需要等待几年才能完成所有组合的打印,但这是他们的事。)

相反,让我们使用位向量来保存所有可能的组合。我们将设置位数等于n并将它们全部初始化为 1。例如,如果输入字符串是“abcdefghij”,则初始位向量值将是 {1111111111}。

对于每种组合,我们只需遍历输入字符串中的所有字符,如果对应位为 1,则将每个字符设置为大写,否则将其设置为小写。然后我们减少位向量并重复。

例如,输入“abc”的过程如下所示:

位:对应组合:
111 ABC
110 ABc
101 AbC
100 Abc
011 aBC
010 aBc
001 abC
000 abc

通过使用循环而不是递归函数调用,我们还避免了在大输入字符串上发生堆栈溢出异常的可能性。

这是实际的实现:

import java.util.BitSet;

public void PrintCombinations(String input) {
    char[] currentCombo = input.toCharArray();

    // Create a bit vector the same length as the input, and set all of the bits to 1
    BitSet bv = new BitSet(input.length());
    bv.set(0, currentCombo.length);

    // While the bit vector still has some bits set
    while(!bv.isEmpty()) {
        // Loop through the array of characters and set each one to uppercase or lowercase, 
        // depending on whether its corresponding bit is set
        for(int i = 0; i < currentCombo.length; ++i) {
            if(bv.get(i)) // If the bit is set
                currentCombo[i] = Character.toUpperCase(currentCombo[i]);
            else
                currentCombo[i] = Character.toLowerCase(currentCombo[i]);
        }

        // Print the current combination
        System.out.println(currentCombo);

        // Decrement the bit vector
        DecrementBitVector(bv, currentCombo.length);            
    }

    // Now the bit vector contains all zeroes, which corresponds to all of the letters being lowercase.
    // Simply print the input as lowercase for the final combination
    System.out.println(input.toLowerCase());        
}


public void DecrementBitVector(BitSet bv, int numberOfBits) {
    int currentBit = numberOfBits - 1;          
    while(currentBit >= 0) {
        bv.flip(currentBit);

        // If the bit became a 0 when we flipped it, then we're done. 
        // Otherwise we have to continue flipping bits
        if(!bv.get(currentBit))
            break;
        currentBit--;
    }
}
于 2011-07-22T09:20:02.490 回答
6
String str = "Abc";
str = str.toLowerCase();
int numOfCombos = 1 << str.length();  

for (int i = 0; i < numOfCombos; i++) {

    char[] combinations = str.toCharArray();
    for (int j = 0; j < str.length(); j++) {

        if (((i >> j) & 1) == 1 ) {
            combinations[j] = Character.toUpperCase(str.charAt(j));
        }

    }
    System.out.println(new String(combinations));
}
于 2016-07-15T23:30:43.770 回答
1

你也可以使用回溯来解决这个问题:

public List<String> letterCasePermutation(String S) {
    List<String> result = new ArrayList<>();
    backtrack(0 , S, "", result);
    return result;
}

private void backtrack(int start, String s, String temp, List<String> result) {
    if(start >= s.length()) {
        result.add(temp);
        return;
    }
   
    
    char c = s.charAt(start);
    if(!Character.isAlphabetic(c)) {
        backtrack(start + 1, s, temp + c, result);
        return;
    }
    if(Character.isUpperCase(c)) {
        backtrack(start + 1, s, temp + c, result);
        c = Character.toLowerCase(c);
        backtrack(start + 1, s, temp + c, result);
    }
    else {
        backtrack(start + 1, s, temp + c, result);
        c = Character.toUpperCase(c);
        backtrack(start + 1, s, temp + c, result);
    }
}
于 2020-08-13T07:59:09.387 回答
0

请在此处找到上述代码片段:

public class StringPerm {
public static void main(String[] args) {
    String str = "abc";
    String[] f = permute(str);

    for (int x = 0; x < f.length; x++) {
        System.out.println(f[x]);
    }

}

public static String[] permute(String str) {
    String low = str.toLowerCase();
    String up = str.toUpperCase();

    char[] l = low.toCharArray();

    char u[] = up.toCharArray();

    String[] f = new String[10];
    f[0] = low;
    f[1] = up;
    int k = 2;

    char[] temp = new char[low.length()];

    for (int i = 0; i < l.length; i++) 
    {
        temp[i] = l[i]; 

        for (int j = 0; j < u.length; j++) 
        {
            if (i != j) {
                temp[j] = u[j];
            }
        }

        f[k] = new String(temp);
        k++;
    }

    for (int i = 0; i < u.length; i++) 
    {
        temp[i] = u[i];         

        for (int j = 0; j < l.length; j++) 
        {
            if (i != j) {
                temp[j] = l[j];
            }
        }

        f[k] = new String(temp);
        k++;
    }

    return f;
}

}

于 2011-07-22T04:29:35.270 回答
0

你可以做类似的事情

```

import java.util.*;
public class MyClass {
    public static void main(String args[]) {
        String n=(args[0]);
        HashSet<String>rs = new HashSet();
        helper(rs,n,0,n.length()-1);

        System.out.println(rs);
    }
    public static void helper(HashSet<String>rs,String res , int l, int n)
    {
        if(l>n)
        return;

        for(int i=l;i<=n;i++)
        {

            res=swap(res,i);
            rs.add(res);
            helper(rs,res,l+1,n);
            res=swap(res,i);
        }

    }
    public static String swap(String st,int i)
    {
        char c = st.charAt(i);

        char ch[]=st.toCharArray();
        if(Character.isUpperCase(c))
        {
            c=Character.toLowerCase(c);
        }
        else if(Character.isLowerCase(c))
        {
            c=Character.toUpperCase(c);
        }
        ch[i]=c;
        return new String(ch);
    }

}

```

于 2018-03-09T21:01:36.313 回答