一个20卷的一个模具在java中死亡

时间:2013-07-05 16:10:54

标签: java arrays arraylist

我正在进行一项练习,要求我打印20卷骰子并在括号中对重复的值进行分组。我的代码遵循我正在阅读的书中使用的伪代码。我能够将重复的值分组在括号中,但下一个练习要求我将括号中重复次数最多的值分组。

例如:

(333)51314121(22)326(55)14

将是:

(333)51314121223265514

编辑:如果有多个重复值的最大组,则只将第一组分组在括号中。

我怎样才能做到这一点?非常感谢您提供任何帮助。

public void run() {

    Random generator = new Random();
    ArrayList<Integer> a = new ArrayList<Integer>();

    for (int i = 0; i < 21; i++) {
        int die = generator.nextInt(6)+ 1;
        a.add(die);
    }

    for (int j = 0; j < a.size() - 1; j++) {
        if (inRun) {
             if (a.get(j) != a.get(j - 1)) {
                 System.out.print(")");
                 inRun = false;
             }

        }
        else {
            if (a.get(j) == a.get(j + 1)) {
                System.out.print("(");
                inRun = true;
            }
        }
        System.out.print(a.get(j));

    }
    if (inRun) {
        System.out.print(")");
    }

}

3 个答案:

答案 0 :(得分:1)

除了普通数组之外,你真的不需要数据结构。

您可以在插入时检查 O(n)

  • 如果添加的数字等于上一个,则会增加序列计数 - 如果没有,则重置计数。
  • 当您递增序列计数时,检查它是否大于已存储的最大序列计数长度 - 如果它更大,则当前序列计数 变为 最大序列数

检查代码 - 有些评论可以帮助理解(run demo online here):

public void run() {
    Random generator = new Random();
    int[] a = new int[20];

    int biggerSequence = 1;         // starts pointing to the first char
    int biggerSequenceEndIndex = 1; // starts pointing to the first char
    int currentSequence = 1;
    int previous = -1;
    for (int i = 0; i < 20; i++) {
        int die = generator.nextInt(6)+ 1;
        a[i] = die;
        if (die == previous) { // if inserted equals previous
            currentSequence++; // increment sequence
            if (currentSequence > biggerSequence) { // if it is bigger than max
                biggerSequence = currentSequence; // max becomes it
                biggerSequenceEndIndex = i+1;
            }
        } else {
            previous = die;
            currentSequence = 1; // reset the count
        }
    }

    for (int i = 0; i < a.length; i++) {
       if (i == biggerSequenceEndIndex-biggerSequence) { System.out.print("("); }
       System.out.print(a[i]);
       if (i+1 == biggerSequenceEndIndex) { System.out.print(")"); }
    }
}

示例输出:

(1)2345678901234567890
(11)345678901234567890
1(22)45678901234567890
1(22)45578901234567890
123456789012345678(99)
54(3333)43514564513551

答案 1 :(得分:0)

只需尝试存储从任何给定索引开始的重复值的数量。类似的东西:

public void run(){

    Random generator = new Random();
    ArrayList<Integer> a = new ArrayList<Integer>();

    for (int i = 0; i < 21; i++) {//Generate your numbers
        int die = generator.nextInt(6)+ 1;
        a.add(die);
    }

    //store the number of repeats by index. (index is key, # of repeats is key)
    HashMap<Integer, Integer> repeats = new HashMap<Integer, Integer>();

    //This will find store the number of repeated numbers starting at any given index.
    int index = 0;
    repeats.put(index, 1);
    for(int i = 1; i < a.size(); i++){
        if(a.get(i) == a.get(index)){//Repeated values occurring
            repeats.put(index, repeats.get(index) + 1);
        } else {//End of a repeated sequence (even if that sequence was only 1 number long)
            repeats.put(i, 1);
            index = i;
        }
    }

    //Find the index at which the maximum number of repeats occurs
    int max = 0;
    int startIndex = 0;
    for(Integer i : repeats.keySet()){
        //If the number of repeats is bigger than anything seen before
        if(repeats.get(i) > max){
            //Store the number of repeats and the index at which they start
            max = repeats.get(i);
            startIndex = i;
        }
    }

    //print everything out
    for(int i = 0; i < a.size(); i++){
        if(i == startIndex)//Prints the open parenthesis before the repeats start
            System.out.print("(");
        System.out.print(a.get(i)); //Prints the number
        if(i == startIndex + max)
            System.out.print(")");//Prints the close parenthesis after the repeats end
    }
}

请注意,此算法假定最大大小只有1个重复序列。如果您想要保留多个,则必须将所有索引存储在另一个列表中。但这是解决方案的一个小修复,看起来像这样:

ArrayList<Integer> startIndeces = new ArrayList<Integer>();
int max = 0;
for(Integer i : repeats.keySet()){
    //If the number of repeats is bigger than anything seen before
    if(repeats.get(i) > max){
        //Store the number of repeats and the index at which they start
        max = repeats.get(i);
        startIndeces = new ArrayList<Integer>();
        startIndeces.add(i);
    } else if(repeats.get(i) == max)
        startIndeces.add(i);
}

否则算法会存储最长序列的第一个实例。

答案 2 :(得分:0)

您需要对数组进行多次传递。通过它一次,计算所有运行的时间。然后确定最大运行长度。最后,返回并打印出数组,将括号放在最大长度的运行周围。

尝试这样的事情(确切的实现留给你):

runContents = a list containing the first random number
runLength = [1], i.e. a one element list with the number 1 in it
maxLength = 1
for each subsequent random number you want to consider {
  if the last element of runContents == the next random number {
    add 1 to the last element of runLength
  } else {
    if maxLength < the last element of runLength {
      maxLength = the last element of runLength
    }
    append the random number to runContents
    append a 1 to runLength
  }
}

i = 0
while i < length(runContents) {
  if runLength[i] == maxLength {
    print runLength[i] copies of runContents[i] surrounded by parens
  } else {
    print runLength[i] copies of runContents[i]
  }
}