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

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ł

4

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

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;
}
0
using namespace std;
using bitset = boost::dynamic_bitset<>;

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

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

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