Как добавлять, вычислять и фильтровать те элементы, которые меньше среднего, без использования повторяющихся циклов

#java

#java

Вопрос:

Я использую List структуру java ():

 var nums = List.of( 3, 9, 7, 12, 20, 4, 11, 9, 21, 6, 8, 10 );
 

Благодаря этому использованию я выполняю следующую программу без необходимости использования повторяющихся циклов:

     package averagesumwithoutcycles;
    import java.util.*;
    import java.util.List;
    
    public class SumaSinCiclos {
        
        private static int suma = 0;
    
    public static void main(String[] args) {
        int[] nums = {3, 9, 7, 12, 20, 4, 11, 9, 21, 6, 8, 10};
        System.out.println(average(nums, 0));
    }
    
    public static float average(int n[], int pos){
        float resultado = (float)suma /(float)n.length;
        if(pos < n.length) {
            suma = suma   n[pos];
            average(n, pos   1);
            System.out.println(resultado);
        }
        return resultado;
    }
        
    }
 

До сих пор я добился следующего:

  • Сумма элементов массива
  • Количество элементов в массиве
  • Результат деления (среднее значение)

Мой вопрос заключается в следующем, основываясь на моем коде, как я могу суммировать элементы ( array ), вычислять среднее значение и фильтровать те элементы, которые меньше среднего.

Примечание: важно получить эти данные без использования повторяющихся циклов

Комментарии:

1. Вы имеете в виду, что не хотите использовать циклы for и while? Вы используете рекурсию, которая в основном уже является циклом

2. @Mick Серьезно? ну, они упомянули тему об использовании списка, я не должен использовать повторяющиеся циклы, подобные этим: for, while, do while

3. У меня нет для вас кода, но я могу предложить отсортировать массив с помощью рекурсии и одновременно вычислить позицию (индекс) среднего элемента. Затем вы можете получить «нижнюю» часть массива, которая находится перед средним индексом.

4. @Mick Я подумал, что, не будучи одним из них for, while, do while в коде, я бы соблюдал это условие не использовать повторяющиеся циклы.

5. Ну, технически это отличается от итеративного цикла, но это все равно рекурсивный цикл. Это школьный проект или что-то в этом роде? Я бы не рекомендовал использовать рекурсию для чего-то подобного в практическом приложении

Ответ №1:

Вот наилучший возможный ответ, на мой взгляд. Он использует внутренние циклы, но любое возможное решение для получения суммы массива требует цикла (итеративного или рекурсивного).

 import java.util.Arrays;
import java.util.stream.IntStream;

class Main {  
    private static int suma = 0;

    public static void main(String[] args) {
        int[] nums = {3, 9, 7, 12, 20, 4, 11, 9, 21, 6, 8, 10};
        for (int num : nums) {
            System.out.println(num);
        }
        nums = filter(nums, average(nums));
        System.out.println("____________n");
        for (int num : nums) {
            System.out.println(num);
        }
    }
    
    public static float average(int[] n){
        float suma = IntStream.of(n).sum();
        return suma / n.length;
    }
    
    public static int[] filter(int[] nums, float average) {
        return Arrays.stream(nums).filter(x -> x >= average).toArray();
    }
}
 

Комментарии:

1. Вы действительно думаете, что использование потоков здесь уместно?

2. Я думаю, что это единственный способ без явного использования цикла или рекурсии

3. @Mick Спасибо за вклад, но использование for и повторяющихся циклов не будет принято, конечно, использование циклов проще и облегчает работу, но темы стремятся усложнить программы 🙁

4. Циклы for предназначены только для печати результата, потоки выполняют фактическую работу. В любом случае, я не уверен, какова цель. Использование рекурсии для чего-то подобного не выгодно и приведет к сбою для массива, превышающего длину 1000

5. @Mick Teacher стремится усложнить нашу работу, это нельзя было использовать, потому что вы не используете структуру данных Java list, я подумал, что предмет может быть немного проще.

Ответ №2:

Вы всегда можете сделать что-то подобное (но это громоздко).

 int[] vals = {10,2,8}; 
int sum = 0;
sum  = vals[0];
sum  = vals[1];
sum  = vals[2];
double avg = (double)sum/vals.length;

List<Integer> lessThan = new ArrayList<>();
if (vals[0] < avg) {
  lessThan.add(vals[0]);
}
if (vals[1] < avg) {
  lessThan.add(vals[1]);
}
if (vals[2] < avg) {
  lessThan.add(vals[2]);
}
System.out.println(lessThan); // prints 2

 
 var nums = List.of( 3, 9, 7, 12, 20, 4, 11, 9, 21, 6, 8, 10 );

int sum = 0;
for (int v : nums) {
   sum =v;
}
double avg = (double)sum/v.size();
 

как только у вас будет среднее значение, вы можете найти те, которые меньше, следующим образом.

 vars lessThan = new ArrayList<>();
for (int v : nums) {
    // store the numbers that are less than avg in the list.
}
Then print them here.
 

Комментарии:

1. @WSJ Правда в том, но что мы можем сделать с инструктором. Друг, как мне распечатать данные по отдельности: сумму элементов, среднее и наименьшее среднее.

2. Я бы посоветовал, если еще не слишком поздно, попросить инструктора уточнить, что требуется. Я предполагаю, что электронное письмо сработает.

3. @WSJ Это sum = vals[0]; я должен добавить по одному для каждого элемента в массиве?

4. @WSJ Нет времени, в 23:59 я должен загрузить эту тему.

5. @WSJ Следующим образом у меня есть общая сумма элементов массива ideone.com/kTwVbx

Ответ №3:

Может быть, я что-то упускаю, но, похоже, вы решили проблему. В вашем коде у вас есть сумма элементов и среднее значение, и вы не используете явный цикл.

Единственная проблема заключается в том, что те элементы, которые меньше среднего. Возможным решением может быть использование выделенной рекурсивной функции с того момента, как вы завершили свою первую рекурсию (передайте все элементы и сверьте их со средним значением [у вас уже есть] один за другим при рекурсии).

Может быть, что-то вроде:

 public static void main(String[] args) {
    int[] nums = {3, 9, 7, 12, 20, 4, 11, 9, 21, 6, 8, 10};
    System.out.println(average(nums, 0, nums)); // Added "nums" again
}

public static float average(int n[], int pos, int originalElements[]){
    float resultado = (float)suma /(float)n.length;
    if(pos < n.length) {
        suma = suma   n[pos];
        average(n, pos   1, originalElements);
        System.out.println(resultado);
    } else {
        // you will get hete only ONCE, in case pos = n.length
        // note that in this state, "resultado" contains the original array's average
        checkSmallThanAverage(resultado, 0, originalElements);
    }
    return resultado;
}

public static void checkSmallThanAverage(float resultado, int pos, int originalElements[]) {
     if(pos < originalElements.length) {
         if (originalElements[pos] < resultado) {
             System.out.println("element "   originalElements[pos]   " is smaller than average");
         }
         checkSmallThanAverage(resultado, pos 1, originalElements);
     }
}
 

Комментарии:

1. Не могли бы вы сказать мне, какую строку кода я должен добавить в свой код, пожалуйста?