Я новичок в Java, и я делаю этот курс, и мне нужна помощь в этом. По сути, пользователь вводит строку, а затем программа выводит только гласные в одной строке.
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner inp = new Scanner(System.in);
System.out.print("In:");
String word = inp.nextLine();
//write your code below
for(int whatsat = 0; whatsat < word.length(); whatsat++){
if (word.charAt(whatsat).equals("a")){ //how to declare mutiple letters?
System.out.print(word.charAt(whatsat));
}
}
}
}
Исследуйте регулярные выражения Java, которые в этом случае позволили бы быстро извлечь только гласные. «Шаблон» — важная часть возможностей регулярных выражений Java.




Я согласен с @Logan. Вы не используете equals() для сравнения значений примитивного типа (int, char, boolean и т. д.), просто используйте простое выражение ==.
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner inp = new Scanner(System.in);
System.out.print("In:");
String word = inp.nextLine();
//write your code below
for(int whatsat = 0; whatsat < word.length(); whatsat++){
char c = Character.toLowerCase(word.charAt(whatsat));
if (c == 'a' || c == 'e'|| c == 'i' || c == 'o' || c == 'u'){
System.out.print(word.charAt(whatsat));
}
}
}
}
Итак, здесь есть две проблемы:
Чтобы сравнить символы, сделайте что-то вроде:
if (word.charAt(whatsat) == 'a') {
...
}
Обратите внимание на одинарные кавычки! 'a' не "a"!
Если вы спрашиваете «почему сравнение строк и символов отличается?», это хороший вопрос. На самом деле я не знаю причину, так что мы оба должны исследовать ее. Идем дальше.
Чтобы проверить наличие нескольких символов:
for(int whatsat = 0; whatsat < word.length(); whatsat++){
if (word.charAt(whatsat) == 'a' || word.charAt(whatsat) == 'e' || word.charAt(whatsat) == 'i'){
System.out.print(word.charAt(whatsat));
}
}
Обратите внимание, что если вы вводите заглавные буквы, вам нужно:
if (...word.charAt(whatsat) == 'A' ...)
В долгосрочной перспективе вы захотите изучить регулярные выражения, как предложил Адриан в комментариях. Это может быть сложно для начинающего студента, но если вам интересно, вы должны изучить это.
Надеюсь это поможет.
Не обижайтесь, но если вашей следующей задачей будет выписать все согласные вместо гласных, что вы тогда будете делать? Конечно, не выписывайте операторы 21 или (||)... К сожалению, ваше решение не является хорошей практикой или не очень масштабируемо для нескольких символов.
@ vs97 Ничего не занято! Абсолютно согласен. Смогу ли я заниматься этим профессионально? Нет, конечно нет. Но если я даю совет начинающему студенту CS, который только изучает разницу между строками и символами, я собираюсь адаптировать свой ответ к их уровню. Я не удивлюсь, если они только что узнали, что делает if; Могу ли я ожидать, что они будут знать о перечислениях и множествах?
Простой способ сделать это (намеренно избегая сложных параметров регулярного выражения) — использовать метод String.indexOf() в вашем цикле.
В приведенном ниже примере мы в основном проверяем, содержит ли «AEIOUaeiou» char, который мы извлекаем из пользовательского ввода. Если это так, мы извлекаем его:
public static void main(String[] args) {
Scanner inp = new Scanner(System.in);
System.out.print("In:");
String word = inp.nextLine();
//write your code below
// This will hold any matching vowels we find
StringBuilder sb = new StringBuilder();
for (int i = 0; i < word.length(); i++) {
// Check if our list of vowels contains the current char. If the current char exists in the String of vowels, it will have an index of 0 or greater.
if ("AEIOUaeiou".indexOf(word.charAt(i)) > -1) {
// If so, add it to our StringBuilder
sb.append(word.charAt(i));
}
}
// Finally, print the result
System.out.println(sb.toString());
}
Результат:
При тестовом вводе «Это мой тестовый ввод. Он сработал?» вывод: iieiuiio
Вы можете упростить это, используя indexOf > -1 и избегая String.valueOf
Я не уверен, какой метод "проще", но да, это тоже сработает :)
С точки зрения проверки, безусловно, проще искать символ в строке по сравнению с поиском строки в строке, как вопрос ветвления/цикла
Это все еще решение O (n ^ 2) из-за внутренней функции indexOf
Я В самом деле удивлен, что никто не предложил использовать Enums... Самый чистый и простой способ, на мой взгляд.
Просто определите Enum со всеми гласными, просмотрите строку и сравните каждый символ со значениями внутри Enum, игнорирование дела — обратите внимание на приведение char к String. Если он присутствует в Enum, распечатайте его.
public class VowelFind {
enum Vowels {
A, E, I, O, U
}
public static void main(String[] args) {
Scanner inp = new Scanner(System.in);
System.out.print("In:");
String word = inp.nextLine();
for (int i = 0; i < word.length(); i++) { //loop through word
for (Vowels v : Vowels.values()) { //loop through Enum values
if ((word.charAt(i)+"").equalsIgnoreCase(v.name())) { //compare character to Enum value, ignoring case
System.out.print(word.charAt(i));
}
}
}
}
}
Input: Hello World
Output: eoo
Вы понимаете, что это решение O (n ^ 2), что хуже, чем O (n), то есть вы можете сделать то же самое в одном цикле вместо двух.
Если это не так, рассмотрите возможность запуска того же кода для слова из 1 миллиона букв.
Использование вложенных циклов, безусловно, не самый чистый и простой способ добиться этого...
O(n²) означает, что у вас есть 2 вложенных цикла, которые растут на основе входных данных, однако вложенный цикл не растет на основе входных данных, поскольку он имеет постоянный набор итераций. Это означает, что это цикл O (1). В свою очередь, весь алгоритм становится O (n)
@Минн посмотри stackoverflow.com/questions/27089438/complexity-of-enum-values
Хорошо, у вас, кажется, есть фундаментальное непонимание того, как работает нотация большого O. O (n) означает, что ваш алгоритм усложняется на основе входных аргументов за линейное время, если у вас есть 2 вложенных цикла, которые повторяют весь ввод, у вас есть n * n операций, также известных как O (n²). В этом случае у вас есть вложенный цикл, который всегда имеет одинаковое количество итераций независимо от ввода. Это означает его константу, которая обозначается как O(1). Здесь вводом является слово, а не массив значений. Было бы O(n²), если бы обе петли были на входе, но это не так.
Я думаю, вы все еще не поняли, что я пытаюсь сказать. Даже если Vowels.values() кажется постоянной операцией, это еще хуже, потому что каждый раз, когда вы вызываете Vowels.values(), создается новый массив; что по-прежнему является операцией O (n). Этот сценарий похож на объединение строк внутри цикла.
Это не делает его O (n²), как вы утверждали.
Я предпочитаю использовать Hashmap, поскольку поиск выполняется O (1)
public class PrintVowelsInWord {
public static Map<Character, Character> vowels;
public static void main(String[] args) {
loadMap();
// for simplicity sake I am not using Scanner code here
getVowels("wewillrockyou");
}
public static void loadMap() {
if (vowels == null) {
vowels = new HashMap<>();
vowels.put('a', 'a');
vowels.put('e', 'e');
vowels.put('i', 'i');
vowels.put('o', 'o');
vowels.put('u', 'u');
}
}
public static void getVowels(String input) {
for (Character letter : input.toCharArray()) {
if (vowels.containsKey(letter)) {
System.out.print(letter);
}
}
}
}
Это может быть O (1), но эта константа довольно плоха с точки зрения производительности из-за хэширования и поиска, а также из-за накладных расходов из-за упаковки символов.
Рассмотрим случай, если он хочет найти какие-то случайные буквы. Ваша карта действительно будет расти, и код может стать загрязненным.
@Minn Предположим, что входные данные представляют собой всю прозу Шекспира, хеширование для 5 гласных будет выполнено один раз, а карту можно сделать статической. Эта карта не постоянно растет как (есть только 5 возможных гласных).
@Pant Почему карта должна расти? Для случайных писем требования другие и, следовательно, другое решение :)
Я предполагаю, что мое доказательство концепции в main() запутало то, что я пытался донести. Здесь отредактировал мой код.
Обратите внимание, что
charAt()возвращаетchar, у которого нет методаequals()(или каких-либо методов).