【问题标题】:Iterating over a char array inside nested loops迭代嵌套循环内的 char 数组
【发布时间】:2021-06-05 04:59:01
【问题描述】:

我正在用 Java 创建一个 Hangman 游戏,但我在比较字母和单词(字符数组)时使用的循环遇到了一些问题:

public class Hangman{
  static String seleccionar(){
        //Se selecciona al azar una palabra de la lista
        String[] palabras = {"callado","llamar","esgrima","monedero",
                          "tortuga","semanas","matutino","graduar",
                          "domador","regazo","vicio","carrito",
                          "esqueleto","golosinas","zodiaco","anestesia",
                          "pera","clase","acierto","oliva"};
        int numero = 0;
        numero = (int)(Math.random() * 9);
        String palabra = palabras[numero]; 
        return palabra;
    }

  public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(System.in);
        System.out.println("Ahorcado");

        //Método retorna una palabra aleatoria //Method that returns random word
        String palabra = seleccionar();
        System.out.println(palabra);
        char[] letras = palabra.toCharArray();

        //Ocultar la palabra //Hiding the word
        char[] oculto = new char[palabra.length()];
        for (int i = 0; i < palabra.length(); i++){
            String underscore = "_"; 
            oculto[i] = underscore.charAt(0);
        }
        
        //Here's the issue

        int contador = 0;
        int s = 0;
        for (int k = 0; k < palabra.length(); k++){
            char letraUsuario = sc.next().charAt(0);
            for (char letra: letras){
                if (String.valueOf(letraUsuario).equalsIgnoreCase(String.valueOf(String.valueOf(letra)))){
                    oculto[s] = letraUsuario;
                }
                else{
                    contador += 1;
                }
                s += 1;
            }
            for (char letra: oculto){
                System.out.print(letra);
            }
            System.out.println();
            if (contador == 7){
                break;
            }
        }
        sc.close();
}

所以当我运行它时,终端会显示:

Ahorcado
esgrima
r
___r___
m
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 12 out of bounds for length 7
        at Hangman.main(Hangman.java:36)

我不太确定为什么它显示索引 12,它的迭代次数是否超出了我告诉它的次数?

先谢谢了

【问题讨论】:

    标签: java arrays char iteration nested-loops


    【解决方案1】:

    您的代码的主循环中还有一个问题:

    for (char letra: letras){
        if (String.valueOf(letraUsuario).equalsIgnoreCase(String.valueOf(String.valueOf(letra)))){
            oculto[s] = letraUsuario;
        }
        else{
            contador += 1;
        }
        s += 1;
    }
    

    即使字母包含在单词中,contador 也会增加,这意味着对于更长的单词,一个错误将结束游戏。只有在完成整个循环后没有找到匹配的字符时才应该递增。

    我推荐你使用 Map>,它会记录单词中的所有字符及其被选中后的索引,这样可以简化主循环,如下所示:

    char[] oculto = new char[palabra.length()];
    Map<Character, List<Integer>> characterIndexes = new HashMap<>();
    for (int i = 0; i < oculto.length; i++) {
        oculto[i] = '_';
        if (!characterIndexes.containsKey(letras[i])) {
            List<Integer> indexes = new ArrayList<>();
            indexes.add(i);
            characterIndexes.put(letras[i], indexes);
        } else {
            characterIndexes.get(letras[i]).add(i);
        }
    }
    
    int contador = 0;
    for (int k = 0; k < palabra.length(); k++) {
        char letraUsuario = Character.toLowerCase(sc.next().charAt(0));
        if (characterIndexes.containsKey(letraUsuario)) {
            for (int i : characterIndexes.get(letraUsuario)) {
                oculto[i] = letraUsuario;
            }
        } else {
            contador++;
        }
        for (char letra : oculto) {
            System.out.print(letra);
        }
        System.out.println();
        if (contador == 7) {
            break;
        }
    }
    sc.close();
    

    【讨论】:

      【解决方案2】:

      问题出在 s 变量中,您正在递增(在每个循环上 +1 以获取单词中的下一个字母),但是在检查下一个 palabra 时,您不会重置s 回到 0 从第 0 个字母开始检查。所以固定代码很简单:

      int contador = 0;
      int s = 0; //SETTING AT 0
      for (int k = 0; k < palabra.length(); k++){
          s=0; //RESETTING FOR EACH NEW WORD
          char letraUsuario = sc.next().charAt(0); //ievada simbolu
          for (char letra: letras){
             if (String.valueOf(letraUsuario).equalsIgnoreCase(String.valueOf(String.valueOf(letra)))){
                oculto[s] = letraUsuario;
             } else{
                contador += 1;
             }
             s += 1; //this reaches the length of the word at the end of inner loop
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-10-22
        • 2013-05-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-30
        • 2017-09-18
        相关资源
        最近更新 更多