Como posso verificar se um único caractere aparece em uma string?

210

Em Java, há uma maneira de verificar a condição:

"Esse caractere único aparece na string x"

sem usar um loop?

barfoon
fonte
4
Existe alguma razão específica para tentar evitar loops?
shsteimer
2
Você não pode fazer uma pesquisa geral pelo personagem sem um loop. Veja como uma máquina de Turing funciona.
Salvador Valencia
4
Devemos assumir que @barfoon não deseja que o loop esteja no código deles. Obviamente, a máquina faz um loop em algum lugar. Caso contrário, a questão é um absurdo.
WW.
Eu diria que a manipulação de strings do java é bastante limitada
ACV

Respostas:

276

Você pode usar string.indexOf('a').

Se o caractere aestiver presente em string:

retorna o índice da primeira ocorrência do caractere na sequência de caracteres representada por esse objeto ou -1 se o caractere não ocorrer.

mP.
fonte
8
Mas sempre há um loop atrás dessa chamada, porque você não consegue encontrar um símbolo.
vava
4
indexOf () usa um loop internamente.
mmcdole 03/02/09
22
Não é isso que Barfoon perguntou. B deseja evitar fazer o loop no código de B. Naturalmente, a API precisa fazer um loop, afinal uma String é uma matriz de caracteres agrupados em uma classe agradável com muitos métodos úteis.
mP.
5
Como essas respostas estão recebendo tantos votos positivos? As soluções de uso indexOf()usam loop internamente. Nenhuma das respostas fornece a solução correta e, se alguém se atreve a fazer uma nova pergunta, as pessoas a declaram Duplicate. Realmente decepcionante; (
Prashant Prabhakar Singh
4
@PrashantPrabhakarSingh Não vejo como isso pode ser feito sem um loop. Uma sequência é mais ou menos um grupo de caracteres. Se for um grupo (coleção, matriz, etc), não importa se é interno ou externo ao código nativo, eu esperaria que você precisasse de um loop para encontrar algo dentro do "grupo". Eu acredito "sem usar um loop?" é mais como "sem escrever meu próprio loop?".
Tyler
145
  • String.contains() que verifica se a sequência contém uma sequência especificada de valores de caracteres
  • String.indexOf() que retorna o índice dentro da string da primeira ocorrência do caractere ou substring especificado (há 4 variações desse método)
Zach Scrivena
fonte
15
um char não é um CharSequence, portanto não pode ser passado para String.contains (CharSequence).
mP.
28
Para usar String.Contains () com um único caractere C fazer esta: String.Contains (Character.toString (c))
friederbluemle
7
Ou faça isso se você quiser um código curto:String.contains(""+c)
Felix Neumeyer
31

Não sei exatamente o que o pôster original está perguntando exatamente. Como indexOf (...) e contém (...) provavelmente usam loops internamente, talvez ele esteja olhando para ver se isso é possível sem um loop? Eu posso pensar em duas maneiras fora de mão, uma seria, naturalmente, a recorrência:

public boolean containsChar(String s, char search) {
    if (s.length() == 0)
        return false;
    else
        return s.charAt(0) == search || containsChar(s.substring(1), search);
}

O outro é muito menos elegante, mas completo ...:

/**
 * Works for strings of up to 5 characters
 */
public boolean containsChar(String s, char search) {
    if (s.length() > 5) throw IllegalArgumentException();

    try {
        if (s.charAt(0) == search) return true;
        if (s.charAt(1) == search) return true;
        if (s.charAt(2) == search) return true;
        if (s.charAt(3) == search) return true;
        if (s.charAt(4) == search) return true;
    } catch (IndexOutOfBoundsException e) {
        // this should never happen...
        return false;
    }
    return false;
}

O número de linhas cresce à medida que você precisa para suportar seqüências cada vez maiores, é claro. Mas não há loops / recorrências. Você pode até remover a verificação de comprimento se estiver preocupado com o fato de que esse comprimento () use um loop.

Jack Leow
fonte
10
Se você definir recursão como um procedimento sem loop, você é um nerd: D +1 por ser criativo.
Guerda
1
Tudo é bom para o comprimento codificado de 5. Caso contrário, é necessário fazer um loop para procurar o personagem. Não é pedante, mas a prova disso é demonstrada pela definição de uma máquina de Turing. A base de um dispositivo computacional.
Salvador Valencia
4
Me corrija se eu estiver errado, sinto que no final do dia, uma recursão é um laço disfarçado, não é? E isso pode levar a mais consumo de memória do que um loop comum em alguns cenários.
PasinduJay
12
String temp = "abcdefghi";
if(temp.indexOf("b")!=-1)
{
   System.out.println("there is 'b' in temp string");
}
else
{
   System.out.println("there is no 'b' in temp string");
}
Richard
fonte
1
não é a duplicata exata da resposta aceita?, reconhecemos seu esforço, mas você deve tentar encontrar alguma pergunta sem resposta e respondê-la.
Shekhar_Pro
7

Você pode usar 2 métodos da Stringclasse.

  • String.contains() que verifica se a sequência contém uma sequência especificada de valores de caracteres
  • String.indexOf() que retorna o índice dentro da string da primeira ocorrência do caractere ou substring especificado ou retorna -1 se o caractere não for encontrado (existem 4 variações desse método)

Método 1:

String myString = "foobar";
if (myString.contains("x") {
    // Do something.
}

Método 2:

String myString = "foobar";
if (myString.indexOf("x") >= 0 {
    // Do something.
}

Links de: Zach Scrivena

Halfacht
fonte
4

Para verificar se algo não existe em uma sequência, você precisa pelo menos observar cada caractere em uma sequência. Portanto, mesmo se você não usar explicitamente um loop, ele terá a mesma eficiência. Dito isto, você pode tentar usar str.contains ("" + char).

mweiss
fonte
Acordado. Em algum momento, alguém, em algum lugar, precisa construir um loop para fazer isso. Felizmente, a API Java faz isso ou nosso código seria muito confuso!
Fortyrunner /
4

Se você precisar verificar a mesma sequência com frequência, poderá calcular as ocorrências de caracteres antecipadamente. Esta é uma implementação que usa uma matriz de bits contida em uma matriz longa:

public class FastCharacterInStringChecker implements Serializable {
private static final long serialVersionUID = 1L;

private final long[] l = new long[1024]; // 65536 / 64 = 1024

public FastCharacterInStringChecker(final String string) {
    for (final char c: string.toCharArray()) {
        final int index = c >> 6;
        final int value = c - (index << 6);
        l[index] |= 1L << value;
    }
}

public boolean contains(final char c) {
    final int index = c >> 6; // c / 64
    final int value = c - (index << 6); // c - (index * 64)
    return (l[index] & (1L << value)) != 0;
}}
fillumina
fonte
Eu tentei sua solução em um problema semelhante que eu tenho. Minha solução mais próxima foi mais de 1500 milissegundos para string1 de comprimento 63k e string2 de comprimento 95k. Sua solução gera um resultado em 3-5 milissegundos. Você pode editar sua solução para incluir uma explicação? Por favor?
Viorel Florian
1
package com;
public class _index {

    public static void main(String[] args) {
        String s1="be proud to be an indian";
        char ch=s1.charAt(s1.indexOf('e'));
        int count = 0; 
        for(int i=0;i<s1.length();i++) {
            if(s1.charAt(i)=='e'){
                System.out.println("number of E:=="+ch);
                count++;
            }
        }
        System.out.println("Total count of E:=="+count);
    }
}
Praveen kumar
fonte
2
e fornão é um loop agora?
Mindwin
0
String s="praveen";
boolean p=s.contains("s");
if(p)
    System.out.println("string contains the char 's'");
else
    System.out.println("string does not contains the char 's'");

Resultado

string does not contains the char 's'
praveen
fonte
A mesma resposta foi fornecida antes.
Serge Belov
0
static String removeOccurences(String a, String b)
{
    StringBuilder s2 = new StringBuilder(a);

    for(int i=0;i<b.length();i++){
        char ch = b.charAt(i);  
        System.out.println(ch+"  first index"+a.indexOf(ch));

        int lastind = a.lastIndexOf(ch);

    for(int k=new String(s2).indexOf(ch);k > 0;k=new String(s2).indexOf(ch)){
            if(s2.charAt(k) == ch){
                s2.deleteCharAt(k);
        System.out.println("val of s2 :             "+s2.toString());
            }
        }
      }

    System.out.println(s1.toString());

    return (s1.toString());
}
Ganeshmani
fonte
Aqui, estamos procurando ocorrências de todos os caracteres da String b presentes na String a e excluindo os caracteres.
Ganeshmani
0
you can use this code. It will check the char is present or not. If it is present then the return value is >= 0 otherwise it's -1. Here I am printing alphabets that is not present in the input.

import java.util.Scanner;

public class Test {

public static void letters()
{
    System.out.println("Enter input char");
    Scanner sc = new Scanner(System.in);
    String input = sc.next();
    System.out.println("Output : ");
    for (char alphabet = 'A'; alphabet <= 'Z'; alphabet++) {
            if(input.toUpperCase().indexOf(alphabet) < 0) 
                System.out.print(alphabet + " ");
    }
}
public static void main(String[] args) {
    letters();
}

}

//Ouput Example
Enter input char
nandu
Output : 
B C E F G H I J K L M O P Q R S T V W X Y Z
Nandu cg
fonte
0

Abaixo está o que você estava procurando?

int index = string.indexOf(character);
return index != -1 && string.lastIndexOf(character) != index;
Toochka
fonte
Por que você tem && string.lastIndexOf(character) != index
GreenAsJade
-1

Você não poderá verificar se char aparece em alguma string sem pelo menos passar por cima da string uma vez usando loop / recursão (os métodos internos como indexOf também usam um loop)

Se não. Às vezes, você consulta se um caractere está na string x é muito mais do que o comprimento da string do que eu recomendaria usar uma estrutura de dados Set , pois isso seria mais eficiente do que simplesmente usarindexOf

String s = "abc";

// Build a set so we can check if character exists in constant time O(1)
Set<Character> set = new HashSet<>();
int len = s.length();
for(int i = 0; i < len; i++) set.add(s.charAt(i));

// Now we can check without the need of a loop
// contains method of set doesn't use a loop unlike string's contains method
set.contains('a') // true
set.contains('z') // false

Usando set, você poderá verificar se o caractere existe em uma string em tempo constante O (1), mas também usará memória adicional (a complexidade do espaço será O (n)).

Dhyey
fonte
-3

Eu usei o método string.includes () para isso, que retorna true ou false se a string ou o caractere for encontrado. Veja a documentação abaixo.

https://www.w3schools.com/jsref/jsref_includes.asp

Udugam
fonte
Embora esse link possa responder à pergunta, é melhor incluir aqui as partes essenciais da resposta e fornecer o link para referência. As respostas somente para links podem se tornar inválidas se a página vinculada for alterada.
Adriano Martins
2
Essa resposta é para JavaScript, a questão diz especificamente em Java
Hazem Farahat
-4

// isso é apenas o principal ... você pode usar um leitor ou scanner com buffer

string s;
int l=s.length();
int f=0;
for(int i=0;i<l;i++)
   {
      char ch1=s.charAt(i); 
      for(int j=0;j<l;j++)
         {
          char ch2=charAt(j);
          if(ch1==ch2)
           {
             f=f+1;
             s.replace(ch2,'');
           }
          f=0;
          }
     }
//if replacing with null does not work then make it space by using ' ' and add a if condition on top.. checking if its space if not then only perform the inner loop... 
a qualquer momento
fonte