Как я могу проверить, появляется ли один символ в строке?


210

В Java есть способ проверить условие:

«Появляется ли этот единственный символ вообще в строке x»

без использования цикла?


4
Есть ли какая-то конкретная причина, по которой вы пытаетесь избежать петель?
Штеймер

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

4
Мы должны предположить, что @barfoon не хочет, чтобы цикл был в их коде. Очевидно, машина где-то делает цикл. В противном случае вопрос глупость.
WW.

Я бы сказал, что манипулирование строками Java довольно ограничено
ACV

Ответы:


276

Вы можете использовать string.indexOf('a').

Если символ aприсутствует в string:

он возвращает индекс первого вхождения символа в последовательности символов, представленной этим объектом, или -1, если символ не встречается.


8
Но за этим вызовом всегда есть петля, потому что иначе вы не сможете найти символ.
Вава

4
indexOf () использует цикл внутри.
mmcdole

22
Это не то, что спросил Барфун. B хочет избежать выполнения цикла в коде B. Естественно, API должен делать цикл, поскольку String - это массив символов, заключенных в хороший класс с множеством полезных методов.
мП

5
Как эти ответы получают так много голосов? Решения использования indexOf()использует цикл внутри. Ни один из ответов не дает правильного решения, и если кто-то осмеливается задать новый вопрос, люди заявляют об этом Duplicate. Действительно разочаровывает; (
Прашант Прабхакар Сингх

4
@PrashantPrabhakarSingh Я не понимаю, как это можно сделать без цикла. Строка - это более или менее группа символов. Если это группа (коллекция, массив и т. Д.), То независимо от того, является ли она внутренней или внешней по отношению к нативному коду, я ожидаю, что вам понадобится цикл, чтобы найти что-то в «группе». Я верю "без использования цикла?" больше похоже на «без написания собственного цикла?».
Тайлер

145
  • String.contains() который проверяет, содержит ли строка указанную последовательность значений символов
  • String.indexOf() который возвращает индекс в строке первого вхождения указанного символа или подстроки (есть 4 варианта этого метода)

15
char не является 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() который проверяет, содержит ли строка указанную последовательность значений символов
  • 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не петля сейчас?
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'");

Вывод

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

Здесь мы ищем вхождения каждого символа из строки b, присутствующего в строке 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

Вы не сможете проверить, присутствует ли вообще символ в какой-либо строке, не перебирая строку по крайней мере один раз с использованием цикла / рекурсии (встроенные методы, такие как 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

Используя set, вы сможете проверить, существует ли символ в строке за постоянное время O (1), но вы также будете использовать дополнительную память (сложность пробела будет O (n)).


-3

Для этого я использовал метод string.include (), который возвращает true или false, если найдена строка или символ. Смотрите ниже документацию.

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


Хотя эта ссылка может ответить на вопрос, лучше включить сюда основные части ответа и предоставить ссылку для справки. Ответы, содержащие только ссылки, могут стать недействительными, если связанная страница изменится.
Адриано Мартинс,

2
Этот ответ для JavaScript, этот вопрос специально говорят на Java
Хазем Фарахат

-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.