365 / 247 / 24
Регистрация: 03.04.2011
Сообщений: 558
Записей в блоге: 1
1

написать функцию для нахождения среднего массива типа double

25.08.2011, 04:45. Показов 3861. Ответов 37
Метки нет (Все метки)

Очень надеюсь, что модераторы не переместят данную тему, так как она посвящается именно пользователям с++ builder.


Задача: написать функцию для нахождения среднего массива типа double

Условия:
  1. Программа должна быть консольной
  2. Использовать только стандартные функции (STL использовать нельзя, а так же STL algorithm)
  3. Функция должна быть максимально производительной

Пояснение, в функцию мы передаем массив типа double и число элементов в массиве
Пример:
C++
1
2
double a[10];
double res = get(a,10);
Жду ваши варианты!
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
25.08.2011, 04:45
Ответы с готовыми решениями:

Написать функцию,для нахождения среднего арифметического отрицательных элементов
Нужно написать функцию,для нахождения среднего арифметического отрицательных элементов...

Написать программу для нахождения количества значений элементов массива меньших среднего арифметического
1. Дан двумерный числовой массив A состоящий из 35*35 элементов. Написать программу для нахождения...

Написать функцию нахождения среднего арифметического
Прошу помощи глупому студенту:-| Само задание "Написать функцию нахождения среднего...

Написать функцию нахождения среднего геометрического
Надо найти среднее геометрическое нескольких чисел

37
3093 / 2413 / 256
Регистрация: 11.03.2009
Сообщений: 5,450
25.08.2011, 06:05 2
1. Почему собственно консольная программа со стандартными функциями посвещена именно пользователям с++ builder?
2. Что такое средний массив?
1
365 / 247 / 24
Регистрация: 03.04.2011
Сообщений: 558
Записей в блоге: 1
25.08.2011, 06:12  [ТС] 3
Цитата Сообщение от kazak Посмотреть сообщение
средний массив
Опечатался)) среднее значение в массиве!!!))

Цитата Сообщение от kazak Посмотреть сообщение
Почему собственно консольная программа со стандартными функциями посвещена именно пользователям с++ builder?
Так нужно)) без лишних вопросов!
0
1280 / 598 / 116
Регистрация: 18.08.2009
Сообщений: 832
25.08.2011, 08:20 4
Я тоже не могу понять, при чём тут Билдер и вообще, в чём изюминка данной задачи?

C++
1
2
3
4
5
6
7
double dArray[]={0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0};
double dAverage = 0.0;
 
for (int i=0;i<10;i++)
       dAverage+=dArray[i];
 
dAverage/=10.0;
Может ты ждал решение с помощью ассемблерной вставки?

Добавлено через 26 минут
Оказывается такая функция уже есть в math,
C++
1
extern PACKAGE double __fastcall Mean(double const *Data, const int Data_Size)/* overload */;
тогда вообще одной строчкой
C++
1
2
3
4
#include <math.hpp>
double dArray[] = {0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0};
 
double dAverage = Mean(dArray,10);
Добавлено через 33 минуты
Решил устроить соревнование между стандартной Билдеровской функцией и
вычислением с использованием простого цикла:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <math.hpp>
#include <DateUtils.hpp>
#include <IOStream>
 
const int dSIZE = 10000000;
// создадим очень большой массив
double *dArray = new double[dSIZE];
for (int i = 0; i < dSIZE; i++) {
    dArray[i] = i/3.14159265358979323846;
}
 
TDateTime dtFirst = Now(); // запомним время
// вычисление с помощью функции из модуля Math.hpp
double dAverage1 = Mean(dArray, dSIZE);
 
// выводим результат
std::cout << dAverage1 << std::endl;
const AnsiString sTime1 = AnsiString(MilliSecondOf(dtFirst)) + " мсек";
std::cout << sTime1.c_str() << std::endl;
 
TDateTime dtSecond = Now(); // запомним время
double dAverage2 = 0.0;
// вычисление с использованием простого цикла
for (int i = 0; i < dSIZE; i++)
    dAverage2 += dArray[i];
 
dAverage2 /= dSIZE;
 
delete []dArray;
 
// выводим результат
dtSecond = Now() - dtSecond;
std::cout << dAverage2 << std::endl;
const AnsiString sTime2 = AnsiString(MilliSecondOf(dtSecond)) + " мсек";
std::cout << sTime2.c_str() << std::endl;
Результат:
Код
Функция Mean
1591549.1126091
63 мсек

Вычисление циклом
1591549.27176401
172 мсек
Вывод: не надо придумывать велосипед, пользуйтесь стандартными функциями
1
3093 / 2413 / 256
Регистрация: 11.03.2009
Сообщений: 5,450
25.08.2011, 08:47 5
Maluda, замеры не в том месте и не в том количестве сделаны, поэтому результат неверен.
1
365 / 247 / 24
Регистрация: 03.04.2011
Сообщений: 558
Записей в блоге: 1
25.08.2011, 10:30  [ТС] 6
Maluda, спорим я твою конструкцию из цикла завалю массивом из двух элементов??!!)))) math отпадает)) дело в том что ее нужно самому написать!

Добавлено через 50 секунд
А, и по поводу велосипедов, если почитать algorithm то многое ясно становится))
0
3093 / 2413 / 256
Регистрация: 11.03.2009
Сообщений: 5,450
25.08.2011, 11:24 7
В чем всетаки трудность заключается?
0
1121 / 792 / 100
Регистрация: 01.02.2011
Сообщений: 1,865
Записей в блоге: 1
26.08.2011, 08:04 8
ошибка была, потому что надо было вызывать так: Mean(dArray, dSIZE-1)
1
1280 / 598 / 116
Регистрация: 18.08.2009
Сообщений: 832
26.08.2011, 09:18 9
kazak, я замеры сделал правильно, просто делал в оконном приложении, а когда по просьбе
pomkalk вывод переделывал в консольный забыл строчку дописать. Поэтому замеры правильные. Изначально было так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
const int dSIZE = 10000000;
 
double *dArray = new double[dSIZE];
for (int i = 0; i < dSIZE; i++) {
    dArray[i] = i/3.14159265358979323846;
}
 
TDateTime dtFirst = Now();
// вычисление с помощью функции из модуля Math.hpp
 // Правильно должно быть dSIZE - 1
double dAverage1 = Mean(dArray, dSIZE - 1);
 
dtFirst = Now() - dtFirst;
Memo1->Lines->Add(dAverage1);
Memo1->Lines->Add(AnsiString(MilliSecondOf(dtFirst)) + " мсек");
 
TDateTime dtSecond = Now();
double dAverage2 = 0.0;
// вычисление с использованием массива
for (int i = 0; i < dSIZE; i++)
    dAverage2 += dArray[i];
 
dAverage2 /= dSIZE;
 
dtSecond = Now() - dtSecond;
 
delete []dArray;
 
Memo1->Lines->Add(dAverage2);
Memo1->Lines->Add(AnsiString(MilliSecondOf(dtSecond)) + " мсек");
kzru_hunter, странно, но действительно надо dSize - 1.

Тогда результат будет:
Код
1591549.27176401
63 мсек
1591549.27176401
172 мсек
pomkalk, выкладывай свою функцию, устроим соревнование по скорости
0
3093 / 2413 / 256
Регистрация: 11.03.2009
Сообщений: 5,450
26.08.2011, 14:28 10
Цитата Сообщение от Maluda Посмотреть сообщение
странно, но действительно надо dSize - 1.
ничего странного, второй параметр обозначает индекс последнего элемента в массиве.

Цитата Сообщение от Maluda Посмотреть сообщение
выкладывай свою функцию, устроим соревнование по скорости
Начнем с того, что использование TDateTime не дает постоянных результатов, они плавают от запуска программы к запуску.
Для функции Mean у меня получилость ~31-47 мс,
для простого суммирования в цикле ~90-130 мс,
и наконец для такой конструкции (идея правда не моя - вскрыл Mean дизассемблером )
C++
1
2
3
4
5
6
7
8
9
10
   szfl = dSIZE % 4;
   szint = dSIZE - szfl - 1;
 
   for (int i = 0; i < szint; i += 4)
      aver += p[i] + p[i+1] +p [i+2] +p [i+3];
 
   for (int j = dSIZE - szfl; j < dSIZE; j++)
      aver += p[j];
 
   aver /= dSIZE;
~31-60 мс.

Добавлено через 23 секунды
dSIZE = 10000000
2
1280 / 598 / 116
Регистрация: 18.08.2009
Сообщений: 832
26.08.2011, 14:44 11
Цитата Сообщение от kazak Посмотреть сообщение
ничего странного, второй параметр обозначает индекс последнего элемента в массиве.
Просто в функции этот параметр называется const int Data_Size, логичнее было бы его назвать const int LastArrayIndex.
0
1121 / 792 / 100
Регистрация: 01.02.2011
Сообщений: 1,865
Записей в блоге: 1
26.08.2011, 16:07 12
Можно ещё быстрее сделать, если суммировать не по 4 числа, а по 32
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
        int szfl = kol % 32;
        int szint = kol - szfl - 1;
        double aver = 0, *l;
 
        for (int i = 0; i < szint; i += 32)
        {
                l = p+i;
                aver += l[0] + l[1] + l[2] + l[3] + l[4] + l[5] + l[6] + l[7] + l[8] + l[9] + l[10] + l[11] + l[12] + l[13] + l[14] + l[15] + l[16] + l[17] + l[18] + l[19] + l[20] + l[21] + l[22] + l[23] + l[24] + l[25] + l[26] + l[27] + l[28] + l[29] + l[30] + l[31];
        }
 
        for (int j = kol - szfl; j < kol; j++)
                aver += p[j];
 
        aver /= kol;
Было бы ещё быстрее, если бы это сделать как ассемблерную вставку.
0
365 / 247 / 24
Регистрация: 03.04.2011
Сообщений: 558
Записей в блоге: 1
26.08.2011, 16:11  [ТС] 13
Maluda, kazak, это конечно хорошо, НО, такую функцию можно ЗАВАЛИТЬ, массивом всего из двух параметров!
Еще варианты
0
3093 / 2413 / 256
Регистрация: 11.03.2009
Сообщений: 5,450
26.08.2011, 16:20 14
Цитата Сообщение от kzru_hunter Посмотреть сообщение
Можно ещё быстрее сделать, если суммировать не по 4 числа, а по 32
Смысла нет.

pomkalk, что значит завалить?

Добавлено через 3 минуты
Цитата Сообщение от kzru_hunter Посмотреть сообщение
for (int i = 0; i < szint; i += 32)
{
l = p+i; // тем более здесь дополнительные вычисления
aver += l[0] + l[1] + l[2] + l[3] + l[4] + l[5] + l[6] + l[7] + l[8] + l[9] + l[10] + l[11] + l[12] + l[13] + l[14] + l[15] + l[16] + l[17] + l[18] + l[19] + l[20] + l[21] + l[22] + l[23] + l[24] + l[25] + l[26] + l[27] + l[28] + l[29] + l[30] + l[31];
}
.....
0
365 / 247 / 24
Регистрация: 03.04.2011
Сообщений: 558
Записей в блоге: 1
26.08.2011, 16:24  [ТС] 15
kazak, Завалить - это значит что я передам в функцию массив из двух значений, после чего мне вернется не верный результат!!))
0
3093 / 2413 / 256
Регистрация: 11.03.2009
Сообщений: 5,450
26.08.2011, 16:27 16
Не знаю что там тебе возвращается, но считает верно.
0
365 / 247 / 24
Регистрация: 03.04.2011
Сообщений: 558
Записей в блоге: 1
26.08.2011, 16:52  [ТС] 17
kazak, если передать в функцию массив, хотя бы из двух значений!, со значениями максимально приближенными к максимально допустимому, что тогда мне функция вернет))
0
3093 / 2413 / 256
Регистрация: 11.03.2009
Сообщений: 5,450
26.08.2011, 17:00 18
Это нормальное явление, по другому никак.
0
365 / 247 / 24
Регистрация: 03.04.2011
Сообщений: 558
Записей в блоге: 1
26.08.2011, 17:27  [ТС] 19
Почему ни как??)) как!!))
Нужно каждое число массива сначала делить на количество элементов, а затем только складывать))

Добавлено через 19 секунд
Жду ваших предложений по реализации данной функции!!))
0
3093 / 2413 / 256
Регистрация: 11.03.2009
Сообщений: 5,450
26.08.2011, 17:39 20
Цитата Сообщение от pomkalk Посмотреть сообщение
Нужно каждое число массива сначала делить на количество элементов, а затем только складывать))
А если массив будет заполнен малыми числами?))
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
26.08.2011, 17:39
Помогаю со студенческими работами здесь

Написать шаблон функции для вывода в обратном порядке массива типа int и double
Есть массив, нужно вывести его в обратном порядке

Написать функцию нахождения количества элементов больших среднего арифметического
Написать функцию нахождения количества элементов больших среднего арифметического.

Написать функцию для нахождения максимального из числовых элементов двумерного массива
Написать функцию для нахождения максимального из числовых элементов двумерного массива. Заранее...

Написать функцию для нахождения максимального из числовых элементов двумерного массива
Написать функцию для нахождения максимального из числовых элементов двумерного массива. Заранее...

Написать функцию min с переменным числом параметров, которая находит минимальное из чисел типа int или из чисел типа double
Написать функцию min с переменным числом параметров, которая находит минимальное из чисел типа int...

Функция для нахождения среднего арифметического пяти чисел типа FLOAT
Написать программу, которая использует функцию для нахождения среднего арифметического пяти чисел...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru