Limit anagram hits - Java

Asked

Viewed 130 times

0

I have a code that checks if the user has typed an existing word in the anagram, but if he enters the same word 10 times it counts as 10 hits, I would like to limit this to 1 time only. The code I’ve been doing is this:

String palavra[] = {"BAR", "OLA", "ALO"}; // Maneira mais elegante de inicializar um vetor

String p = jTextField1.getText(); 

// Recupera String do componente textfield.

boolean existe = false; // Declaro uma flag que indica se encontrou ou não uma palavra igual.

for (int i = 0 ; i < 3; i++) {

    if (palavra[i].equals(p)) { // Percorre vetor de acordo com i.

        existe = true; // Altera valor da flag.

       break; // Sai do laço se encontrou palavra igual.
   }

}


if (existe==true) {

//verifica flag

    cont++;

JOptionPane.showMessageDialog(this, "Acertos :"+cont+"de 3");



} else if (existe==false){

    JOptionPane.showMessageDialog(this, "NAO EXISTE");
}

1 answer

2


You didn’t post all the code, but let’s assume it looks something like this:

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextField;

public class Anagramas extends JFrame {

    private JTextField jTextField1;
    private int cont;

    public Anagrama() {
        // ...
    }

    public void achaAnagrama() {
        String palavra[] = {"BAR", "OLA", "ALO"}; // Maneira mais elegante de inicializar um vetor

        String p = jTextField1.getText(); 

        // Recupera String do componente textfield.

        boolean existe = false; // Declaro uma flag que indica se encontrou ou não uma palavra igual.

        for (int i = 0 ; i < 3; i++) {

            if (palavra[i].equals(p)) { // Percorre vetor de acordo com i.

                existe = true; // Altera valor da flag.

               break; // Sai do laço se encontrou palavra igual.
           }

        }


        if (existe==true) {

        //verifica flag

            cont++;

        JOptionPane.showMessageDialog(this, "Acertos :"+cont+"de 3");



        } else if (existe==false){

            JOptionPane.showMessageDialog(this, "NAO EXISTE");
        }
    }

}

First thing I notice, it’s better to change the name of array palavra for palavras in the plural, after all array contains several words, not a single word.

By the way, which is better? Use String[] palavras or String palavras[]? With String[] palavras we have the usual notation, variable type (String[]) followed by the name. Already with String palavras[], we have the kind defined by half (String), followed by the variable name, followed by something that will modify the previously declared type, something that is unnecessarily more complicated. Also, anyone who glances at the code quickly may not understand the [] after the variable name and imagine that the type is simply String instead of String[]. It is therefore better to declare:

String[] palavras = {"BAR", "OLA", "ALO"};

You can also simplify that:

if (existe == true) {
    // ...
} else if (existe == false) {
    // ...
}

Compare with == true is unnecessary. Simply use if (existe) { becomes clearer and simpler. Also, if it does not enter the if, then the only possibility is that existe is false, which is why the else if is irreverent, as it will always work true when the flow reaches that point. So your code could be simplified for this:

if (existe) {
    // ...
} else {
    // ...
}

Another thing about your code is this:

for (int i = 0 ; i < 3; i++) {
// ...
JOptionPane.showMessageDialog(this, "Acertos :"+cont+"de 3");

Why 3? Because 3 is the size of your array. Therefore, it is better to compute the size of the array instead of using the fixed 3, because in this case, if you decide to put more elements in the array, you will not need to arrange the size manually:

for (int i = 0; i < palavras.length; i++) {
// ...
JOptionPane.showMessageDialog(this, "Acertos: " + cont + " de " + palavras.length);

And also note that there is space both before and after the "of" in the message.

In fact, we can even use the syntax of for-each instead and get rid of the complexity of having to control the indexes in the iteration, further simplifying the code:

for (String pa : palavra) {
    if (pa.equals(p)) {
        existe = true; // Altera valor da flag.
        break; // Sai do laço se encontrou palavra igual.
   }
}

What you need to know is not how many times he was right, but what the hits were. After all, if he’s been right before and just repeated the word, you have to somewhere know what words have been tried. One way to do this is to keep the right words in one Set. And in this case, you will no longer need the variable cont, just use the size of the Set. This way, your code looks like this:

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextField;

public class Anagramas extends JFrame {

    private JTextField jTextField1;
    private Set<String> acertadas;

    public Anagrama() {
        // ...
        acertadas = new HashSet<>();
    }

    public void achaAnagrama() {
        String[] palavras = {"BAR", "OLA", "ALO"}; // Maneira mais elegante de inicializar um vetor

        String p = jTextField1.getText(); 

        // Recupera String do componente textfield.

        boolean existe = false; // Declaro uma flag que indica se encontrou ou não uma palavra igual.

        for (String pa : palavra) {
            if (pa.equals(p)) {
                existe = true; // Altera valor da flag.
                break; // Sai do laço se encontrou palavra igual.
            }
        }

        if (existe) {
            acertadas.add(p);
            JOptionPane.showMessageDialog(this, "Acertos: " + acertadas.size() + " de " + palavras.length);
        } else {
            JOptionPane.showMessageDialog(this, "NÃO EXISTE");
        }
    }
}

Can you do even better? Yes. If palavras is also a Set, instead of a array, you can use the method contains and remove the loop and also the variable existe, leaving the code very simple:

import java.util.Arrays;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextField;

public class Anagramas extends JFrame {

    private JTextField jTextField1;
    private Set<String> acertadas;
    private Set<String> palavras;

    public Anagrama() {
        // ...
        acertadas = new HashSet<>();
        palavras = new HashSet<>(Arrays.asList("BAR", "OLA", "ALO"));
    }

    public void achaAnagrama() {
        String p = jTextField1.getText(); // Recupera String do componente textfield.

        if (palavras.contains(p)) {
            acertadas.add(p);
            JOptionPane.showMessageDialog(this, "Acertos: " + acertadas.size() + " de " + palavras.size());
        } else {
            JOptionPane.showMessageDialog(this, "NÃO EXISTE");
        }
    }
}
  • 1

    This answer is very good, should have more votes :/

  • Dude, it’s working, partially , I don’t understand this part: Joptionpane.showMessageDialog(this, "Hits: " + hits.size() + hits" from " + word.length); hits.size ? This value is not going out of 1 as I hit the words , and I need to show how many were hit to pass the stage after hitting the minimum of 3 . Since thank you !

  • @Mateusrocha Opa, sorry, I changed the name of the variable in the last hour before posting and left this behind. See if now is ok. If after that he’s not coming out of 1, say what are the words you’re testing for me to take the same test as well.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.