问题如下:
如果我每生成100个包含小写,大写,数字,标点符号长度为8的字符串,小写字符占70%,大写字符占20%,数字占5%,标点符号占5%。另外这些字符都是随机取得的。这个问题困惑我很久,希望有人能帮我想出合适的算法,谢谢。

解决方案 »

  1.   

    笨方法:
    先从小写字符里面选70次得到70个小写字符
    然后是30个大写字符
    其他依次类推然后得到100个字符之后,打乱他们的顺序就可以了聪明办法:
    取一个随机数0<value<1
    if(value<0.7)
        随机取一个小写字符
    if(0.7<value<0.9)
        随机取一个大写字符
    依次类推
      

  2.   

    在Java中所有字符都以16bit的16进制的unicode编码识别,例如 \u0345 。
    不同的字符类型占用不同的连续编码段。所以:1.找到小写字母段的首末码,首码就是偏移量
    2.找到大写字母段的首末码,首码就是偏移量
    3.找到数字字符段的首末码,首码就是偏移量
    4.找到标点字符段的首末码,首码就是偏移量各码段偏移量都找到了,那么就可以随机取字符了初始化一个字符数组,长度为1001.从小写字母段随机取70个字符填充到数组[00-69]
    2.从大写字母段随机取20个字符填充到数组[70-89]
    3.从数字字符段随机取05个字符填充到数组[90-94]
    4.从数字字符段随机取05个字符填充到数组[95-99]对数组进行“洗牌”,洗牌完毕就是你要的结果了。
      

  3.   

    faint,居然jFresH_MaN已经回复了我都不知道。。btw,洗牌算法就不说了,随便找一本“数据结构与算法”的书籍都有讲
      

  4.   

    To JF,
    聪明办法:
    取一个随机数0<value<1
    if(value<0.7)
    随机取一个小写字符
    if(0.7<value<0.9)
    随机取一个大写字符
    依次类推我测试了一下,
    for(int i=0;i<10;i++){
          System.out.println(Math.random());
    }
    似乎并不能保证每次value<0.7的数量都在7 左右
      

  5.   

    似乎并不能保证每次value<0.7的数量都在7 左右
    =====
    那是肯定的,因为随机数虽然说是在0,1上均匀分布的,但是得到10个随机数肯定保证均匀分布在0,1上
    所以如果说你的要求是70%这样精确的结果,那使用笨方法好了
      

  6.   

    import java.util.*;public class Cryptogram2 {
    private static final char upper[] = 
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
    private static final char lower[] = 
    new String(upper).toLowerCase().toCharArray();
    private static final char digit[] = 
    "0123456789".toCharArray();
    private static final char interp[] =
    ",.;':\"`".toCharArray();

    private double upperRatio = 0.7;
    private double lowerRatio = 0.2;
    private double digitRatio = 0.05;
    private double interpRatio = 0.05;

    private int total = 100;
    private int length = 8;

    private Collection<String> result;

    public Cryptogram2(){
    result = new ArrayList<String>();
    int upperNum = (int)(total*length*upperRatio);
    int lowerNum = (int)(total*length*lowerRatio);
    int digitNum = (int)(total*length*digitRatio);
    int interpNum = (int)(total*length*interpRatio);

    String wholeStr = new String();
    wholeStr += generate(upper,upperNum);
    wholeStr += generate(lower,lowerNum);
    wholeStr += generate(digit,digitNum);
    wholeStr += generate(interp,interpNum);

    //System.out.println(wholeStr.length());
    split(wholeStr.toCharArray());
    }


    public String generate(char[] src, int num){
    String tmp = new String();
    Random rnd = new Random();
    for(int i=0; i<num; i++){
    tmp += src[rnd.nextInt(src.length)];
    }

    return tmp;
    }

    public void split(char[] str){
    for(int i=0; i<100; i++){
    String tmp = new String();
    Random rnd = new Random();
    while(tmp.length()<8){
    int index = rnd.nextInt(str.length);
    char c = str[index];
    if( c != '$'){
    tmp += c;
    str[index] = '$';
    }
    }

    result.add(tmp);
    }
    }

    public Collection getResult(){
    return result;
    }

    public static void main(String[] args){
    System.out.println(new Cryptogram2().getResult());
    }


    }