Eu não sei se pode pôr simplesmente o código inteiro aqui, então pus no pastebin.
Eu estou querendo receber uma senha de até 4 dígitos, e depois fazer uma verificação até chegar na senha que foi posta. Fiz um loop em for, quando ele chegasse na senha correta era pra parar de tentar achar a senha e mostrar “senha correta”, mas não aparece e fica eternamente tentando achar a senha.
Quando encontrar a senha você tem que interromper o loop. Nesse caso, você pode usar uma flag ou simplesmente usar o break. Mas pelo que vi no seu código, o laço prevê até 10.000 repetições (o que por sinal é um valor muito alto, muito embora esteja de acordo com o PFC - 10^4), não havendo nenhuma condição de parada para o for. Com efeito, no melhor dos casos o for terá 1 iteração e no pior 10.000 iterações. O mais correto era código testar para os conhecidos e não para as possibilidades. Explico: em vez do código buscar por possibilidades (ir gerando números) e ver se dá ‘match’, ou seja se há correspondência, ele deveria testar se uma determina senha tem correspondente em um universo de senhas finito (sendo esse universo o reduzido possível). É como se as senhas registradas estivessem em um BD ou em uma lista, bastando verificar se a senha informada tem algum correspondente no BD ou na lista de senhas cadastradas.
Contudo, você pode transpor a condição do else if para o for, por exemplo:
Agora que eu prestei atenção… Tu está apensando a tentativa a cada iteração do for. Veja o que isso gera:
Iteração 1: tentativa 0000\n
Iteração 2: 0000\n + tentativa que resulta em 0000\n0001\n
iteração n: […]
Logo, nunca haverá correspondência.
Uma forma de resolver:
import java.text.DecimalFormat;
import javax.swing.JOptionPane;
public class Desafio08 {
public static void main(String[] args) {
StringBuffer mask = new StringBuffer();
DecimalFormat df = new DecimalFormat("0000");
int senha = Integer.parseInt(JOptionPane.showInputDialog("Digite uma senha númerica de 4 dígitos"));
mask.append(df.format(senha));
boolean correta = false;
StringBuffer tentativa = new StringBuffer();
System.out.println("M: " + mask);
JOptionPane.showMessageDialog(null, mask);
while(correta != true) {
if(tentativa.equals(mask)) {
System.out.println("Senha correta");
JOptionPane.showMessageDialog(null, "senha correta");
correta = true;
}else{
for (int i = 0; i < 10000; i++) {
//tentativa.append(df.format(i));
/*
* Em vez de apensar, eu gero um novo StringBuffer
*/
tentativa = new StringBuffer(df.format(i));
System.out.println(tentativa);
/*
* Se você colocar uma quebra de linha no final, nunca irá dar match
*/
//tentativa.append("\n");
System.out.println("\n");
/*
* O método equals no StringBuffer é u método herdado de Object, mas não o subscreve. Portanto,
compara objetos. Nesse caso, queremos comparar as Strings, então...
*/
if(tentativa.toString().equals(mask.toString())){
correta = true;
System.out.println("Match!" + "A senha "
+ mask + " corresponde a tentativa: " + tentativa + ".");
i = 10000;
}
}
}
}
}
}
Teste:
Devo lembrar que, se por exemplo a senha for 7532, então haverá 7.532 iterações. Logo a melhor maneira de resolver isso, seria listar as senhas aceitas e testar se a senha digitada bate.
Eu percebi que esse While está sendo totalmente inútil, eu tirei tudo do while e deixei só o for, e funcionou normalmente. Eu queria saber como eu poderia fazer essas tentativas até acertar sem utilizar o for, e utilizar o while