Problema com String

Boas tou aqui com um problema, é o seguinte o objectivo é identificar numa frase as letras que aparecem e as que nao aparecem, e guardar numa string as que aparecem e o mesmo para as que nao aparecem na frase, eu ja consegui identificar isso mesmo so que o problema é que no output as letras estao repetidas, quando eu so quero uma letra, ta aqui o codigo que fiz:

[code]public class ex7 {
public static void main(String[]args){
Scanner kbd=new Scanner (System.in);

	String S=kbd.nextLine();
	String K=S.toUpperCase();
	String Abc="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	String A="";
	String N="";
	
	for(int i=0;i<=25;i++){
		
		for(int j=0;j<K.length();j++){
		
		if(Abc.charAt(i)==K.charAt(j))
			A=A+K.charAt(j);
			N=N+" ";
			
		
		
		if(Abc.charAt(i)!=K.charAt(j)){
			A=A+" ";				
                            N=N+Abc.charAt(i);
		}
		
		}
		
	}
	
	    System.out.println("Aparecem: "+A);
	System.out.println("Nao aparecem: "+N);	
}[/code]

no output aparece: Aparecem: EEFIX
Nao aparecem: AAAAABBBBBCCCCC…etc
alguem me pode dar uma ideia para nao aparecerem letras repetidas?
Cumps

Você pode criar um Set de Character e colecionar todas as letras que contains no seu alfabeto e depois concatenar o resultado na String A (Se o alfabeto tiver completo é só colecionar eles no SET).

As que não aparecem você compara com seu SET(o alfabeto) e gera um vetor ou uma coleção das que são diferentes, o resultado você armazena na sua String N.

Teu método entra em loop infinito. Veja a linha 19 (j sempre recebe 0).

eu realmente nao intendi a pergunta.
…[quote] é o seguinte o objectivo é identificar numa frase as letras que aparecem e as que nao aparecem, e guardar numa string as que aparecem e o mesmo para as que nao aparecem na frase, eu ja consegui identificar isso [/quote]…

como assim as letras que aparecem?

Cara, seu código dificilmente vai rodar.
Você atribui j = 0 no seu for, ou seja, infinito.

Até mais!

Nosso amigo Eder Peixoto já tinha dado a dica! :slight_smile:

Até mais!

Teu código possui também erro de lógica, pois a iteração pela variável Abc deveria ser dentro do for que itera pela String digitada pelo usuário.

Deveria ser algo como:

for( char chAlvo : S ){
    for( char chAlfa : Abc  ){
    }
}

Só pra facilitar um pouco, fiz um código semelhante ao seu, e segui a linha dos métodos
utilizados.

public class ProcurandoStrings {
	
	public static void main(String[] args) {
		
	    Scanner kbd = new Scanner(System.in);  
	    String S = kbd.nextLine();  
	    String K = S.toUpperCase();  
	    String Abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";  
	    String A = "";  
	    String N = "";  

	    for (int i = 0; i <= 25; i++) {
	    	if (K.contains(String.valueOf(Abc.charAt(i)))) {
	    		A = A + Abc.charAt(i);
	    	}
	    	else {
	    		N = N + Abc.charAt(i);
	    	}
		}
	    
	    System.out.println("Aparecem: "+A);  
	    System.out.println("Nao aparecem: "+N);   
	}
}

Eu faria de outras formas, mas essa segue mais ou menos o que você estava pensando, assim você
pode implementar da forma que precisa.
E tente implementar de outras formas, tem formas mais elegantes! :wink:

Abraços!

Uma dica: o tipo das variáveis A e N não deveria ser String, pois a todo momento estão sendo alteradas. O mais aconselhável é utilizar StringBuilder ou StringBuffer.

String: utilize preferencialmente quando o conteúdo não for alterado;
StringBuilder: indicado para utilizar quando o String sofre alterações e quando NÃO há concorrência quanto a acesso (multi-thread);
StringBuffer: indicado para utilizar quando o String sofre alterações e quando HÁ concorrência quanto a acesso (multi-thread);

[quote=Eder Peixoto]Uma dica: o tipo das variáveis A e N não deveria ser String, pois a todo momento estão sendo alteradas. O mais aconselhável é utilizar StringBuilder ou StringBuffer.

String: utilize preferencialmente quando o conteúdo não for alterado, pois foi implementado para otimizar acesso de leitura;
StringBuilder: indicado para utilizar quando o String sofre alterações e quando NÃO há concorrência quanto a acesso (multi-thread);
StringBuffer: indicado para utilizar quando o String sofre alterações e quando HÁ concorrência quanto a acesso (multi-thread);

Exatamente como o Eder Peixoto falou!
Na verdade nasomet reescrevi seu código, como eu disse, seguindo suas variáveis e métodos,
assim mantive alguma “originalidade” do seu código.

Mas como eu disse, Eu faria de outras formas e uma delas é utilizando as dicas que o Eder mencionou.
E como eu disse nasomet, tente implementar de outras formas, tanto seguindo o que o Eder
mencionou, como melhorando outras partes do código.

Assim você se acostumará a codificar da forma correta, não somente da forma que funciona.
E se tiver problemas com novas implementações, é só postar a dúvida.

Só lembrando que não resisti e tirei a comparação de Strings com “==” e utilizei contains.

Abraços!

desculpem se não fui muito claro, vou ter em conta as dicas do Eder Peixoto e do AlexandreGama, muito obrigado!
Abraços

Bem parecido com o seu e o colega Alexandre, só que nesse exemplo a String com caracteres do alfabeto é percorrida para verificar se o mesmo está no texto digitado, assim o algoritmo fica mais eficiente para textos maiores e os caracteres já estarão ordenados no final.

Como foi dito é aconselhável usar um StringBuider para concatenar os caracteres. Observe que o texto digitado é convertido para maiúsculo.

String str = new Scanner(System.in).nextLine().toUpperCase(); String strAll = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; String strContains = ""; String strNotContains = ""; char[] strChars = strAll.toCharArray(); for (char c : strChars) { boolean contains = str.indexOf(c) != -1; if ((contains) && (strContains.indexOf(c) == -1)) { strContains += c; } else if (strNotContains.indexOf(c) == -1) { strNotContains += c; } } System.out.println("Caracteres que estao no texto : " + strContains); System.out.println("Caracteres que nao estao no texto: " + strNotContains);

Olá nasomet
O amigo lsjunior também postou uma implementação, dessa vez usando até foreach.

Agora só um detalhe
O lsjunior indicou que o algoritmo seria mais rápido, mas há um detalhe (tosco neste caso) também.

Imagine a situação:

"ABCDEFGHIJLMNOPQRSTUVWXYZ" //25 Letras
"ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" //50 letras

Repare que ao começar com o alfabeto temos:
para A = 50 comparações sem sucesso
para B = 50 comparações sem sucesso
para C = 50 comparações sem sucesso
.
.
.
para Z = 50 comparação com 1 sucesso
Ou seja, 50x25

Repare que ao começar com o texto temos:
para Z = 25 comparações com 1 sucesso
para Z = 25 comparações com 1 sucesso
.
.
.
para Z = 25 comparações com 1 sucesso
Ou seja, 25x50

Há formas interessantes de se lidar com eficiência de algoritmos e é bacana estudar.
Você terá casos que um algoritmo é eficiente em certos momentos, mas dependendo dos dados, ineficiente ou
igual, como a situação acima.

Abraços!

Vc não entendeu bem o algortimo, cada letra do alfateto e verificada uma única vez. Independete do tamanho do texto serão feita apenas as verificações se o texto possui cada uma das 26 letras do alfabeto.

[code]String str = new Scanner(System.in).nextLine().toUpperCase();
String strAll = “ABCDEFGHIJKLMNOPQRSTUVWXYZ”;
String strContains = “”;
String strNotContains = “”;
// Coloco o alfabeto em caracteres
char[] strChars = strAll.toCharArray();
// Percorro o array com os caracteres do alfabeto
for (char c : strChars) {
// Verifico se o caracter atual existe no texto
boolean contains = str.indexOf© != -1; // O texto digitado possui o caracter atual
// Se o texto possuir o caracter atual e o mesmo ainda nao tiver na String strContains
if ((contains) && (strContains.indexOf© == -1)) {
strContains += c;
}
// Se o NAO texto possuir o caracter atual e o mesmo ainda nao tiver na String strNotContains
else if (strNotContains.indexOf© == -1) {
strNotContains += c;
}
}

System.out.println("Caracteres que estao no texto : " + strContains);
System.out.println("Caracteres que nao estao no texto: " + strNotContains);[/code]

Olá lsjunior! Na verdade não falei em relação ao seu código. :wink:
Falei de modo geral, quando percorremos duas Strings para comparar caracter a caracter.

Se temos a frase “ABC”
e um texto “HHHHHHHHHH”

Não importa se você comparar, nesta situação, da frase para o texto, ou do texto para a frase,
o número de comparações será a mesma.

Primeira situação : 3x10
Segunda situação: 10x3

Quis pegar um “gancho” para a eficiência de algoritmos, apesar do exemplo ser bem, mas bem pobrezinho!

Abraços!

Que tal assim?

[code]
public class TesteAlfabeto {
public static void main(String args[]) {
boolean alfabeto[] = new boolean[25];
String texto = “Este e um exemplo de teste.”;

    texto = texto.toUpperCase();
    for (char ch : texto.toCharArray()) {
        int letra = ch - 65;
        if (letra >= 0 && letra < alfabeto.length)
            alfabeto[letra] = true;
    }

    for (int i = 0; i < 25; i++) {
        System.out.println("A letra " + (char)(i + 65) + " " + (alfabeto[i] ? "está" : "não está") + " no texto.");
    }
}

}[/code]

Esse sim, tem uma performance ótima. Percorre cada caractere do texto apenas uma vez, e não testa contains no alfabeto nenhuma vez.

E pode ser facilmente modificado para não só dizer se a letra existe, mas quantas vezes aparece no texto.

Aqui vai um exemplo com a modificação da contagem:

[code]public class TesteAlfabeto {
public static void main(String args[]) {
int alfabeto[] = new int[25];
String texto = “Este e um exemplo de teste.”;

    texto = texto.toUpperCase();
    for (char ch : texto.toCharArray()) {
        int letra = ch - 65;
        if (letra >= 0 && letra < alfabeto.length)
            alfabeto[letra]++;
    }

    for (int i = 0; i < 25; i++)
        if (alfabeto[i] != 0)
            System.out.println("A letra " + (char)(i + 65) + " aparece " + alfabeto[i] + " vezes no texto.");
}

}
[/code]

Boa ViniGodoy!

O seu exemplo é o clássico exemplo que eu fazia em C na faculdade quando o professor
dava as aulas sobre eficiência de algortimos!

O nosso amigo já tem bastante coisa pra se divertir!

Atémais!

Ai que ta, nesse exemplo nao ha necessidade de comparacao de caracter por caracter, por que nao quero saber quantas vezes aparece a letra ‘A’ e sim se existe a letra ‘A’.

alfabeto = “ABC”;
texto = “Um texto Qualquer”;
array = [‘A’, ‘B’, ‘C’]; os caracteres do alfabeto

ai vem o loop

o texto possui a letra ‘A’
o texto possui a letra ‘B’
o texto pessui a letra ‘C’

termina o loop

pronto, acabou, nesse caso seriam feitas 3 iteracoes no array e nao o tamanho do array x o tamanho do texto.