You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Quiz无重复随机出题实现问题求助

解决Quiz应用题目重复的问题

嘿,我来帮你搞定这个题目重复的问题!你当前的做法是每次打乱整个数组然后取第一个元素,但洗牌是完全随机的,所以确实会出现连续抽到同一题的情况。下面给你两种简单实用的解决方案,你可以根据自己的需求选择:


方案一:用集合追踪已出题的索引(适合无限循环出题,重复一轮后重置)

这个思路是用一个集合记录已经出过题的索引,每次随机选一个没被记录过的索引,直到所有题目都出过一遍再重置集合。

修改步骤:

  1. 在MainActivity中添加成员变量,存储已使用的题目索引和当前题目:
import java.util.Random;
import java.util.Set;
import java.util.HashSet;
// ... 其他原有导入

public class MainActivity extends AppCompatActivity {
    private TextView textView;
    private Button generateQbutton;
    private boolean aBoolean;
    private Set<Integer> usedIndices = new HashSet<>(); // 新增:记录已用题目索引
    private Facts currentFact; // 新增:存储当前显示的题目,方便弹窗调用
    // ... 其他原有代码
  1. 替换原来的randomFacts方法,去掉洗牌逻辑,改为随机选择未使用的索引:
public void randomFacts (){
    // 所有题目都出过一遍,重置索引集合
    if (usedIndices.size() == factArray.length) {
        usedIndices.clear();
        Toast.makeText(this, "本轮题目已完成,重新开始!", Toast.LENGTH_SHORT).show();
    }

    // 随机选一个未使用的索引
    int randomIndex;
    Random random = new Random();
    do {
        randomIndex = random.nextInt(factArray.length);
    } while (usedIndices.contains(randomIndex));

    // 记录索引,更新当前题目内容
    usedIndices.add(randomIndex);
    currentFact = factArray[randomIndex];
    textView.setText(currentFact.getmFacts());
    aBoolean = currentFact.ismAnswers();
}
  1. 修复弹窗显示的内容(你原来的弹窗固定用factArray[0]的dialog,现在要改成当前题的):
generateQbutton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        AlertDialog.Builder altdial = new AlertDialog.Builder(MainActivity.this);
        // 把factArray[0]改成currentFact,显示当前题的弹窗内容
        altdial.setMessage(currentFact.getmDialog()).setPositiveButton("k", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) { }
        });
        AlertDialog ctnalert = altdial.create();
        ctnalert.show();
        
        randomFacts ();
    }
});
  1. 原来的shuffelFacts方法可以直接删除,因为现在不需要洗牌逻辑了。

方案二:用临时列表存储剩余题目(适合一轮出完所有题再重置)

这个思路是把所有题目放到一个临时列表里,每次随机选一个题目后就从列表中移除,直到列表为空再重新填充,这样能保证一轮内绝对不会重复出题。

修改步骤:

  1. 在MainActivity中添加成员变量存储剩余题目和当前题目:
import java.util.Random;
import java.util.ArrayList;
import java.util.Arrays;
// ... 其他原有导入

public class MainActivity extends AppCompatActivity {
    private TextView textView;
    private Button generateQbutton;
    private boolean aBoolean;
    private ArrayList<Facts> remainingFacts; // 新增:存储剩余未出题目的列表
    private Facts currentFact; // 新增:存储当前显示的题目
    // ... 其他原有代码
  1. 在onCreate方法中初始化剩余题目列表:
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    textView = findViewById(R.id.textV);
    generateQbutton = findViewById(R.id.buttonP);
    
    // 初始化剩余题目列表
    remainingFacts = new ArrayList<>(Arrays.asList(factArray));
    randomFacts ();
    
    // ... 原有点击事件代码(记得修改弹窗的dialog来源)
}
  1. 替换randomFacts方法:
public void randomFacts (){
    // 列表为空,重新填充所有题目
    if (remainingFacts.isEmpty()) {
        remainingFacts = new ArrayList<>(Arrays.asList(factArray));
        Toast.makeText(this, "本轮题目已完成,重新开始!", Toast.LENGTH_SHORT).show();
    }

    // 随机选一个剩余题目并从列表中移除
    Random random = new Random();
    int randomIndex = random.nextInt(remainingFacts.size());
    currentFact = remainingFacts.remove(randomIndex);
    textView.setText(currentFact.getmFacts());
    aBoolean = currentFact.ismAnswers();
}
  1. 同样要修改弹窗的dialog来源,和方案一一致,改成currentFact.getmDialog()。

两种方案都能解决重复问题:方案一更适合想无限随机出题(允许跨轮重复但同轮不重复)的场景,方案二更适合需要一轮内把所有题都出一遍再循环的场景。你可以根据自己的需求选择~

内容的提问来源于stack exchange,提问作者Steigy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 09:06:03