Comment puis-je vérifier si un seul caractère apparaît dans une chaîne?

210

En Java, existe-t-il un moyen de vérifier la condition:

"Ce caractère unique apparaît-il du tout dans la chaîne x"

sans utiliser de boucle?

barfoon
la source
4
Y a-t-il une raison particulière pour laquelle vous essayez d'éviter les boucles?
shsteimer
2
Vous ne pouvez pas faire une recherche générale du personnage sans boucle. Regardez comment fonctionne une machine de Turing.
Salvador Valence
4
Nous devons supposer que @barfoon ne veut pas que la boucle soit dans leur code. Évidemment, la machine fait une boucle quelque part. Sinon, la question est absurde.
WW.
Je dirais que la manipulation des cordes de Java est assez limitée
ACV

Réponses:

276

Vous pouvez utiliser string.indexOf('a').

Si l'omble aest présent dans string:

il renvoie l'index de la première occurrence du caractère dans la séquence de caractères représentée par cet objet, ou -1 si le caractère ne se produit pas.

mP.
la source
8
Mais il y a toujours une boucle derrière cet appel car vous ne pouvez pas trouver un symbole autrement.
vava
4
indexOf () utilise une boucle en interne.
mmcdole
22
Ce n'est pas ce que Barfoon a demandé. B souhaite éviter de faire la boucle dans le code de B. Naturellement, l'API doit faire une boucle après tout, une chaîne est un tableau de caractères enveloppé dans une belle classe avec beaucoup de méthodes utiles.
mP.
5
Comment ces réponses reçoivent-elles autant de votes positifs? Les solutions d'utilisation des indexOf()usages bouclent en interne. Aucune des réponses ne donne de solution correcte et si quelqu'un ose poser une nouvelle question, les gens la déclarent Duplicate. Vraiment décevant; (
Prashant Prabhakar Singh
4
@PrashantPrabhakarSingh Je ne vois pas comment cela peut se faire sans boucle. Une chaîne est plus ou moins un groupe de caractères. S'il s'agit d'un groupe (collection, tableau, etc.), peu importe qu'il soit interne ou externe au code natif, je m'attendrais à ce que vous ayez besoin d'une boucle pour trouver quelque chose dans le "groupe". Je crois "sans utiliser de boucle?" est plus comme "sans écrire ma propre boucle?".
Tyler
145
  • String.contains() qui vérifie si la chaîne contient une séquence spécifiée de valeurs char
  • String.indexOf() qui renvoie l'index dans la chaîne de la première occurrence du caractère ou de la sous-chaîne spécifié (il existe 4 variantes de cette méthode)
Zach Scrivena
la source
15
un char n'est pas une CharSequence donc il ne peut pas être passé à String.contains (CharSequence).
mP.
28
Pour utiliser String.contains () avec un seul caractère c, procédez comme suit
friederbluemle
7
Ou faites-le si vous aimez le code court:String.contains(""+c)
Felix Neumeyer
31

Je ne sais pas exactement ce que l'affiche originale demande. Comme indexOf (...) et contains (...) utilisent tous deux probablement des boucles en interne, peut-être qu'il cherche à voir si cela est possible sans boucle? Je peux penser à deux manières différentes, l'une serait bien sûr la récurrence:

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'autre est beaucoup moins élégant, mais complet ...:

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

Le nombre de lignes augmente à mesure que vous avez besoin de supporter des chaînes de plus en plus longues bien sûr. Mais il n'y a pas du tout de boucles / récurrences. Vous pouvez même supprimer la vérification de la longueur si vous pensez que cette longueur () utilise une boucle.

Jack Leow
la source
10
Si vous définissez la récursivité comme une procédure sans boucle, vous êtes un geek: D +1 pour être créatif.
guerda
1
Tout est bon pour la longueur codée en dur de 5. Sinon, IL FAUT FAIRE UNE BOUCLE pour rechercher le personnage. Ne pas être pédant, mais la preuve en est donnée par la définition d'une machine de Turing. Les fondements d'un appareil informatique.
Salvador Valence
4
Corrigez-moi si je me trompe, je me sens à la fin de la journée, une récursivité est une boucle déguisée n'est-ce pas? Et cela peut entraîner une consommation de mémoire plus importante qu'une boucle ordinaire dans certains scénarios.
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
la source
1
n'est-ce pas le double exact de la réponse acceptée?, nous reconnaissons votre effort mais vous devriez essayer de trouver une question sans réponse et y répondre.
Shekhar_Pro
7

Vous pouvez utiliser 2 méthodes de la Stringclasse.

  • String.contains() qui vérifie si la chaîne contient une séquence spécifiée de valeurs char
  • String.indexOf() qui renvoie l'index dans la chaîne de la première occurrence du caractère ou de la sous-chaîne spécifié ou renvoie -1 si le caractère n'est pas trouvé (il existe 4 variantes de cette méthode)

Méthode 1:

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

Méthode 2:

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

Liens par: Zach Scrivena

Halfacht
la source
4

Pour vérifier si quelque chose n'existe pas dans une chaîne, vous devez au moins regarder chaque caractère d'une chaîne. Ainsi, même si vous n'utilisez pas explicitement une boucle, elle aura la même efficacité. Cela étant dit, vous pouvez essayer d'utiliser str.contains ("" + char).

mweiss
la source
D'accord. À un moment donné, quelqu'un, quelque part, a besoin de construire une boucle pour ce faire. Heureusement, l'API Java le fait ou notre code serait très encombré!
Fortyrunner
4

Si vous devez souvent vérifier la même chaîne, vous pouvez calculer les occurrences de caractères à l'avance. Il s'agit d'une implémentation qui utilise un tableau de bits contenu dans un tableau long:

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
la source
J'ai essayé votre solution sur un problème similaire que j'ai. Ma solution la plus proche était de plus de 1500 millisecondes pour la longueur de chaîne1 63k et la longueur de chaîne2 95k. Votre solution crache un résultat en 3 à 5 millisecondes. Pouvez-vous modifier votre solution pour inclure une explication? S'il vous plaît?
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
la source
2
et forn'est pas une boucle maintenant?
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'");

Production

string does not contains the char 's'
praveen
la source
La même réponse a déjà été fournie.
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
la source
Ici, nous recherchons les occurrences de chaque caractère de la chaîne b présent dans la chaîne a et supprimons les caractères.
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
la source
0

Est-ce que ce que vous cherchiez ci-dessous?

int index = string.indexOf(character);
return index != -1 && string.lastIndexOf(character) != index;
Toochka
la source
Pourquoi avez-vous && string.lastIndexOf(character) != index
GreenAsJade
-1

Vous ne pourrez pas vérifier si char apparaît du tout dans une chaîne sans au moins parcourir la chaîne une fois en utilisant boucle / récursivité (les méthodes intégrées comme indexOf utilisent également une boucle)

Si le non. de fois que vous recherchez si un caractère est dans la chaîne x est bien plus que la longueur de la chaîne que je recommanderais d'utiliser une structure de données Set car cela serait plus efficace que d'utiliser simplementindexOf

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

En utilisant set, vous pourrez vérifier si un caractère existe dans une chaîne à temps constant O (1) mais vous utiliserez également de la mémoire supplémentaire (la complexité de l'espace sera O (n)).

Dhyey
la source
-3

J'ai utilisé la méthode string.includes () pour cela qui retourne vrai ou faux si la chaîne ou le caractère est trouvé. Voir la documentation ci-dessous.

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

Udugam
la source
Bien que ce lien puisse répondre à la question, il est préférable d'inclure les parties essentielles de la réponse ici et de fournir le lien de référence. Les réponses de lien uniquement peuvent devenir invalides si la page liée change.
Adriano Martins
2
Cette réponse est pour JavaScript, la question précise en Java
Hazem Farahat
-4

// ce n'est que le principal ... vous pouvez utiliser un lecteur ou un scanner avec mémoire tampon

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... 
à tout moment
la source