Come posso verificare se un singolo carattere appare in una stringa?


210

In Java c'è un modo per verificare la condizione:

"Questo singolo carattere appare affatto nella stringa x"

senza usare un ciclo?


4
C'è qualche motivo particolare per cui stai cercando di evitare i loop?
shsteimer,

2
Non puoi fare una ricerca generale per il personaggio senza un ciclo. Guarda come funziona una macchina di Turing.
Salvador Valencia,

4
Dovremmo supporre che @barfoon non voglia che il loop sia nel loro codice. Ovviamente la macchina fa un ciclo da qualche parte. Altrimenti la domanda è senza senso.
WW.

Direi che la manipolazione delle stringhe di Java è piuttosto limitata
ACV

Risposte:


276

È possibile utilizzare string.indexOf('a').

Se il carattere aè presente in string:

restituisce l'indice della prima occorrenza del carattere nella sequenza di caratteri rappresentata da questo oggetto, oppure -1 se il carattere non si verifica.


8
Ma c'è sempre un ciclo dietro quella chiamata perché altrimenti non puoi trovare un simbolo.
vava,

4
indexOf () utilizza un ciclo internamente.
mmcdole,

22
Non è quello che Barfoon ha chiesto. B desidera evitare di fare il ciclo nel codice di B. Naturalmente l'API deve fare un ciclo dopo tutto una stringa è una matrice di caratteri racchiusa in una bella classe con molti metodi utili.
mP.

5
In che modo queste risposte ottengono così tanti voti? Le soluzioni di utilizzo indexOf()utilizzano loop internamente. Nessuna delle risposte fornisce la soluzione corretta e se qualcuno osa porre una nuova domanda, la gente lo dichiara Duplicate. Davvero deludente; (
Prashant Prabhakar Singh

4
@PrashantPrabhakarSingh Non vedo come si possa fare senza un ciclo. Una stringa è più o meno un gruppo di caratteri. Se si tratta di un gruppo (raccolta, matrice, ecc.), Indipendentemente dal fatto che sia interno o esterno al codice nativo, mi aspetterei che avresti bisogno di un ciclo per trovare qualcosa all'interno del "gruppo". Credo "senza usare un ciclo?" è più come "senza scrivere il mio ciclo?".
Tyler,

145
  • String.contains() che controlla se la stringa contiene una sequenza specificata di valori char
  • String.indexOf() che restituisce l'indice all'interno della stringa della prima occorrenza del carattere o della sottostringa specificata (ci sono 4 varianti di questo metodo)

15
un char non è un CharSequence quindi non può essere passato a String.contains (CharSequence).
mP.

28
Per usare String.contains () con un solo carattere c, procedi come segue
friederbluemle,

7
Oppure, se ti piace il codice funzione:String.contains(""+c)
Felix Neumeyer,

31

Non sono sicuro di cosa chieda esattamente il poster originale. Dato che indexOf (...) e contiene (...) entrambi usano probabilmente i cicli internamente, forse sta cercando di vedere se ciò è possibile senza un ciclo? Posso pensare a due mani fuori mano, una ovviamente sarebbe la ricorrenza:

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

L'altro è molto meno elegante, ma completezza ...:

/**
 * 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;
}

Il numero di linee aumenta man mano che è necessario supportare stringhe sempre più lunghe. Ma non ci sono loop / recidive. Puoi anche rimuovere il controllo della lunghezza se sei preoccupato che quella lunghezza () usi un ciclo.


10
Se definisci la ricorsione come una procedura non-loop, sei un geek: D +1 per essere creativo.
guerda,

1
Va tutto bene per la lunghezza hard coded di 5. In caso contrario, è necessario fare un loop per cercare il personaggio. Non essere pedanti ma, la prova di ciò è dimostrata dalla definizione di una macchina di Turing. Le basi di un dispositivo computazionale.
Salvador Valencia,

4
Correggimi se sbaglio, mi sento alla fine della giornata, una ricorsione è un ciclo sotto mentite spoglie vero? E può portare a un maggiore consumo di memoria rispetto a un normale ciclo in alcuni scenari.
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");
}

1
non è questo il duplicato esatto della risposta accettata?, riconosciamo il tuo impegno ma dovresti provare a trovare qualche domanda senza risposta e rispondere.
Shekhar_Pro

7

Puoi usare 2 metodi dalla Stringclasse.

  • String.contains() che controlla se la stringa contiene una sequenza specificata di valori char
  • String.indexOf() che restituisce l'indice all'interno della stringa della prima occorrenza del carattere o della sottostringa specificata o restituisce -1 se il carattere non viene trovato (esistono 4 varianti di questo metodo)

Metodo 1:

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

Metodo 2:

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

Collegamenti di: Zach Scrivena


4

Per verificare se qualcosa non esiste in una stringa, devi almeno guardare ogni carattere in una stringa. Quindi, anche se non usi esplicitamente un loop, avrà la stessa efficienza. Detto questo, puoi provare a usare str.contains ("" + char).


Concordato. Ad un certo punto, qualcuno, da qualche parte ha bisogno di costruire un ciclo per farlo. Fortunatamente l'API Java fa questo o il nostro codice sarebbe molto disordinato!
Fortyrunner,

4

Se è necessario controllare spesso la stessa stringa, è possibile calcolare in anticipo le occorrenze dei caratteri. Questa è un'implementazione che utilizza un array di bit contenuto in un array lungo:

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;
}}

Ho provato la tua soluzione su un problema simile che ho. La mia soluzione più vicina era oltre 1500 millisecondi per lunghezza stringa1 63k e lunghezza stringa2 95k. La tua soluzione genera un risultato in 3-5 millisecondi. Potete per favore modificare la soluzione per includere una spiegazione? Per favore?
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);
    }
}

2
e fornon è un ciclo ora?
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'");

Produzione

string does not contains the char 's'

La stessa risposta è stata fornita in precedenza.
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());
}

Qui stiamo cercando le occorrenze di ogni carattere dalla stringa b presente nella stringa a ed eliminando i caratteri.
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

0

Di seguito è quello che stavi cercando?

int index = string.indexOf(character);
return index != -1 && string.lastIndexOf(character) != index;

Perché hai && string.lastIndexOf(character) != index
GreenAsJade

-1

Non sarai in grado di verificare se il carattere appare affatto in una stringa senza che almeno una volta superi la stringa una volta usando loop / ricorsione (i metodi integrati come indexOf usano anche un ciclo)

Se il no. di volte cerchi se un carattere è nella stringa x è molto più lungo della lunghezza della stringa di quanto consiglierei di usare una struttura di dati Set in quanto sarebbe più efficiente del semplice utilizzoindexOf

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 sarai in grado di verificare se il carattere esiste in una stringa in tempo costante O (1) ma utilizzerai anche memoria aggiuntiva (la complessità dello spazio sarà O (n)).


-3

Ho usato il metodo string.includes () per questo che restituisce vero o falso se viene trovata la stringa o il carattere. Vedi la documentazione qui sotto.

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


Sebbene questo collegamento possa rispondere alla domanda, è meglio includere qui le parti essenziali della risposta e fornire il collegamento come riferimento. Le risposte di solo collegamento possono diventare non valide se la pagina collegata cambia.
Adriano Martins,

2
Questa risposta è per JavaScript, la domanda specifica in Java
Hazem Farahat,

-4

// questo è solo il principale ... puoi usare un lettore o uno scanner con 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... 
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.