0 / 0 / 0
Регистрация: 21.11.2010
Сообщений: 30
1

Функторы и алгоритмы stl

07.12.2010, 01:18. Показов 5597. Ответов 6
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый день! Интересует такой вопрос.
Я хочу, используя стандартный алгоритм стл for_each() и функтор, определить наибольший элемент в векторе. Т.е. функтор должен просматривать последовательность и в конце выводить значение наибольшего элемента. Написал нижеследующий код. Проблема заключается в том, что написанный мной функтор содержит подсчет просмотренных элементов (int i), чтобы сделать вывод только в конце. Т.е. код зависит от количества элементов вектора. Подскажите, пожалуйста, как переписать код функтора, чтобы он не зависел от числа элементов вектора.

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
36
37
38
39
40
41
#include <iostream>
#include <vector>
#include <functional>
#include <algorithm>
#include <time.h>
 
using namespace std;
 
class cl: public unary_function<int,void>
{
    int i,max_value;
public:
    cl()
    {
        max_value=0;
        i=0;
 
    }
    ~cl(){}
    void operator()(int value)
    {
        i++;                 // Подсчитывается номер обрабатываемого элемента вектора
        if(value>max_value)
            max_value=value;
        if(i==10)            // Проверка на достижение последнего элемента
            cout<<"Max value: "<<max_value;
    }
};
 
int main()
{   
    vector<int> vec;
    srand(time(NULL));
    for(int j=0; j<10; j++)
        vec.push_back(rand()%101);
        for(int j=0; j<10; j++)
        cout<<vec[j]<<" ";
    cout<<endl;
    for_each(vec.begin(),vec.end(),cl());
    return 0;
}
0
07.12.2010, 01:18
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
07.12.2010, 01:18
Ответы с готовыми решениями:

STL, функторы
Всем привет! Вообщем есть код: #include &lt;iostream&gt; #include &lt;algorithm&gt; #include &lt;vector&gt; int main() { ...

STL функторы, предикаты
У нас есть: std::multimap&lt;std::string,std::string&gt; map; нужно удалить все повторяющиеся ключи, используя алгоритм с предикатом. ...

Функторы, алгоритмы и адаптеры
Нужна помощь! 1 Нужно создать multimap и multiset на основе элементов типа класса CPerson, содержащий в своем классе следующие...

6
274 / 175 / 12
Регистрация: 14.03.2010
Сообщений: 501
07.12.2010, 02:55 2
Никак. Разве что передавать в конструктор функционала число элементов массива.
Запомнить значение в функционале тоже не получится, потому что в эстээлевских алгоритмах объекты передаются по значениям, а не по ссылкам.
Так что либо пиши свою функцию, либо пользуйся std::min_element / std::max_element, либо std::valarray.

Добавлено через 11 минут
В принципе, можно сделать и вот так (функтор записывает максимальное значение во внешнюю переменную, ссылку на которую получил в конструкторе), но так не очень круто:
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
#include <iostream>
#include <vector>
 
template <typename type>
struct maximum {
    maximum (type & storage) : m_value(storage) {}
 
    void operator () (const type & value) { if (value > m_value) m_value = value; }
 
    type & m_value;
};
 
int main (int argc, char * const argv[]) {
    int max_element;
    std::vector<int> v;
    
    for (int i = 0; i < 10; ++i) v.push_back(random() % 100);
    for (int i = 0; i < 10; ++i) std::cout << v[i] << " ";
    std::cout << std::endl;
    
    std::for_each(v.begin(), v.end(), maximum<int>(max_element));
    
    std::cout << max_element;
 
    return 0;
}
0
Эксперт С++
 Аватар для Mr.X
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
07.12.2010, 06:15 3
Ну, во-первых вы неправильно вычисляете максимум. Инициализируете нулем, а потом сравниваете со значениями вектора. Если все значения вектора будут меньше нуля, то выведется ноль, а не искомый максимум:
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
36
37
38
39
40
41
42
43
#include <iostream>
#include <vector>
#include <functional>
#include <algorithm>
#include <time.h>
 
using namespace std;
 
class cl: public unary_function<int,void>
{
    int i,max_value;
public:
        cl()
        {
                max_value=0;
                i=0;
 
        }
        ~cl(){}
        void operator()(int value)
        {
                i++;                 // Подсчитывается номер обрабатываемого элемента вектора
                if(value>max_value)
                        max_value=value;
                if(i==10)            // Проверка на достижение последнего элемента
                        cout << "Max value: "
                             << max_value
                             << std::endl;
        }
};
 
int main()
{       
        vector<int> vec;
        srand(time(NULL));
        for(int j=0; j<10; j++)
                vec.push_back(rand()%101 - 1000);
        for(int j=0; j<10; j++)
                cout<<vec[j]<<" ";
        cout<<endl;
        for_each(vec.begin(),vec.end(),cl());
        return 0;
}
А во-вторых алгоритмом for_each вот так пользуются:
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
//////////////////////////////////////////////////////////////////////////////////////
#include <algorithm>
#include <functional>
#include <iostream>
#include <time.h>
#include <vector>
////////////////////////////////////////////////////////////////////////////////////// 
using namespace std;
//////////////////////////////////////////////////////////////////////////////////////
struct  T_get_max_elem
{
    int   value_max_;
    bool  is_first_iter_;
    //-------------------------------------------------------------------------------- 
    T_get_max_elem() : value_max_(), is_first_iter_(true)
    {}
    //-------------------------------------------------------------------------------- 
    void operator()(int  value_cur)
    {
        if(   is_first_iter_
           || value_cur > value_max_)
        {
            is_first_iter_  = false;
            value_max_      = value_cur;
        }   
    }
    //--------------------------------------------------------------------------------
    operator int()
    {
        return  value_max_;
    }
};
 
int main()
{       
    vector<int> vec;
    srand(time(NULL));
    for(int j = 0; j < 10; ++j)
    {
        vec.push_back(rand() % 101 - 90);
    }
            
    for(size_t  j = 0; j < vec.size(); ++j)
    {
        cout << vec[j] 
             << " ";
    }            
    cout<<endl;
    cout << "Max value: "
         << for_each(vec.begin(),vec.end(),T_get_max_elem())
         << std::endl;    
}
0
0 / 0 / 0
Регистрация: 21.11.2010
Сообщений: 30
07.12.2010, 08:12  [ТС] 4
volovzi, задача состоит не в нахождении максимума как такового, я ее упростил, чтобы не плодить много кода. Интересен непосредственно сам момент определения конечного элемента вектора.
Mr.X, почему в for_each нельзя использовать функтор в том виде, в котором использую его я?
0
Эксперт С++
 Аватар для Mr.X
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
07.12.2010, 08:39 5
Цитата Сообщение от Leningradec Посмотреть сообщение
Mr.X, почему в for_each нельзя использовать функтор в том виде, в котором использую его я?
Я вам продемонстрировал, что алгоритм for_each возвращает объект функтора, которым мы пробежались по контейнеру, и мы спокойно можем извлечь из него информацию, которая там накопилась, поэтому нет необходимости отслеживать момент окончания обработки внутри функтора.
Ну а резвиться и дерзать никто никому не запрещает.
2
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12837 / 7573 / 1765
Регистрация: 25.07.2009
Сообщений: 13,969
07.12.2010, 10:57 6
просто на всякий случай... минимальный/максимальный по модулю элементы:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <algorithm>
#include <cmath>
 
template <typename T>
struct ModCmp {
    bool operator () (const T & a, const T & b){
        return fabs(static_cast<double>(a)) < fabs(static_cast<double>(b));
    }
};
 
int main(){
    const int SIZE(5);
    int arr[SIZE] = { 3, -8, 2, -5, 4 };
    
    std::cout << "Array: ";
    for ( int i = 0; i < SIZE; ++i )
        std::cout << arr[i] << ( i < SIZE - 1 ? ' ' : '\n' );
    std::cout << "Minimum element of the unit: " << *std::min_element(arr, arr + SIZE, ModCmp<int>()) << std::endl;
    std::cout << "Maximum element of the unit: " << *std::max_element(arr, arr + SIZE, ModCmp<int>()) << std::endl;
    
    return 0;
}
1
274 / 175 / 12
Регистрация: 14.03.2010
Сообщений: 501
07.12.2010, 13:20 7
Mr.X, ха, никогда не обращал внимания, что "for_each" что-то возвращает. Тогда, действительно, проще.
1
07.12.2010, 13:20
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
07.12.2010, 13:20
Помогаю со студенческими работами здесь

функторы && STL
Знакомлюсь с функторами. Помогите реализовать поиск минимального числа в последовательности, средн.арифмет. в посл-ти и количество...

STL алгоритмы сортировки
Здрасти. В STL есть алгоритмы sort - упорядочивает последовательность и stable_sort - упорядочивает последовательность, не меняя...

Задача на С++. Алгоритмы библиотеки STL.
Программа должна демонстрировать использование контейнерных классов для хранения встроенных типов данных. В программе выполнить...

Алгоритмы STL Удаление элементов в векторе
Банальный вопрос. vector&lt;int&gt; В нем разные числа могут повторяться. Хочу удалить заданное значение, полностью исключить его из вектора. ...

Контейнер map и алгоритмы STL: несовместимость?
Всем доброго времени суток! Столкнулся с проблемой: алгоритм remove_if не работает с контейнером map. Рассмотрим следующую функцию: ...


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

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

Редактор формул (кликните на картинку в правом углу, чтобы закрыть)
Опции темы

Новые блоги и статьи
Linux API: Полное руководство
hw_wired 08.02.2025
Linux API – это низкоуровневый программный интерфейс, обеспечивающий взаимодействие пользовательских приложений с ядром операционной системы. Он включает набор системных вызовов, библиотечных функций. . .
Асинхронное программировани­­­­­е и эмуляция async/await в C (СИ)
hw_wired 08.02.2025
Язык программирования C, несмотря на свой возраст, предоставляет неплохие средства для реализации асинхронных операций, позволяя создавать эффективные решения для обработки параллельных задач. В. . .
Как сгенерировать случайное число в указанном диапазоне в JavaScript
bytestream 08.02.2025
В JavaScript генерация случайных чисел основана на детерминированном алгоритме, который создает последовательность псевдослучайных значений. Встроенный метод Math. random() возвращает псевдослучайное. . .
Как получить список всех таблиц в PostgreSQL
bytestream 08.02.2025
PostgreSQL предлагает несколько методов для получения списка таблиц в базе данных. Наиболее распространенный способ - использование системного каталога pg_tables, который содержит информацию обо всех. . .
Java Spring для начинающих
bytestream 08.02.2025
Spring Framework - это универсальное решение для создания корпоративных Java-приложений. Он предоставляет комплексную программную и конфигурационную модель для современных приложений на Java. Spring. . .
Асинхронное программировани­­­­­­е и async/await в Visual Basic
bytestream 08.02.2025
В основе асинхронного программирования в Visual Basic лежит концепция неблокирующего выполнения операций. Когда программа встречает длительную операцию, например, чтение большого файла или запрос к. . .
Async/await и асинхронное программировани­­е в Delphi
bytestream 08.02.2025
Асинхронное программирование является неотъемлемой частью разработки современных приложений, позволяя создавать отзывчивые и эффективные программы. В Delphi реализация асинхронности опирается на. . .
Асинхронное программировани­­­­­е и async/await в C#
bytestream 08.02.2025
Асинхронное программирование - концепция, позволяющая приложениям эффективно выполнять длительные операции без блокировки основного потока выполнения. В контексте современной разработки на C# это. . .
Асинхронное программировани­­­­­е и горутины/каналы в Go
bytestream 08.02.2025
Язык Go изначально разрабатывался с учетом современных многоядерных процессоров и необходимости эффективного параллельного выполнения задач. В отличие от традиционных подходов к асинхронному. . .
Как восстановить stash в Git
hw_wired 08.02.2025
Git stash - это средство для временного сохранения изменений в рабочей директории. В процессе разработки часто возникают ситуации, когда нужно быстро переключиться на другую задачу, но текущие. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru