如何检查字符串是否包含字母表的所有字母?

2022-09-04 04:59:17

我正在尝试检查字符串是否包含字母表的所有字母。我创建了一个包含整个字母表的内容。我将字符串转换为char数组,并且我正在迭代字符数组,并且对于内存中删除元素中的每个字符。最后,我试图检查是否为空,以查看是否所有元素都已被删除。这将指示字符串包含字母表的所有字母。ArrayListArrayListArraylist

不幸的是,代码在我从数组列表中删除元素的if条件中引发错误IndexOutOfBoundsException

List<Character> alphabets = new ArrayList<Character>();

alphabets.add('a');
alphabets.add('b');
alphabets.add('c');
alphabets.add('d');
alphabets.add('e');
alphabets.add('f');
alphabets.add('g');
alphabets.add('h');
alphabets.add('i');
alphabets.add('j');
alphabets.add('k');
alphabets.add('l');
alphabets.add('m');
alphabets.add('n');
alphabets.add('o');
alphabets.add('p');
alphabets.add('q');
alphabets.add('r');
alphabets.add('s');
alphabets.add('t');
alphabets.add('u');
alphabets.add('v');
alphabets.add('w');
alphabets.add('x');
alphabets.add('y');
alphabets.add('z');

// This is the string- I've just put a random example
String str = "a dog is running crazily on the ground who doesn't care about the world";

//Remove all the spaces
str = str.replace(" ", "");

// Convert the string to character array
char[] strChar = str.toCharArray();

for (int i = 0; i < strChar.length; i++) {

    char inp = strChar[i];

    if (alphabets.contains(inp)) {
        alphabets.remove(inp);
    }
}

if (alphabets.isEmpty())
    System.out.println("String contains all alphabets");
else
    System.out.println("String DOESN'T contains all alphabets");

答案 1

所有这些解决方案似乎都为相对简单的检查做了很多工作,特别是考虑到Java 8的流API:

/* Your lowercase string */.chars()
    .filter(i -> i >= 'a' && i <= 'z')
    .distinct().count() == 26;

编辑:为了速度

如果要在找到整个字母表后立即结束字符串迭代,同时仍在使用流,则可以在内部跟踪:HashSet

Set<Integer> chars = new HashSet<>();
String s = /* Your lowercase string */;
s.length() > 25 && s.chars()
    .filter(i -> i >= 'a' && i <= 'z') //only alphabet
    .filter(chars::add)                //add to our tracking set if we reach this point
    .filter(i -> chars.size() == 26)   //filter the 26th letter found
    .findAny().isPresent();            //if the 26th is found, return

这样,一旦填充了 26 个必需的字符,流就会停止。Set

在下面的性能方面有一些(甚至仍然)更有效的解决方案,但作为个人说明,我会说不要让自己过早地陷入过多的优化,在那里你可以有可读性和更少的工作量来编写实际代码。


答案 2

List.remove按索引删除。由于可以将 a 转换为 int,因此可以有效地删除不存在的索引值,即 char 'a' 等于 int 97。如您所见,您的列表没有97个条目。char

你可以做alphabet.remove(alphabets.indexOf(inp));

正如@Scary Wombat(https://stackoverflow.com/a/39263836/1226744)和@Kevin Esche(https://stackoverflow.com/a/39263917/1226744)所指出的那样,有更好的算法替代方案。