如何检查一个字符是否出现在字符串中?

在Java中有一种方法来检查条件:

"这个字符是否出现在字符串x中"

没有使用循环?

1184969 次浏览

你可以使用string.indexOf('a')

如果字符a出现在string中:

它返回in中第一个出现的字符的索引 对象表示的字符序列,或-1

.字符不出现

要检查字符串中是否存在某些东西,您至少需要查看字符串中的每个字符。所以即使你没有显式地使用循环,它也会有同样的效率。也就是说,您可以尝试使用str.contains(""+char)。

是的,在字符串类上使用indexOf()方法。请参阅此方法的API文档

我不确定最初的海报到底想要什么。由于indexOf(…)和contains(…)都在可能内部使用循环,也许他想看看如果没有循环这是否可行?我可以想到两种方法,一种当然是递归

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

当然,行数会随着您需要支持越来越长的字符串而增长。但是根本没有循环/递归。如果您担心length()使用循环,您甚至可以删除长度检查。

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

如果您需要经常检查相同的字符串,您可以预先计算字符出现的次数。这是一个使用位数组包含在长数组中的实现:

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

你可以使用String类中的两个方法。

方法1:

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

方法2:

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

链接by: 扎克Scrivena

这是你要找的吗?

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

如果不使用循环/递归至少检查一次字符串,您将无法检查char是否出现在某些字符串中(像indexOf这样的内置方法也使用循环)

如果不是。如果你在字符串中查找一个字符,x比字符串的长度要多得多,我建议使用数据结构,因为这比简单地使用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))。

如果你在JAVA中看到indexOf的源代码:

public int indexOf(int ch, int fromIndex) {


final int max = value.length;


if (fromIndex < 0) {


fromIndex = 0;


} else if (fromIndex >= max) {


// Note: fromIndex might be near -1>>>1.


return -1;


}




if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {


// handle most cases here (ch is a BMP code point or a


// negative value (invalid code point))


final char[] value = this.value;


for (int i = fromIndex; i < max; i++) {


if (value[i] == ch) {


return i;


}


}


return -1;


} else {


return indexOfSupplementary(ch, fromIndex);


}


}

你可以看到它使用for循环来查找字符。注意,你在代码中使用的每一个indexOf都等于一个循环。

因此,对于单个字符使用循环是不可避免的。

然而,如果你想找到一个具有更多不同形式的特殊字符串,使用有用的库,如util.regex,它部署了更强的算法来匹配字符或字符串模式与正则表达式。例如,在字符串中查找电子邮件:

String regex = "^(.+)@(.+)$";
 

Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(email);

如果你不喜欢使用正则表达式,只需使用循环和charAt,并尝试在一个循环中覆盖所有情况。

注意递归方法比循环方法有更多的开销,所以不推荐使用。

String.contains(String)String.indexOf(String) -建议

"abc".contains("Z"); // false - correct
"zzzz".contains("Z"); // false - correct
"Z".contains("Z"); // true - correct
"😀and😀".contains("😀"); // true - correct
"😀and😀".contains("😂"); // false - correct
"😀and😀".indexOf("😀"); // 0 - correct
"😀and😀".indexOf("😂"); // -1 - correct

String.indexOf(int)和仔细考虑的String.indexOf(char)与char int扩大

"😀and😀".indexOf("😀".charAt(0)); // 0 though incorrect usage has correct output due to portion of correct data
"😀and😀".indexOf("😂".charAt(0)); // 0 -- incorrect usage and ambiguous result
"😀and😀".indexOf("😂".codePointAt(0)); // -1 -- correct usage and correct output

在Java世界中,关于字符的讨论是模棱两可的

charCharacter的值可以被视为单个字符吗?

没有。在unicode字符的上下文中,charCharacter有时可以是part of a single character,在逻辑上不应该被视为a complete single character

如果不是,什么应该被认为是单个字符(逻辑上)?

任何支持Unicode字符字符编码的系统都应将Unicode的码点视为单个字符。

所以Java应该做得很清楚&响亮而不是向用户暴露太多的内部实现细节。

String类不擅长抽象(尽管它需要大量的understanding of its encapsulations to understand the abstraction 😒😒😒,因此需要anti-pattern)。

它与一般的char用法有何不同?

char只能映射到基本多语言平面中的一个字符。

只有codePoint - int可以覆盖Unicode字符的完整范围。

为什么会有这种差异?

char在内部被视为16-bit无符号值,不能使用UTF-16内部表示仅使用2-bytes表示所有unicode字符。有时候,16-bit范围内的值必须与另一个16-bit值组合才能正确定义字符。

在不太冗长的情况下,indexOfcharAtlength和这类方法的用法应该更显式。真诚地希望Java将添加新的具有明确定义的抽象的UnicodeStringUnicodeCharacter类。

选择contains而不是indexOf(int)的原因

  1. 实际上,在java中有许多代码流将逻辑字符视为char
  2. 在Unicode上下文中,char是不够的
  3. 虽然indexOf接受int,但charint的转换对用户隐藏了这一点,用户可能会执行类似str.indexOf(someotherstr.charAt(0))的操作(除非用户知道确切的上下文)。
  4. 因此,将所有内容都处理为CharSequence(又名String)更好
    public static void main(String[] args) {
System.out.println("😀and😀".indexOf("😀".charAt(0))); // 0 though incorrect usage has correct output due to portion of correct data
System.out.println("😀and😀".indexOf("😂".charAt(0))); // 0 -- incorrect usage and ambiguous result
System.out.println("😀and😀".indexOf("😂".codePointAt(0))); // -1 -- correct usage and correct output
System.out.println("😀and😀".contains("😀")); // true - correct
System.out.println("😀and😀".contains("😂")); // false - correct
}

语义

  1. char可以处理大多数实际用例。为了将来的可扩展性,最好在编程环境中使用代码点。
  2. codepoint应该处理几乎所有关于编码的技术用例。
  3. 不过,字形集群不属于codepoint抽象级别的范围。
  4. 如果__abc1太昂贵(翻倍),存储层可以选择char接口。除非存储成本是唯一的度量标准,否则最好使用codepoint。此外,最好将存储视为byte,并将语义委托给围绕存储构建的业务逻辑。
  5. 语义可以在多个层次上进行抽象。codepoint应该成为接口的最低级别,在运行时环境中可以围绕codepoint构建其他语义。

如果有人用这个;

let text = "Hello world, welcome to the universe.";
let result = text.includes("world");
console.log(result) ....// true

结果将是truefalse

这对我来说总是有效的