{"id":220,"date":"2021-12-08T22:02:22","date_gmt":"2021-12-08T22:02:22","guid":{"rendered":"https:\/\/solinfo.ro\/blog\/?p=220"},"modified":"2024-05-17T20:31:19","modified_gmt":"2024-05-17T20:31:19","slug":"stl-lectia-1-map","status":"publish","type":"post","link":"https:\/\/solinfo.ro\/blog\/stl-lectia-1-map\/","title":{"rendered":"STL, lec\u021bia 1 &#8211; Map"},"content":{"rendered":"\n<p><\/p>\n\n\n\n<p>Map este o structur\u0103 de date cu ajutorul c\u0103reia putem asocia valori (mapped value) unor anumite chei (key value). Modul de operare al structurii de date Map este similar cu al unui vector de frecven\u021b\u0103, \u00eens\u0103, dac\u0103 \u00een cazul unui vector de frecven\u021b\u0103, valoarea cheie este reprezentat\u0103 doar de tipul de dat\u0103 int, la Map putem avea orice tip de date.<\/p>\n\n\n\n<p>\u00centr-un Map, <strong>valorile sunt ordonate<\/strong> \u00een func\u021bie de <strong>key value<\/strong>. <\/p>\n\n\n\n<p><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Cum folosim Map?<\/li><\/ul>\n\n\n\n<p>Primul pas este includerea libr\u0103riei &lt;map&gt; \u00een programul nostru:<\/p>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\n<pre class=\"wp-block-preformatted\">#include &lt;map&gt;<\/pre>\n<\/div><\/div>\n\n\n\n<p>Al doilea pas este ini\u021bializarea unui map:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">map&lt;key_data_type, value_data_type> m;\n<\/pre>\n\n\n\n<p>Pentru a vedea concret cum func\u021bioneaz\u0103 structura de date Map, voi lua ca exemplu problema <a rel=\"noreferrer noopener\" href=\"https:\/\/www.pbinfo.ro\/probleme\/2268\/colegi\" data-type=\"URL\" data-id=\"https:\/\/www.pbinfo.ro\/probleme\/2268\/colegi\" target=\"_blank\">#2268<\/a> de pe pbinfo.ro. \u00cen rezolvarea acesteia, vom folosi un Map. Numele elevilor vor reprezenta c\u00e2te un key value, iar frecven\u021ba fiec\u0103rui nume un mapped value.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">#include &lt;iostream&gt;\n#include &lt;map&gt;\n\nusing namespace std;\n\nint n;\nstring nume; \/\/ numele care vor fi citite\nmap &lt;string, int&gt; M; \/\/ map av\u00e2nd <strong>key_value<\/strong> de tipul <strong>string(nume)<\/strong>, \u0219i <strong>mapped_value<\/strong> de tipul <strong>int(frecven\u021b\u0103)<\/strong>\nmap &lt;string, int&gt; :: iterator it; \/\/ cu ajutorul lui, vom itera prin map\npair &lt;string, int&gt; elev; \/\/ p\u0103strez elevul cu frecven\u021ba maxim\u0103 \u0219i primul \u00een ordine alfabetic\u0103. elev.first va reprezenta numele elevului, iar elev.second frecven\u021ba acestuia\n\nint main(){\n\n    cin &gt;&gt; n;\n    for(int i = 1; i &lt;= n; i++){\n        \n        cin &gt;&gt; nume; \/\/ citesc <strong>n<\/strong> nume\n        M[nume]++; \/\/ m\u0103resc frecven\u021ba numelui\n        \n    }\n\n    for(it = M.begin(); it != M.end(); it++){\n\n\/\/ aici, it -&gt; first va reprezenta fiecare nume din map, iar it -&gt; second frecven\u021ba acestuia\n        \n        if(elev.second &lt; it -&gt; second){ \n\/\/ dac\u0103 \u00eent\u0103lnesc un nume cu frecven\u021b\u0103 mai mare, \u00eel p\u0103strez\n            \n            elev.first = it -&gt; first;\n            elev.second = it -&gt; second;\n            \n        }else if(elev.second == it -&gt; second &amp;&amp; elev.first &gt; it -&gt; first){\n            \n\/\/ dac\u0103 \u00eent\u0103lnesc un nume cu aceea\u0219i frecven\u021b\u0103, dar care este mai mic lexicografic(adic\u0103, este plasat \u00eenaintea lui elev.first \u00een ordinea alfabetic\u0103) dec\u00e2t ceea ce am deja \u00een variabila <strong>elev<\/strong>, \u00eel p\u0103strez \n\n            elev.first = it -&gt; first;\n            elev.second = it -&gt; second;\n            \n        }\n    }\n\n    cout &lt;&lt; elev.first &lt;&lt; \" \" &lt;&lt; elev.second; \/\/ afi\u0219ez elevul cu frecven\u021ba maxim\u0103 \u0219i care este primul \u00een ordine alfabetic\u0103\n\n    return 0;\n}<\/pre>\n\n\n\n<p>\u00cen mod asem\u0103n\u0103tor, se rezolv\u0103 \u0219i problema <a rel=\"noreferrer noopener\" href=\"https:\/\/www.pbinfo.ro\/probleme\/2217\/map\" data-type=\"URL\" data-id=\"https:\/\/www.pbinfo.ro\/probleme\/2217\/map\" target=\"_blank\">#2217<\/a>. <\/p>\n\n\n\n<p>\u00centruc\u00e2t mai sus am specificat structura de date <strong>unordered_map<\/strong>, v\u0103 voi prezenta diferen\u021bele dintre aceste 2 structuri de date \u0219i c\u00e2nd trebuie s\u0103 le folosim.<\/p>\n\n\n\n<p>Vom folosi Map atunci c\u00e2nd avem nevoie de date\/informa\u021bii <strong>\u00een ordine<\/strong>! Altfel, dac\u0103 ordinea elementelor nu este necesar\u0103, este mai bine s\u0103 folosim <strong>unordered_map<\/strong>!<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Pentru a folosi <strong>unordered_map<\/strong>, avem nevoie de libr\u0103ria &lt;unordered_map&gt; :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">#include &lt;unordered_map&gt;<\/pre>\n\n\n\n<p>Diferen\u021bele majore dintre cele 2 structuri de date sunt:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Ordonarea: Map ne asigur\u0103 c\u0103 elementele vor fi mereu \u00een ordine, \u00een schimb, Unordered Map nu ne permite acest lucru (de aici \u0219i numele)<\/li><li>Eficien\u021ba<\/li><\/ol>\n\n\n\n<p><strong>Map:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>inserare: log(n) + rebalance<\/li><li>\u0219tergere: log(n) + rebalance<\/li><li>c\u0103utare: log(n)<\/li><li>implementare: Self Balancing BST (de exemplu: <a rel=\"noreferrer noopener\" href=\"https:\/\/www.geeksforgeeks.org\/red-black-tree-set-1-introduction-2\/\" data-type=\"URL\" data-id=\"https:\/\/www.geeksforgeeks.org\/red-black-tree-set-1-introduction-2\/\" target=\"_blank\">Red-Black Tree<\/a>)<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Unordered Map:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>inserare: O(1) \u00een medie sau O(n), \u00een cel mai r\u0103u caz<\/li><li>\u0219tergere: O(1) \u00een medie sau O(n), \u00een cel mai r\u0103u caz<\/li><li>c\u0103utare: O(1) sau O(n)<\/li><li>implementare: <a rel=\"noreferrer noopener\" href=\"https:\/\/www.geeksforgeeks.org\/c-program-hashing-chaining\/\" data-type=\"URL\" data-id=\"https:\/\/www.geeksforgeeks.org\/c-program-hashing-chaining\/\" target=\"_blank\">Hash Table<\/a><\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p>Problema <a rel=\"noreferrer noopener\" href=\"https:\/\/www.pbinfo.ro\/probleme\/3626\/min-len-subseq\" data-type=\"URL\" data-id=\"https:\/\/www.pbinfo.ro\/probleme\/3626\/min-len-subseq\" target=\"_blank\">#3626<\/a> este tipul de problem\u0103 \u00een care nu avem nevoie de ordinea elementelor, ci trebuie doar s\u0103 \u0219tim dac\u0103 un element exist\u0103 sau nu. \u0218tim:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">v[i] + v[i + 1] + ... + v[j] = v[1] + v[2] + ... + v[j] - (v[1] + v[2] + ... + v[i - 1]), deci\ns(i, j) = sp[j] - sp[i - 1], i &lt;= j, sp[] = vector de sume par\u021biale\n<\/pre>\n\n\n\n<p>Prin urmare, vom construi sumele par\u021biale \u0219i vom stoca fiecare sum\u0103 de la 1 la i \u0219i indicele la care se ob\u021bine aceasta \u00eentr-un unordered_map. Pasul urm\u0103tor ar fi s\u0103 verific\u0103m la fiecare pas dac\u0103 suma <strong>X &#8211; s <\/strong>a mai fost ob\u021binut\u0103, iar dac\u0103 acest lucru se \u00eent\u00e2mpl\u0103, vom actualiza lungimea minim\u0103, f\u0103c\u00e2nd diferen\u021ba dintre indici.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">#include &lt;iostream&gt;\n#include &lt;unordered_map&gt;\n\nusing namespace std;\n\nint n, s, x, mini = int(1e9), sp; \/\/ (1e9) &lt;=&gt; 10^9 = 1.000.000.000\nunordered_map &lt;int, int&gt; m; \/\/ unordered map unde key value = suma de la 1 la i, iar mapped value = indicele la care a fost ob\u021binut\u0103 suma, adic\u0103 i\n\nint main(){\n\n    cin &gt;&gt; n &gt;&gt; s;\n\n    for(int i = 1; i &lt;= n; i++){\n\n        cin &gt;&gt; x;\n        sp += x; \/\/ adaug la sum\u0103\n\n        m[sp] = i; \/\/ sumei de la 1 la i, sp, \u00eei corespunde indicele i\n\n        if(m[sp - s]) \/\/ dac\u0103 mai ob\u021binut suma sp - s =&gt; exist\u0103 o secven\u021b\u0103 de lungime i - m[sp - s] cu suma s, acest lucru fiind echivalent cu: \"suma de la indicele mp[sp - s] + 1 \u0219i p\u00e2n\u0103 la i este egal\u0103 cu s\". \n            mini = min(mini, i - m[sp - s]); \/\/ actualizez rezultatul\n        \n\n    }\n\n    if(mini == int(1e9))\n        cout &lt;&lt; \"nu exista\";\n    else cout &lt;&lt; mini;\n\n\n}<\/pre>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-medium is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/solinfo.ro\/blog\/wp-content\/uploads\/2021\/12\/pirnog_theodor-1-2-300x300.png\" alt=\"\" class=\"wp-image-239\" width=\"349\" height=\"349\" srcset=\"https:\/\/solinfo.ro\/blog\/wp-content\/uploads\/2021\/12\/pirnog_theodor-1-2-300x300.png 300w, https:\/\/solinfo.ro\/blog\/wp-content\/uploads\/2021\/12\/pirnog_theodor-1-2-150x150.png 150w, https:\/\/solinfo.ro\/blog\/wp-content\/uploads\/2021\/12\/pirnog_theodor-1-2-70x70.png 70w, https:\/\/solinfo.ro\/blog\/wp-content\/uploads\/2021\/12\/pirnog_theodor-1-2-246x246.png 246w, https:\/\/solinfo.ro\/blog\/wp-content\/uploads\/2021\/12\/pirnog_theodor-1-2-276x276.png 276w, https:\/\/solinfo.ro\/blog\/wp-content\/uploads\/2021\/12\/pirnog_theodor-1-2-125x125.png 125w, https:\/\/solinfo.ro\/blog\/wp-content\/uploads\/2021\/12\/pirnog_theodor-1-2.png 398w\" sizes=\"auto, (max-width: 349px) 100vw, 349px\" \/><figcaption><strong><a rel=\"noreferrer noopener\" href=\"https:\/\/www.instagram.com\/701theodor\/\" data-type=\"URL\" data-id=\"https:\/\/www.instagram.com\/701theodor\/\" target=\"_blank\">Pirnog Theodor Ioan<\/a><\/strong><br>Colegiul Na\u021bional \u201cB. P. Hasdeu\u201d, Buz\u0103u<\/figcaption><\/figure><\/div>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Map este o structur\u0103 de date cu ajutorul c\u0103reia putem asocia valori (mapped value) unor anumite chei (key value). Modul &hellip; <\/p>\n","protected":false},"author":3,"featured_media":264,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[43,44],"tags":[],"class_list":["post-220","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cpp","category-stl"],"_links":{"self":[{"href":"https:\/\/solinfo.ro\/blog\/wp-json\/wp\/v2\/posts\/220","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/solinfo.ro\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/solinfo.ro\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/solinfo.ro\/blog\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/solinfo.ro\/blog\/wp-json\/wp\/v2\/comments?post=220"}],"version-history":[{"count":42,"href":"https:\/\/solinfo.ro\/blog\/wp-json\/wp\/v2\/posts\/220\/revisions"}],"predecessor-version":[{"id":300,"href":"https:\/\/solinfo.ro\/blog\/wp-json\/wp\/v2\/posts\/220\/revisions\/300"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/solinfo.ro\/blog\/wp-json\/wp\/v2\/media\/264"}],"wp:attachment":[{"href":"https:\/\/solinfo.ro\/blog\/wp-json\/wp\/v2\/media?parent=220"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/solinfo.ro\/blog\/wp-json\/wp\/v2\/categories?post=220"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/solinfo.ro\/blog\/wp-json\/wp\/v2\/tags?post=220"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}