• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

elementy mapy nie są poprawnie insertowane.

Object Storage Arubacloud
0 głosów
163 wizyt
pytanie zadane 10 sierpnia 2016 w C i C++ przez dziki indyk Użytkownik (940 p.)
edycja 10 sierpnia 2016 przez dziki indyk

Pętla zakresowa użyta na mapie pokazuje że elementy nie są do niej poprawnie insertowane. Konsekwencją niepoprawnego ułożenia mapy jest niemożliwość dostania się do niektórych jej elementów poprzez metodę find. Krótki kod, który obrazuje co się dzieje.

sf::ColorPlus c1("6dbac5ff");

for (auto color: tile_colors)
{
    std::cout << "\"" << color.first.getHexStr() << "\":  \"" << color.second << "\"";
    if (color.first == c1)
        std::cout << "  <- szukany kolor";
    std::cout << std::endl;
}

if (tile_colors.getIterator(c1) != tile_colors.end())
    std::cout << "find znalazło kolor" << std::endl;
else
    std::cout << "find nie znalazło koloru" << std::endl;


output jest następujący:

"000000ff":  "unknown"
"36281cff":  "ground"
"494637ff":  "brick"
"5e5229ff":  "mud"
"9c9c9cff":  "stone"
"6dbac5ff":  "water"  <- szukany kolor
"ececc2ff":  "sand"
find nie znalazło koloru


zwróćcie uwagę na to że element którego find nie znajduje nie jest ułożony zgodnie z "alfabetyczną" kolejnością. oczywiście w tym wypadku wyświetlany jest ciąg hexadecymanlny reprezentujący kolor a nie sam kolor.

metoda porównująca kolory wygląda tak:

bool ColorPlus::operator<(const ColorPlus& color) const
{
    return (r < color.r ? true : (g < color.g ? true : (b < color.b ? true : a < color.a)));
}

elementy mapy są wkładane do niej w ten sposób:

data[key] = value;

gdzie data to std::map<sf::ColorPlus, std::string>
key to obiekt sf::ColorPlus
value to std::string

 

Dlaczego tak się dzieje?

 

1 odpowiedź

0 głosów
odpowiedź 10 sierpnia 2016 przez criss Mędrzec (172,590 p.)
operator< działa działa w taki sposób, że wystarczy, żeby tylko jeden składnik (r/g/b/a) był mniejszy, a operator zwróci true. Nie wiem czy o to ci chodziło, ale wątpie.

Poza tym. Czym jest sf::ColorPlus? o_O Nie kojarze też, żeby std::map miało metode getIterator.
komentarz 10 sierpnia 2016 przez dziki indyk Użytkownik (940 p.)

Masz propozycję jak powinna wyglądać metoda porównywania kolorów?

wyjaśnienie:
sf::ColorPlus to klasa,która dziedziczy od sf::Color i przechowuje składowe koloru: red, green, blue, alpha. ColorPlus stworzyłem żeby dodać do klasy koloru dodatkowe funkcjonalności, takie jak obsługa stringów z hex kolorami i właśnie operator<.

tile_colors posiada składową std::map, przy czym getItarator zastępuje find na mapie, a begin i end odpowiadają begin i end mapy.

 

// data to std::map<KeyType, ValueType>
// w tym przypadku std::map<sf::ColorPlus, std::string>

template <typename KeyType, typename ValueType>
const auto DataManager<KeyType, ValueType>::getIterator(KeyType key) const
{
    return data.find(key);
}

template <typename KeyType, typename ValueType>
auto DataManager<KeyType, ValueType>::begin()
{
    return data.begin();
}

template <typename KeyType, typename ValueType>
const auto DataManager<KeyType, ValueType>::begin() const
{
    return data.begin();
}

template <typename KeyType, typename ValueType>
auto DataManager<KeyType, ValueType>::end()
{
    return data.end();
}

template <typename KeyType, typename ValueType>
const auto DataManager<KeyType, ValueType>::end() const
{
    return data.end();
}

 

komentarz 10 sierpnia 2016 przez criss Mędrzec (172,590 p.)

Ah, dzięki za wyjaśnienie.

Ciężko powiedzieć jak powinno wyglądać porównanie kolorów, bo co to właściwie znaczy, że kolor jest mniejszy? :D Myśle jednak, że największy sens by miało to:


bool ColorPlus::operator<(const ColorPlus& color) const
{
    return r < color.r && g < color.g && b < color.b && a < color.a;
}

 

komentarz 10 sierpnia 2016 przez dziki indyk Użytkownik (940 p.)

ale w przypadku takich kolorów:

a(200, 100, 0, 0)
b(100, 200, 0, 0)

wychodziłoby że a nie jest mniejsze od b i że b nie jest mniejsze od a.
wniosek byłby taki że te kolory są identyczne, a przecież nie są.
 

komentarz 10 sierpnia 2016 przez criss Mędrzec (172,590 p.)
Hem, faktycznie. Pomyślałem o kolorze jak o wektorze. Cóż, jak mówiłem, normalnie nie porównujemy kolorów na zasadzie "mniejszy,większy", więc ciężko się na czymś wzorować. Nie przychodzi mi do głowy żadne sensowne porównanie. Właściwie to dlaczego nie ustawiasz kolorów alfabetycznie wg nazw? Tzn. dlaczego string nie jest kluczem?

A co do pokazanego przez ciebie outputu kolorów... I tak nie bardzo rozumiem dlaczego "stone" znalazło się nad "water"..
2
komentarz 10 sierpnia 2016 przez draghan VIP (106,230 p.)
Można określić porównanie reprezentacji kolorów między sobą tylko wtedy, kiedy można je jednoznacznie przedstawić w jednym wymiarze (można o tym myśleć, jak o umiejscowieniu wszystkich kolorów na osi układu odniesienia).

Zapisując kolor w notacji RGB heksadecymalnie, tworzy się... liczbę, która jednoznacznie określa "wartość" koloru (np. kolor czarny ma wartość liczbową 0, zaś biały to FFFFFF = 16777215). Myślę, że to jest wystarczające kryterium dla tego przypadku. :)
komentarz 11 sierpnia 2016 przez dziki indyk Użytkownik (940 p.)

ostatecznie metoda operator< wygląda tak:
 

bool ColorPlus::operator<(const ColorPlus& color) const
{
    return (Uint32)(r * 16777216 + g * 65536 + b * 256 + a) < (Uint32)(color.r * 16777216 + color.g * 65536 + color.b * 256 + color.a);
}

no i działa jak powinna. dzięki za pomoc. :)

Podobne pytania

0 głosów
0 odpowiedzi 86 wizyt
+1 głos
2 odpowiedzi 522 wizyt
pytanie zadane 12 czerwca 2019 w C i C++ przez k222 Nałogowiec (30,150 p.)
–2 głosów
1 odpowiedź 310 wizyt
pytanie zadane 21 stycznia 2017 w C i C++ przez Michaś Nowicjusz (120 p.)

92,555 zapytań

141,403 odpowiedzi

319,557 komentarzy

61,940 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...