Java 随机数学生成算法不起作用

Java 随机数学生成算法不起作用,java,android,algorithm,random,Java,Android,Algorithm,Random,请注意,问题标题为: Random math question generation algorithm not working 因为我不能在问题标题中输入“问题” 因此,我正在编写一个android应用程序,通过向孩子们提问来帮助他们学习数学。他们可以随意更改位数和操作类型。我现在对我编写的生成随机问题的算法感到困惑。如果使用相同的问题选项,则每次都会生成相同的问题。关于问题选项 number of digits: 1 operation: + number of digits: 2 o

请注意,问题标题为:

Random math question generation algorithm not working
因为我不能在问题标题中输入“问题”


因此,我正在编写一个android应用程序,通过向孩子们提问来帮助他们学习数学。他们可以随意更改位数和操作类型。我现在对我编写的生成随机问题的算法感到困惑。如果使用相同的问题选项,则每次都会生成相同的问题。关于问题选项

number of digits: 1
operation: +
number of digits: 2
operation: +
number of digits: 3
operation: +
number of digits: 2
operation: +
它总是10+10

问题选项

number of digits: 1
operation: +
number of digits: 2
operation: +
number of digits: 3
operation: +
number of digits: 2
operation: +
它总是11+11

问题选项

number of digits: 1
operation: +
number of digits: 2
operation: +
number of digits: 3
operation: +
number of digits: 2
operation: +
它总是8+8

问题选项

number of digits: 1
operation: +
number of digits: 2
operation: +
number of digits: 3
operation: +
number of digits: 2
operation: +
它总是11+11

尽管其他操作类型(-,+/-,*)的随机性稍高,但其中一个操作数始终相同。1位是10,2位是11,3位是8

下面是我的算法:

public void generateAQuestion () {
    switch (options.getOperationType ()) {
        case ADDITION:
            current = generateAddition ();
            break;
        case SUBTRACTION:
            current = generateSubtraction ();
            break;
        case ADD_AND_SUB:
            current = generateAddAndSub ();
            break;
        case MULTIPLICATION:
            current = generateMultiplication ();;
            break;
    }
}

private int generateNumberWithDigitCount () {
    int minValue = 10 ^ (options.getDigitCount () - 1);
    int maxValue = 10 ^ options.getDigitCount () - 1;
    Random r = new Random ();
    return r.nextInt (maxValue - minValue + 1) + minValue;
}

private Question generateAddition () {
    int operand1, operand2;
    operand1 = generateNumberWithDigitCount ();
    operand2 = generateNumberWithDigitCount ();
    return new Question (operand1, operand2);
}

private Question generateSubtraction () {
    int operand1 = generateNumberWithDigitCount ();
    Random r = new Random ();
    int operand2 = -(r.nextInt (operand1));
    return new Question (operand1, operand2);
}

private Question generateAddAndSub () {
    Question firstPart;
    if (Math.random () > 0.5) {
        firstPart = generateAddition ();
    } else {
        firstPart = generateSubtraction ();
    }
    int[] operands = new int[3];
    operands[0] = firstPart.getOperands ()[0];
    operands[1] = firstPart.getOperands ()[1];

    if (Math.random () > 0.5) {
        Random r = new Random ();
        operands[2] = -(r.nextInt (firstPart.getAnswer ()));
    } else {
        operands[2] = generateNumberWithDigitCount ();
    }

    return new Question (operands);
}

private MultiplicationQuestion generateMultiplication () {
    return new MultiplicationQuestion (generateNumberWithDigitCount (), generateNumberWithDigitCount ());
}

private int[] generateAnswers (int correctAnswer) {
    int[] answers = new int[4];
    Random r = new Random ();
    int correctAnswerIndex = r.nextInt (4);
    answers[correctAnswerIndex] = correctAnswer;
    for (int i = 0 ; i < answers.length ; i++) {
        if (i == correctAnswerIndex) {
            continue;
        }

        if (Math.random () > 0.5) {
            answers[i] = correctAnswer + (i + 1);
        } else {
            int candidate = correctAnswer - (i + 1);
            if (candidate < 0) {
                candidate = correctAnswer + i + 5;
            }
            answers[i] = candidate;
        }
    }
    return answers;
}
public void generateAQuestion(){
开关(options.getOperationType()){
案例补充:
当前=生成条件();
打破
案例减法:
电流=发电机牵引力();
打破
案例添加_和_子:
当前=GeneratedAndSub();
打破
大小写乘法:
当前=generateMultiplication();;
打破
}
}
私有int generateNumberWithDigitCount(){
int minValue=10^(options.getDigitCount()-1);
int maxValue=10^options.getDigitCount()-1;
Random r=新的Random();
返回r.nextInt(maxValue-minValue+1)+minValue;
}
私有问题生成条件(){
整数操作数1,操作数2;
操作数1=generateNumberWithDigitCount();
操作数2=generateNumberWithDigitCount();
返回新问题(操作数1、操作数2);
}
私有问题生成subtraction(){
int operan1=generateNumberWithDigitCount();
Random r=新的Random();
整数操作数2=-(r.nextInt(操作数1));
返回新问题(操作数1、操作数2);
}
私人问题GeneratedAndSub(){
问题第一部分;
if(Math.random()>0.5){
第一部分=生成条件();
}否则{
第一部分=发电机牵引力();
}
int[]操作数=新的int[3];
操作数[0]=firstPart.getoperans()[0];
操作数[1]=firstPart.getoperans()[1];
if(Math.random()>0.5){
Random r=新的Random();
操作数[2]=-(r.nextInt(firstPart.getAnswer());
}否则{
操作数[2]=GenerateEnumberWithDigitCount();
}
返回新问题(操作数);
}
私有乘法问题生成乘法(){
返回新的乘法问题(GenerateEnumberWithDigitCount(),GenerateEnumberWithDigitCount());
}
私有int[]生成应答器(int correctAnswer){
int[]答案=新的int[4];
Random r=新的Random();
int correctAnswerIndex=r.nextInt(4);
答案[correctAnswerIndex]=正确答案;
for(int i=0;i0.5){
答案[i]=正确答案+(i+1);
}否则{
int候选者=正确答案-(i+1);
if(候选者<0){
候选人=正确答案+i+5;
}
答案[i]=候选人;
}
}
返回答案;
}
注意:
options
是问题选项,它的方法是自解释的,你可以得到它。不要关心
问题
乘法问题
的构造函数,它们是无关的


我不知道我做错了什么,一切对我都有意义。我做错了什么?

Random r=new Random()重新初始化生成器

这样做一次,而不是每次你需要一个数字。否则会破坏生成器的统计特性


然后将
minValue
maxValue
值分开,使它们具有不同的值,目前它们相等,并且可能由于误用XOR运算符而没有意义
^

这里的错误在于使用10^选项。获取。。。 这与power不同,您可以依次使用Math.pow(10,options.get…)

您遇到的问题是,^运算符在本例中不充当指数模:)

编辑代码

int minValue = (int)(Math.pow(10, (options.getDigitCount () - 1));
int maxValue = (int)(Math.pow(10, options.getDigitCount ())-1;

我完全理解你为什么会弄错,因为很多数学课都讲,^符号表示幂

^
是Java中的异或运算符。鉴于此,最大值和最小值的表达式没有意义。

运算符
^
不是用于取幂,而是用于按位异或

有一个字段:

private Random rand = new Random();

private int generateNumberWithDigitCount () {
    int pow10max = 1;
    for (int digits = options.getDigitCount(); digits > 0; --digits) {
        pow10max *= 10;
    }
    int pow10min = pow10max / 10;
    return pow10min - rand.nextInt(pow10max - pow10min);
}

new Random()
应该使用在过去的实例化中不太可能使用的种子,根据文档…它仍然完全破坏生成器的统计属性。我同意。我本想在评论中指出这一点,但我觉得这本身并不是问题的答案。关于最小值和最大值的观点更有可能是根本原因。我两个都引用了。但我认为滥用随机生成器要糟糕得多。(而且@TDG在我之前就发现了;-)@Bathsheba,“你破坏了统计特性”。为什么?
nextInt(2)
返回1的几率始终为50%。检查此项:可能重复,因此将标题更改为“随机数学问题生成…”@JimMischel问题标题上不允许使用“问题”一词我意识到这一点。我建议用“问题”这个词来代替“问题”。等等,我以为java中有指数。。。^来自另一种语言还是什么?我又在使用C#了吗?可能是针对C#的,但正如Henry所说,它是java的XOR运算符
^
在大多数Basicglad方言中都意味着求幂,这对程序来说是个好主意btw sweeper这是一个很好的答案(加上一个),但一定不要多次初始化生成器。