算法从java中的排列列表创建一个char数组

时间:2012-12-13 15:58:05

标签: java algorithm

我很抱歉略有混乱的标题,我不确定如何用它来表达。

我需要创建一个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>这就是我选择BigInteger

的原因

2 个答案:

答案 0 :(得分: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
     }
   }
}

答案 1 :(得分:0)

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

数字194由一列中的4,十位中的9和数百中的1组成。 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毫秒)。