Jaki algorytm STL umożliwia zwrócenie wartości po przeanalizowaniu zawartości tablicy?

Odpowiedz Nowy wątek
2020-01-15 22:03

Rejestracja: 4 lata temu

Ostatnio: 2 dni temu

0

Dzień dobry.

Chcę zacząć korzystać z biblioteki STL, zamiast pisać własne algorytmy (to drugie już umiem w miarę dobrze, jak mi się wydaje). Chcę zwrócić zakodowaną w postaci bitów numery indeksów, pod którymi moja tablica przechowuje maksymalną wartość w całej tablicy. Napisałem kod w C++ (z STL i bez STL). Chciałbym jednak go odchudzić i pisać w samym STL. Jakiego algorytmu STL użyć, aby przetworzyć tablicę i uzyskać zamierzony efekt?

Tutaj kod z niepełnym STL:

unsigned char whichAxisHasTheHighestValue()
{
    int maximum = max_element(tab, tab + 3);
    unsigned char bits = 0;

    for (int i = 0, int b = 1; i < 3; i++, b *= 2)
        if (tab[i] == maximum)
            bits += b;

    return bits;
}

Jak można zauważyć, funkcja ustawia kolejne bity na 1, jeżeli dana komórka tablicy posiada wartość maksymalną. Użyłem algorytmu STL do znalezienia maksymalnej wartości. Chciałbym wymazać tego fora i zamiast niego użyć algorytmu, aby skrócić kod. Jakiego algorytmu mógłbym użyć?

Michał

edytowany 1x, ostatnio: mpaw, 2020-01-15 22:03
Oczywiście tablica tab ma 3 elementy, a funkcja, której kod umieściłem, jest metodą klasy, która zawiera składową tab - mpaw 2020-01-15 22:05

Pozostało 580 znaków

kq
2020-01-15 22:41
kq
Moderator C/C++

Rejestracja: 6 lat temu

Ostatnio: 11 minut temu

Lokalizacja: Szczecin

Odpowiedź na pytanie z tematu: np. std::minmax_element
Odpowiedź na pytanie z posta: std::accumulate


Pozostało 580 znaków

2020-01-16 10:25

Rejestracja: 4 lata temu

Ostatnio: 11 godzin temu

1

Można użyć for_each razem z dynamicznym bitset. ( C++ 14 + boost )
W takiej konfiguracji nie ma ograniczenia w liczbie elementów tablicy. ( dla unsigned char to maximum 8 ).

#include <iostream>
#include <vector>
#include <algorithm>
#include <boost/dynamic_bitset.hpp>

using namespace std;
using dynamic_bitset = boost::dynamic_bitset<>;

dynamic_bitset codeMaximum( const vector<int>& data )
{
    dynamic_bitset result(data.size());
    for_each(data.cbegin(),data.cend(),[position=0,max=*max_element(data.cbegin(),data.cend()),&result](const int& n)mutable{if(n==max)result[position]=1;++position;});

    return result;
}

int main()
{
    vector<int> data = {0,4,2,7,5,8,3,7,2,7,0,1,8,8,7};
    cout << codeMaximum(data) << "\n";

    return 0;
}
edytowany 1x, ostatnio: TomaszLiMoon, 2020-01-16 12:08
Dzięki. Chodziło mi o accumulate, ale dzięki za odpowiedź. - mpaw 2020-01-16 11:44

Pozostało 580 znaków

2020-01-16 11:53

Rejestracja: 12 lat temu

Ostatnio: 5 godzin temu

0
using namespace std;
using bitset = boost::dynamic_bitset<>;

Ktoś się prosi o kłopoty i miesza czytelnikowi w głowie.


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
Gorzej jak teraz czytelnikowi pomiesza się głowie, od próby znalezienia tego w kodzie, co może pomieszać mu w głowie. - TomaszLiMoon 2020-01-16 12:18

Pozostało 580 znaków

2020-01-16 14:19

Rejestracja: 12 lat temu

Ostatnio: 5 godzin temu

1

Wersja C++20 wygląda dość dobrze, ale kompilatory kiepsko wspierają C++20 więc jest trochę bałaganu z namespace i inculde:
https://wandbox.org/permlink/NQsrv3qxJl1RNv8D

#include <functional>
#include <range/v3/algorithm/max_element.hpp>
#include <range/v3/numeric/inner_product.hpp>
#include <range/v3/view/iota.hpp>

template<typename R>
unsigned int bits_for_positions_of_maximum(R&& r)
{
    auto max = *ranges::max_element(r);
    return ranges::inner_product(r, ranges::views::iota(0), 0, 
                                 std::plus{}, 
                                 [max](auto a, auto bit) { 
                                     return (max == a) ? (1 << bit) : 0; 
                                 });
}

Alternatywna wersja C++20 https://wandbox.org/permlink/stxlHxHwmkd9vgKV


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
edytowany 3x, ostatnio: MarekR22, 2020-01-17 11:52
iota??? co to tu robi, jakim to jest argumentem? - Sunnydev 2020-01-16 16:45
to jest widok/generator, który systematycznie powiększa argument. W tym wypadku generuje to kolejne liczby naturalne. Masz więc iloczyn skalarny jakiegoś wektora (tablicy) z kolejnymi liczbami naturalnymi. - MarekR22 2020-01-16 16:46
ostro :D Dzięki. - Sunnydev 2020-01-16 16:50

Pozostało 580 znaków

Odpowiedz

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0