import java.util.Scanner;
public class CountVowel{
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
Получение размера массива:
System.out.println("Type how many words will be typed: ");
int input = scan.nextInt();
Заполнение массива строковыми значениями
String[] ar1 = new String[input];
for(int i = 0; i < ar1.length; i++){
System.out.println("Type the elements of array with words: ");
ar1[i] = scan.next();
}
Вывод программы:
System.out.println( input + " words are typed and " +
countVowels(ar1) +
" of them contain more than 3 vowels.");
}
Метод подсчета гласных:
public static int countVowels(String[] ar1){ // this method counts
int a = 0;
String[] ar2 = new String[]{"a", "e", "i", "u", "y", "o"};
for(int i = 0; i < ar1.length; i++){
for(String s : ar2){
if (ar1[i].toLowerCase().contains(s)){
a++;
}
}
}
return a;
}
}
Вышеупомянутый метод заключается в проверке гласных, но я не знаю, как это проверить, если гласных больше 3-х.




public static int countVowels(String[] ar1) { // this method counts
int vowelPerWord = 0;
int totalWordsWithThreeVowels = 0;
char[] ar2 = new char[] { 'a', 'e', 'i', 'u', 'y', 'o' };
for (int i = 0; i < ar1.length; i++) {
vowelPerWord = 0;
for (int j = 0; j < ar1[i].length(); j++) {
for (int k = 0; k < ar2.length; k++) {
if (ar2[k] == (ar1[i].charAt(j))) {
vowelPerWord++;
}
}
}
if (vowelPerWord >= 3) {
totalWordsWithThreeVowels++;
}
}
return totalWordsWithThreeVowels;
}
РЕДАКТИРОВАТЬ
хорошо, теперь я исправил ошибку и отредактировал имена переменных, чтобы они имели больше смысла. хотя это O (n * m), я полагаю (где n - количество строк, а m - количество символов в самой длинной строке) (не очень хорошая сложность), он выполняет работу ar1 в этом случае это ваш ввод строки, ar2 — это просто существующие гласные.
поэтому вы просматриваете каждую строку в ar1 и устанавливаете «vowelPerWord» на 0, просматриваете каждый символ в каждой строке и проверяете, является ли это гласным, увеличиваете vowelPerWord на 1. в конце, после того, как вы прошли каждый символ этой строки вы проверяете, было ли 3 или более гласных, если да, увеличьте totalWordsWithThreeVowels, который в конце возвращается.
подождите, я исправляю ошибку в приведенном выше коде прямо сейчас
Дополнительный цикл увеличит сложность кода.
третий (самый внутренний) цикл всегда будет O (6), поэтому теоретически мы можем его игнорировать.
Хотя самый внутренний цикл действительно только 6, если есть, скажем, 1000 слов, самый внутренний цикл из 6 приводит к увеличению количества итераций с 1 000 000 до 6 000 000. Проблема с вложенным циклом, независимо от того, насколько он мал, что сложность возрастает в геометрической прогрессии. В настоящее время это сложность O(6 * N^2), где N — количество слов в ar1. PS: гласная петля 6 на самом деле не проблема здесь, это вложенная петля удвоенного ar1.
да, я знаю, я просто дал самое простое решение для кода, никаких странных регулярных выражений, так как задача больше походила на задачу для начинающих
@ Алан, я согласен. Хотя я лично также решил бы это с помощью лямбда-выражения Java 8 и регулярного выражения, для новичка лучше иметь небольшую модификацию кода, который у них уже есть, чтобы они могли учиться на нем. Я также не использовал регулярное выражение в своем ответе.
Вы можете использовать сопоставление регулярных выражений, чтобы определить, содержит ли строка какой-либо набор символов. Например, если вы хотите узнать, содержит ли строка какие-либо гласные, вы можете использовать:
String str = "yydyrf";
boolean contains = str.toLowerCase().matches(".*[aeiou].*");
System.out.println(contains);
Обновлено:
Таким образом, ваш код будет выглядеть так:
public static int countVowels(String[] ar1) {
int a = 0;
String[] ar2 = new String[] { "a", "e", "i", "u", "y", "o" };
String pattern = ".*[" + String.join("", ar2) + "].*";
for (int i = 0; i < ar1.length; i++) {
if (ar1[i].matches(pattern)) {
a++;
}
}
return a;
}
Хотя это действительно более простой способ, чем цикл и содержит, он не отвечает на вопрос ОП.
Что вам нужно, так это дополнительный цикл и счет. Что-то вроде этого:
// This method counts how many words have at least 3 vowels
public static int countVowels(String[] wordsArray){
int atLeastThreeVowelsCount = 0;
for(String word : wordsArray){
int vowelCount = 0;
for(String vowel : new String[]{ "a", "e", "i", "u", "y", "o" }){
if (word.toLowerCase().contains(vowel)){
vowelCount++;
}
}
if (vowelCount >= 3){
atLeastThreeVowelsCount++;
}
}
return atLeastThreeVowelsCount;
}
Обратите внимание, что я также дал переменным несколько более полезных имен вместо ar1, s и т. д., чтобы было легче читать, что происходит.
Другое решение с методом replaceAll.
Основная идея состоит в том, чтобы вычесть из word.length() ту же длину слова без гласных. И проверьте разницу.
public static int countVowels(String[] ar1){
int a = 0;
for (String word : ar1) {
int i = word.length() - word.toLowerCase().replaceAll("[aeyiuo]", "").length();
if (i >= 3) {
a++;
}
}
return a;
}
Или вы можете использовать matches(), как предложил @pkgajulapalli. Это может быть довольно лаконично с потоковым API:
long count = Arrays.stream(words)
.filter(s -> s.toLowerCase().matches("(.*[aeyiuo].*){3,}"))
.count();
В настоящее время не работает с гласными в верхнем регистре, используйте либо s.toLowerCase(), либо группу регулярных выражений [AaEeYyIiUuOo].
Да, из соображений производительности вы можете использовать предопределенный Pattern, сохраненный в статической переменной или что-то в этом роде, а затем использовать pattern.matcher(s).replaceAll("") :)
Вы можете использовать это:
public static int countVowels(String[] words) {
char[] chars = {'a', 'e', 'i', 'u', 'y', 'o'};
int wordsWith3Vowels = 0;
for (String word : words) {
int countedVowels = 0;
for (char s : chars) {
if (word.toLowerCase().indexOf(s) != -1) {
countedVowels++;
}
}
if (countedVowels >= 3) {
wordsWith3Vowels++;
}
}
return wordsWith3Vowels;
}
Который использует char вместо String, что немного быстрее
public static int countVowels(String[] ar1){ // this method counts
//Create hash map key = array string && value = vowels count
Map<String,Integer> mapVowels=new HashMap<String,Integer>();
int a = 0;
String[] ar2 = new String[]{"a", "e", "i", "u", "y", "o"};
for(int i = 0; i < ar1.length; i++){
for(String s : ar2){
if (ar1[i].toLowerCase().contains(s)){
//Check map string already has vowel count then increase by one
if (mapVowels.get(s)!=null) {
mapVowels.put(s,mapVowels.get(s)+1);
//After add the vowels count get actual count and check is it more than 3
if (mapVowels.get(s)>3)
a++;
}
else {
//If the vowels string new for map then add vowel count as 1 for first time
mapVowels.put(s,1);
}
}
}
}
return a;
}
Начиная с java-8, теперь вы можете использовать потоки.
String[] values = {"AA","BC","CD","AE"};
логическое значение содержит = Arrays.stream(values).anyMatch("s"::equals);
Чтобы проверить, содержит ли массив int, double или longvalue, используйте IntStream, DoubleStream или LongStream соответственно.
Пример int[] а = {1,2,3,4}; логическое значение содержит = IntStream.of(a).anyMatch(x -> x == 4);
Пожалуйста, объясните, что делает этот метод, и, возможно, также поясните, почему у вас есть 3 цикла
forи что именно делаютaиb.