在一个测试运气(概率)程序中计算平均值。

3
我是一名学生,正在编写一个测试概率的程序。它叫做TestLuck,旨在生成用户确定数量的填充有随机值的IntArrayLogs(ADT's)。该程序应计算在匹配第一个值之前生成了多少个值。
实际问题: "创建应用程序TestLuck; 要求用户输入随机整数范围的上限(书上说是10,000,但您还应使用365进行测试),以及要运行测试的次数。 计算并输出平均值。"
这是我想出来的,但出现了错误的结果,我测试过我使用的方法似乎没问题,我认为这与我如何跟踪计数器有关。
for(int k=0; k<numTests; k++) {   
    for(int i=0; i<upperLimit; i++) {
        arrLog.insert(n);
        n = rand.nextInt(upperLimit);
        if(arrLog.contains(arrLog.getElement(0))) {
            totalCount += i;
            break;
        }
        if(i == upperLimit-1)
            totalCount +=i;
    }

    System.out.println("Total Count: " + totalCount);
    arrLog.clear();
}   
testAverage = totalCount/numTests;
System.out.println("Average tests before match: " + testAverage);

包含方法:

// Returns true if element is in this IntLog,
// otherwise returns false.
public boolean contains(int element) {                  
    int location = 0;
    int counter = 0;
    while (location <= lastIndex) {
        if (element == log[location]) {  // if they match
            counter++;
            location++;
            if(counter == 2)
                return true;
        } else
            location++;
    }
    return false;
}

2
嗨。要求别人在您的代码中发现错误并不特别有效。您应该使用调试器(或添加打印语句)来隔离问题,通过跟踪程序的进展并将其与您期望发生的情况进行比较。一旦两者分歧,那么您就找到了问题所在。(然后如果必要,您应该构建一个最小测试用例。) - Oliver Charlesworth
2个回答

1
你不需要一个contains()方法,因为这只会花费更多的时间来计算像比较这样简单的东西。
问题是在匹配第一个数字之前必须生成多少个数字,但你需要考虑是否包括第一个数字。例如:{1,2,3,4,1}计数=5,或者{1,2,3,4,1}计数=4。无论哪种方式,这都不会影响答案的逻辑:
如果你重新排列你的方法,它会运行得更快。
for(int k=0; k<numTests; k++){   
    for(int i=0; i<upperLimit; i++){
        arrLog.insert(n);
        if(arrLog.getElement(0) == n && i != 0){// i != 0 to prevent it from counting a match on the first iteration
            totalCount += i;//totalCount += i+1 if you are counting the first number
            break;
        }
        n = rand.nextInt(upperLimit);
    }
    System.out.println("Total Count: " + totalCount);
    arrLog.clear();
}   
testAverage = totalCount/numTests;
System.out.println("Average tests before match: " + testAverage);

如果您需要使用contains()方法,请在评论中告诉我,我将编辑答案。
我还建议不使用任何存储数据结构,在这种情况下是ADT的IntArrayLog (再次声明,我不知道您是否需要在课程中使用ADT);这样您的程序将运行得更快:
int firstNum;
for(int k=0; k<numTests; k++){
    firstNum = rand.nextInt(upperLimit);
    for(int i=1; i<upperLimit; i++){//notice this starts in 1
        n = rand.nextInt(upperLimit);
        if(firstNum == n){
            totalCount += i;//totalCount += i+1 if you are counting the first number
            break;
        }
    }
    System.out.println("Total Count: " + totalCount);
    arrLog.clear();
}   
testAverage = totalCount/numTests;
System.out.println("Average tests before match: " + testAverage);

我假设在循环开始前_n_已经被赋值了。另外,考虑用一个更大的数字替换_for_语句中的_upperLimit_,以防生成的随机数数量超过了_upperLimit_,尽管这种情况非常罕见,但确实可能发生。 - Memillopeloz

0

我在你的代码中发现一些奇怪的事情。

首先,在给 n 赋值之前,你将其插入到 arrLog 中。

其次,在 for 循环后测试 i == upperLimit-1 条件,然后再将计数器加1。只有当 for 循环在最后一步跳出时才会满足这个条件(这种情况下,你已经将计数器加2)。

第三,在 contains 方法中,如果找到了两次 element,你返回 true。根据我的理解,第一次应该是在位置 0(第一个元素),然后是自身的测试,但是你将第一个元素作为参数传递。你可能应该从位置 1 开始(跳过第一个元素)并且只计数一次:

for (location=1; location<=lastIndex; location++) {
    if (element = log[location]) return true;
}
return false;

不过,只需将narrLog.getElement(0)进行比较应该更容易。

附言:我假设其他所有内容都已正确初始化。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接