¿Cómo puedo verificar si aparece un solo carácter en una cadena?

210

En Java, hay una manera de verificar la condición:

"¿Aparece este único carácter en la cadena x"

sin usar un bucle?

barfoon
fuente
44
¿Hay alguna razón particular por la que intentas evitar los bucles?
shsteimer 03 de
2
No puedes hacer una búsqueda general del personaje sin un bucle. Mira cómo funciona una máquina de Turing.
Salvador Valencia
44
Debemos suponer que @barfoon no quiere que el bucle esté en su código. Obviamente, la máquina hace un bucle en alguna parte. De lo contrario, la pregunta no tiene sentido.
WW.
Yo diría que la manipulación de cadenas de Java es bastante limitada
ACV

Respuestas:

276

Puedes usar string.indexOf('a').

Si el personaje aestá presente en string:

devuelve el índice de la primera aparición del carácter en la secuencia de caracteres representada por este objeto, o -1 si el carácter no aparece.

mP.
fuente
8
Pero siempre hay un bucle detrás de esa llamada porque de lo contrario no puede encontrar un símbolo.
vava
44
indexOf () usa un bucle internamente.
mmcdole 03 de
22
Eso no es lo que preguntó Barfoon. B desea evitar hacer el bucle en el código de B. Naturalmente, la API necesita hacer un bucle después de todo, una Cadena es una matriz de caracteres envueltos en una buena clase con muchos métodos útiles.
mP.
55
¿Cómo estas respuestas están obteniendo tantos votos positivos? Las soluciones de uso indexOf()utiliza el bucle interno. Ninguna de las respuestas da la solución correcta y si alguien se atreve a hacer una nueva pregunta, la gente la declara Duplicate. Realmente decepcionante; (
Prashant Prabhakar Singh
44
@PrashantPrabhakarSingh No veo cómo se puede hacer esto sin un bucle. Una cadena es más o menos un grupo de caracteres. Si es un grupo (colección, matriz, etc.), no importa si es interno o externo al código nativo, esperaría que necesite un bucle para encontrar algo dentro del "grupo". Creo "sin usar un bucle?" es más como "sin escribir mi propio bucle?".
Tyler
145
  • String.contains() que comprueba si la cadena contiene una secuencia específica de valores de caracteres
  • String.indexOf() que devuelve el índice dentro de la cadena de la primera aparición del carácter o subcadena especificado (hay 4 variaciones de este método)
Zach Scrivena
fuente
15
un char no es un CharSequence, por lo que no se puede pasar a String.contains (CharSequence).
mP.
28
Para usar String.contains () con un solo carácter, haga esto: String.contains (Character.toString (c))
friederbluemle
77
O haga esto si le gusta el código corto:String.contains(""+c)
Felix Neumeyer
31

No estoy seguro de lo que el cartel original está preguntando exactamente. Desde indexOf (...) y contiene (...) ambos probablemente usan bucles internamente, ¿tal vez está buscando ver si esto es posible sin un bucle? Se me ocurren dos maneras, por supuesto, una sería la recurrencia:

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

El otro es mucho menos elegante, pero 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;
}

El número de líneas crece a medida que necesita soportar cadenas cada vez más largas, por supuesto. Pero no hay bucles / recursiones en absoluto. Incluso puede eliminar la verificación de longitud si le preocupa que esa longitud () use un bucle.

Jack Leow
fuente
10
Si define la recursividad como un procedimiento sin bucle, es un geek: D +1 por ser creativo.
guerda
1
Todo es bueno para la longitud codificada de 5. De lo contrario, HAY NECESIDAD DE HACER UN BUCLE para buscar el personaje. No para ser pedante, pero la prueba de esto se muestra en la definición de una máquina de Turing. La base de un dispositivo computacional.
Salvador Valencia
44
Corrígeme si me equivoco, siento que al final del día, una recursión es un bucle disfrazado, ¿no? Y puede conducir a un mayor consumo de memoria que un bucle ordinario en algunos escenarios.
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");
}
Ricardo
fuente
1
¿no es este el duplicado exacto de la respuesta aceptada ?, reconocemos su esfuerzo pero debe intentar encontrar alguna pregunta sin respuesta y responderla.
Shekhar_Pro
7

Puedes usar 2 métodos de la Stringclase.

  • String.contains() que comprueba si la cadena contiene una secuencia específica de valores de caracteres
  • String.indexOf() que devuelve el índice dentro de la cadena de la primera aparición del carácter o subcadena especificado o devuelve -1 si no se encuentra el carácter (hay 4 variaciones de este 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.
}

Enlaces por: Zach Scrivena

Medio yate
fuente
4

Para verificar si algo no existe en una cadena, al menos debe mirar cada carácter en una cadena. Entonces, incluso si no usa explícitamente un bucle, tendrá la misma eficiencia. Dicho esto, puedes intentar usar str.contains ("" + char).

mweiss
fuente
Convenido. En algún momento, alguien, en algún lugar, necesita construir un bucle para hacer esto. Afortunadamente, la API de Java hace esto o nuestro código estaría muy abarrotado.
Fortyrunner
4

Si necesita verificar la misma cadena con frecuencia, puede calcular las ocurrencias de caracteres por adelantado. Esta es una implementación que utiliza una matriz de bits contenida en una matriz larga:

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
fuente
Probé su solución en un problema similar que tengo. Mi solución más cercana fue más de 1500 milisegundos para string1 longitud 63k y string2 longitud 95k. Su solución arroja un resultado en 3-5 milisegundos. ¿Puedes editar tu solución para incluir una explicación? ¿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
fuente
2
y forno es un bucle ahora?
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'");

Salida

string does not contains the char 's'
Praveen
fuente
La misma respuesta se ha proporcionado 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
fuente
Aquí estamos buscando ocurrencias de cada carácter de la Cadena b presente en la Cadena a y eliminando los 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
fuente
0

¿Es el siguiente lo que estabas buscando?

int index = string.indexOf(character);
return index != -1 && string.lastIndexOf(character) != index;
Toochka
fuente
¿Por qué tienes && string.lastIndexOf(character) != index
GreenAsJade
-1

No podrá verificar si char aparece en absoluto en alguna cadena sin al menos pasar por la cadena una vez que usa loop / recursión (los métodos integrados como indexOf también usan un ciclo)

Si el no. muchas veces, si un carácter está en la cadena x, es mucho más alto que la longitud de la cadena de lo que recomendaría usar una estructura de datos Set , ya que sería más eficiente que simplemente 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 podrá verificar si el carácter existe en una cadena en tiempo constante O (1) pero también usará memoria adicional (la complejidad del espacio será O (n)).

Dhyey
fuente
-3

Usé el método string.includes () para esto que devuelve verdadero o falso si se encuentra la cadena o el carácter. Consulte la documentación a continuación.

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

Udugam
fuente
Si bien este enlace puede responder la pregunta, es mejor incluir las partes esenciales de la respuesta aquí y proporcionar el enlace como referencia. Las respuestas de solo enlace pueden volverse inválidas si la página vinculada cambia.
Adriano Martins
2
Esta respuesta es para JavaScript, la pregunta específicamente dice en Java
Hazem Farahat
-4

// esto es solo el principal ... puedes usar el lector o escáner de memoria intermedia wither

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... 
en cualquier momento
fuente