Як я можу перевірити, чи в рядку відображається один символ?


210

У Java існує спосіб перевірити стан:

"Чи відображається цей єдиний символ у рядку x"

без використання петлі?


4
Чи є якась конкретна причина того, що ви намагаєтеся уникати циклів?
shsteimer

2
Ви не можете зробити загальний пошук символу без циклу. Подивіться, як працює машина Тюрінга.
Сальвадор Валенсія

4
Ми повинні припустити, що @barfoon не хоче, щоб цикл містився у їхньому коді. Очевидно, що машина десь робить цикл. Інакше питання - нісенітниця.
ВВ.

Я б сказав, що стрибна маніпуляція з Java досить обмежена
ACV

Відповіді:


276

Можна використовувати string.indexOf('a').

Якщо картка aприсутня в string:

він повертає індекс першого появи символу в послідовності символів, представленому цим об'єктом, або -1, якщо символ не відбувається.


8
Але завжди є цикл за цим викликом, тому що ви не можете знайти символ інакше.
vava

4
indexOf () використовує цикл внутрішньо.
mmcdole

22
Це не те, що просив Барфун. B хоче уникати циклу в коді B. Звичайно, API потрібно робити цикл, адже String - це масив символів, загорнутий у хороший клас із безліччю корисних методів.
мП.

5
Як ці відповіді отримують стільки відгуків? Рішення використання indexOf()використовує цикл внутрішньо. Жодна з відповідей не дає правильного рішення, і якщо хтось наважиться задати нове питання, люди заявляють про це Duplicate. Дійсно розчаровуєшся (
Прашант Прабхакар Сінгх

4
@PrashantPrabhakarSingh Я не бачу, як це можна зробити без циклу. Рядок - це більш-менш група символів. Якщо це група (колекція, масив тощо), то незалежно від того, чи є він внутрішнім чи зовнішнім для нативного коду, я би сподівався, що вам знадобиться цикл для того, щоб знайти щось у "групі". Я вважаю, "без використання циклу?" більше схоже на "без написання власного циклу?".
Тайлер

145
  • String.contains() який перевіряє, чи містить рядок задану послідовність знаків char
  • String.indexOf() який повертає індекс у рядку першої появи вказаного символу або підрядка (є 4 варіанти цього методу)

15
char isnt не CharSequence, тому його не можна передавати String.contains (CharSequence).
мП.

28
Щоб використовувати String.contains () з одним знаком
friederbluemle

7
Або зробіть це, якщо вам подобається короткий код:String.contains(""+c)
Фелікс Номейер

31

Я не впевнений, що саме запитує оригінальний плакат. Оскільки indexOf (...) і містить (...) обидва, ймовірно, використовують петлі внутрішньо, можливо, він шукає, чи можливо це взагалі без циклу? Я можу придумати два способи, звичайно, це буде рекурсія:

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

Інший набагато менш елегантний, але повнота ...:

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

Кількість рядків зростає, оскільки вам потрібно підтримувати більш довгі і довші рядки. Але циклів / рекурсій взагалі немає. Ви навіть можете зняти перевірку довжини, якщо ви стурбовані тим, що для цієї довжини () використовується цикл.


10
Якщо ви визначаєте рекурсію як процедуру, що не стосується циклу, ви є видовищем: D +1 для творчості.
guerda

1
Це все добре для жорстко закодованої довжини 5. Інакше НЕОБХІДНО ЗРОБИТИСЯ, щоб шукати персонажа. Це не педантично, але доказом цього є визначення машини Тьюрінга. Фундамент обчислювального пристрою.
Сальвадор Валенсія

4
Виправте мене, якщо я помиляюся, я відчуваю в кінці дня, рекурсія - це петля в маскуванні, чи не так? І це може призвести до більшого споживання пам'яті, ніж звичайний цикл у деяких сценаріях.
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
Це не точний дублікат прийнятої відповіді? Ми визнаємо ваші зусилля, але вам слід спробувати знайти якесь питання без відповіді і відповісти на них.
Shekhar_Pro

7

Можна використовувати 2 методи з Stringкласу.

  • String.contains() який перевіряє, чи містить рядок задану послідовність знаків char
  • String.indexOf() який повертає індекс у рядку першої появи вказаного символу або підрядка або повертає -1, якщо символ не знайдено (є 4 варіанти цього методу)

Спосіб 1:

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

Спосіб 2:

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

Посилання: Зак Скривена


4

Щоб перевірити, чи щось у рядку не існує, вам потрібно принаймні подивитися кожен символ у рядку. Тож навіть якщо ви явно не використовуєте цикл, він матиме таку ж ефективність. Якщо говорити, ви можете спробувати використовувати str.contains ("" + char).


Домовились. У якийсь момент комусь десь потрібно побудувати цикл для цього. На щастя, Java API робить це, або наш код буде дуже захаращений!
Fortyrunner

4

Якщо вам потрібно перевіряти один і той же рядок, ви можете часто обчислити кількість символів. Це реалізація, яка використовує бітовий масив, що міститься у довгому масиві:

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

Я спробував ваше рішення щодо подібної проблеми. Моїм найближчим рішенням було понад 1500 мілісекунд для string1 довжиною 63k та string2 довжиною 95k. Ваше рішення випльовує результат за 3-5 мілісекунд. Чи можете ви відредагувати рішення, щоб включити пояснення? Будь ласка?
Віорел Флоріан


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
і forчи не це петля зараз?
Міндвін

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'");

Вихідні дані

string does not contains the char 's'

Таку ж відповідь було надано і раніше.
Серж Бєлов

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

Тут ми шукаємо події кожного персонажа зі String b, присутнього в String a, та видалення символів.
Ганешмані

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

Це нижче те, що ви шукали?

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

Чому у вас && string.lastIndexOf(character) != index
GreenAsJade

-1

Ви не зможете перевірити, чи відображається char взагалі в якомусь рядку, не маючи при цьому переходу рядка один раз за допомогою циклу / рекурсії (вбудовані методи, такі як indexOf також використовують цикл)

Якщо ні. раз, коли ви шукаєте, якщо знак знаходиться в рядку x, це набагато більше, ніж довжина рядка, ніж я б рекомендував використовувати структуру даних Set, оскільки це було б більш ефективно, ніж просто використовуватиindexOf

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

За допомогою набору ви зможете перевірити, чи існує символ у рядку в постійний час O (1), але ви також будете використовувати додаткову пам'ять (Складність простору буде O (n)).


-3

Для цього я використовував метод string.includes (), який повертає значення true або false, якщо знайдено рядок або символ. Дивіться нижче документацію.

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


Хоча це посилання може відповісти на питання, краще включити сюди суттєві частини відповіді та надати посилання для довідки. Відповіді лише на посилання можуть стати недійсними, якщо пов’язана сторінка зміниться.
Адріано Мартінс

2
Ця відповідь стосується JavaScript, питання спеціально сказано на Java
Hazem Farahat

-4

// це лише головне ... ви можете використовувати зчитуваний буфер чи сканер

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... 
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.