0

我很抱歉标题有点混乱,我不确定如何表达它。

我需要创建一个 char 数组,以允许字符集的所有可能排列。

如果我给你:

char[] charSet = {"a", "b", "c"};
BigInteger value = n; //where n is a number >= 0
char[] charArray = createCharArray(value, charSet);

如何从 value 和 charSet 创建 charArray ,这样如果我运行:

createCharArray(new BigInteger("6"), {"a", "b", "c"});

它会返回 {"a", "c"} 因为

  • a=1
  • b=2
  • c=3
  • aa=4
  • ab=5
  • ac=6

这是我到目前为止所拥有的:

private char[] createCharArray(BigInteger value, char[] charSet){
    List<Character> charArray = new ArrayList<Character>();

    if (value.compareTo(this.max) == 0)
        System.out.println("");

    BigInteger csSize = new BigInteger(String.valueOf(charSet.length));

    if(this.powers.isEmpty())
        this.powers.add(0, csSize.pow(0));
    if(this.sumPowers.isEmpty())
        this.sumPowers.add(0, csSize.pow(0));

    BigInteger curPow;
    int i = 1;


    while((curPow = csSize.pow(i)).compareTo(value) <= -1){
        if(this.powers.size() <= i)
            this.powers.add(i, curPow);

        if(this.sumPowers.size() <= i)
            this.sumPowers.add(i, this.sumPowers.get(i-1).add(curPow)); 

        i += 1;
    }

    i -= 1;


    while (i >= 0 && value.compareTo(BigInteger.ZERO) >= 0){
        if (i <= 1){
            int charNum = value.divide(this.sumPowers.get(0)).intValue() - 1;
            charArray.add(charSet[charNum]);
        }
        else{
            int charNum = value.divide(this.sumPowers.get(i-1).subtract(BigInteger.ONE)).intValue() - 1;
            charArray.add(charSet[charNum]);
        }
        value = value.subtract(this.powers.get(i));
        i -= 1;
    }

    char[] returnArray = new char[charArray.size()];

    int j = 0;

    while(j<charArray.size()){
        returnArray[j] = charArray.get(j);
        j += 1;
    }


    return returnArray;
}

它当然可以使用一些帮助,因为值 0 失败,值 1 和 2 成功,3-8 失败,9、10 成功,等等。

编辑:要清楚,值参数必须能够是任何数字 n > 0。这就是我选择 BigInteger 的原因

4

2 回答 2

0

创建一个有两个字段的类:

private char letter;
private int value;
public <classname>(char letter){
this.letter = letter;
value = 0;
}
//Setters and getters

然后在初始化数组时(通过for循环)将值设置为i + 1(摆脱0)

for(int i = 0; i < <yourarray>.length; i ++){
    //Assuming you initialized your objects before
    <yourarray>[i].<setterforvalue>(i + 1);
}

然后一起计算它们:

for(int i = 0; i < <yourarray>.length; i ++){
    for(int j = 0; j < <yourarray>.length; j ++){
     if(<yourarray>[i] + <yourarray>[j] == <needednumber>){
       //Do what you need to do with the value
     }
   }
}
于 2012-12-13T17:46:13.437 回答
0

好的,经过深思熟虑,最终将其分解为使用数字 0-9 而不是字符。以下是细分:想想常规的以 10 为基数的数字是如何创建的。

数字 194 由个列中的 4、十位中的 9 和百位中的 1 组成。个、十和百之间的差异是乘/除以 10,这是基数。

所以我想我可以通过基数(10)修改 194 以获得 4 个。然后除以 10 以删除那些列。再次 mod 得到 9,然后除以 10,再次 mod 得到 1,除以 10。一旦除法创建一个正好为 0 的数字,我们就完成了。这是因为我们无法创建数字 000194。

对于我的函数,我的基数是字符集的长度,在上面的例子中这个值是 194。

private static void createCharArray(BigInteger value, char[] charSet){
    List<Character> charArray = new ArrayList<Character>();

    BigInteger csSize = BigInteger.valueOf(charSet.length);

    if (value.compareTo(BigInteger.ZERO) == 0)
        charArray.add(0, charSet [0]);
    else{
        BigInteger modded = value.mod(csSize);
        BigInteger digit  = value.divide(csSize);

        while (modded.compareTo(BigInteger.ZERO) != 0 || digit.compareTo(BigInteger.ZERO) != 0){
            if(modded.compareTo(BigInteger.ZERO) == 0){
                charArray.add(0, charSet[csSize.subtract(BigInteger.ONE).intValue()]);
                value = value.subtract(BigInteger.ONE);
            }
            else
                charArray.add(0, charSet[modded.subtract(BigInteger.ONE).intValue()]);
            value = value.divide(csSize);

            modded = value.mod(csSize);
            digit  = value.divide(csSize);
        }
    }

    for(char c : charArray)
        System.out.print(c);
    System.out.println();


}

public static void main(String[] args) {
    long start = System.nanoTime();
    String characters = "";
    characters += "0123456789";
    characters += "abcdefghijklmnopqrstuvwxyz";
    characters += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    characters += " !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~";

    char[] cs = characters.toCharArray();
    Arrays.sort(cs);

    createCharArray(new BigInteger("1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"), cs);
    long total = System.nanoTime() - start;
    System.out.println("Completed in: " + total + " billionths of a second");
    System.out.println("Completed in: " + total/1000000 + " thousandth(s) of a second");
}  

如果您运行它,请注意 BigInteger 底部的 4 行是 100 个字符长。在我的机器上,它只需要 1/1000 秒(1 毫秒)。

于 2012-12-14T04:23:56.667 回答