{"id":1798,"date":"2016-09-20T10:25:39","date_gmt":"2016-09-20T08:25:39","guid":{"rendered":"http:\/\/www.webotlet.hu\/?p=1798"},"modified":"2017-02-14T09:39:31","modified_gmt":"2017-02-14T08:39:31","slug":"c-programozas-12-veletlen-szamok","status":"publish","type":"post","link":"https:\/\/www.webotlet.hu\/?p=1798","title":{"rendered":"C++ programoz\u00e1s 12. &#8211; V\u00e9letlen sz\u00e1mok"},"content":{"rendered":"<h1>V\u00e9letlen sz\u00e1mok, avagy b\u00edzzuk a sorsra<\/h1>\n<p>Programoz\u00e1s sor\u00e1n sokszor el\u0151fordul, hogy valamilyen \u00e9rt\u00e9ket v\u00e9letlenszer\u0171en kell megadni, vagy fel kell t\u00f6lteni egy t\u00f6mb\u00f6t v\u00e9letlen sz\u00e1mokkal. A v\u00e9letlen sz\u00e1m gener\u00e1l\u00e1s\u00e1nak m\u00f3dszere att\u00f3l f\u00fcgg, hogy eg\u00e9sz vagy val\u00f3s sz\u00e1mokat szeretn\u00e9nk sorsolni. Miel\u0151tt azonban nekikezden\u00e9nk tiszt\u00e1zni kell, hogy a v\u00e9letlen sz\u00e1m sorsol\u00e1shoz sz\u00fcks\u00e9g van bizonyos el\u0151re meg\u00edrt k\u00f3dokra, melyeket #include-olni kell ahhoz, hogy a feladatot megoldhassuk. A k\u00f3dunk elej\u00e9n a sorsol\u00e1s egyik r\u00e9sz\u00e9t v\u00e9gz\u0151 rand() f\u00fcggv\u00e9ny haszn\u00e1lat\u00e1hoz a k\u00f6vetkez\u0151 sort kell beilleszteni a k\u00f3dunk elej\u00e9re:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">#include &lt;cstdlib&gt;<\/pre>\n<h4>Eg\u00e9sz sz\u00e1mok sorsol\u00e1sa<\/h4>\n<p>El\u0151sz\u00f6r meg kell hat\u00e1rozni annak az intervallumnak a hat\u00e1rait, amelyb\u0151l az adott sz\u00e1mot sorsolni kell:<\/p>\n<p><strong>[0;20]<\/strong><br \/>\n<strong>[10;30]<\/strong><br \/>\n<strong>[-10;10]<\/strong><br \/>\n<strong>[-20;0]<\/strong><br \/>\n<strong>[-40;-20]<\/strong><\/p>\n<p>Ha eg\u00e9sz sz\u00e1mokat akarunk sorsolni, akkor ezek a t\u00edpusok j\u00f6hetnek sz\u00f3ba. A j\u00f3 az eg\u00e9szben az, hogy b\u00e1rmilyen eg\u00e9szeket tartalmaz\u00f3 intervallumra egy \u00e1ltal\u00e1nos &#8220;k\u00e9plettel&#8221; meg lehet adni a sorsoland\u00f3 sz\u00e1mot. El\u0151sz\u00f6r meg kell hat\u00e1rozni az intervallum als\u00f3 \u00e9s fels\u0151 hat\u00e1r\u00e1t. Ha ezeket tudjuk, akkor j\u00f6het a sorsol\u00e1st v\u00e9gz\u0151 programk\u00f3d. Ennek \u00e1ltal\u00e1nos form\u00e1ja a k\u00f6vetkez\u0151:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">rand() % (fels\u0151-als\u00f3+1) + als\u00f3;<\/pre>\n<p>Bontsuk akkor r\u00e9szekre ezt a k\u00f3dot. Kezdj\u00fck bel\u00fclr\u0151l kifel\u00e9 haladva:<\/p>\n<p>A rand() f\u00fcggv\u00e9ny egy v\u00e9letlen sz\u00e1mokat gener\u00e1l\u00f3 f\u00fcggv\u00e9ny, mely egy eg\u00e9sz sz\u00e1mot sorsol ki a [0;32767] intervallumb\u00f3l. \u00cdgy is \u00edrhattam volna, hogy a rand() f\u00fcggv\u00e9ny ilyen \u00e9rt\u00e9keket sorsol: 0 <= sz\u00e1m <= 32767.\n\nEzt a sz\u00e1mot meg kell szorozni az intervallum m\u00e9ret\u00e9vel, amit minden esetben \u00fagy kapunk, hogy a fels\u0151 hat\u00e1rb\u00f3l kivonjuk az als\u00f3t \u00e9s 1-et hozz\u00e1adunk. Az egyik p\u00e9ld\u00e1n\u00e1l maradva a [0;10] intervallum m\u00e9rete 11, hiszen 10-0+1 = 11. Mi\u00e9rt adunk hozz\u00e1 egyet? Mert ha csak a k\u00e9t sz\u00e1m k\u00fcl\u00f6nbs\u00e9g\u00e9t venn\u00e9nk, akkor az intervallumba a fels\u0151 hat\u00e1r nem tartozna bele. Mi\u00e9rt? Hamarosan kider\u00fcl. Ha ezt az intervallum m\u00e9retet behelyettes\u00edtj\u00fck a megfelel\u0151 helyre egyszer\u0171s\u00f6dik a k\u00e9plet:\n\n[code lang=\"cpp\"]rand() % intervallum_m\u00e9rete + als\u00f3;[\/code]\n\nL\u00e1thatod, hogy a rand() f\u00fcggv\u00e9ny \u00e1ltal sorsolt eg\u00e9sz sz\u00e1mot elosztjuk az intervallum m\u00e9ret\u00e9vel marad\u00e9kos oszt\u00e1ssal. Ebb\u0151l mi is k\u00f6vetkezik? Az, hogy a marad\u00e9kos oszt\u00e1s minden esetben kihagyja az eredm\u00e9nyb\u0151l az oszt\u00f3 \u00e9rt\u00e9k\u00e9t. Ha 10-et osztok marad\u00e9kos oszt\u00e1ssal 3-mal, akkor az eredm\u00e9ny 0-1-2 lehet. A 3 soha. Ez minden esetben \u00edgy van, teh\u00e1t maga az oszt\u00f3 nem lehet benne az eredm\u00e9nyben. Ez\u00e9rt adunk hozz\u00e1 egyet, hogy az intervallum fels\u0151 hat\u00e1ra is benne legyen az eredm\u00e9nyben.\n\nHa most n\u00e9zz\u00fck a bels\u0151 r\u00e9szt, akkor alakul a dolog. N\u00e9zz\u00fck \u00fajra a p\u00e9ld\u00e1kat imm\u00e1r behelyettes\u00edtve az eddig tanultakat:\n\n[code lang=\"cpp\"]\n[0;20]     rand() % 21 + als\u00f3;\n[10;30]    rand() % 21 + als\u00f3;\n[-10;10]   rand() % 21 + als\u00f3;\n[-20;0]    rand() % 21 + als\u00f3;\n[-40;-20]  rand() % 21 + als\u00f3;\n[\/code]\n\n\u00c9rdekes m\u00f3don hab\u00e1r 5 k\u00fcl\u00f6nf\u00e9le t\u00edpust adtam meg intervallumra, az intervallumok m\u00e9rete m\u00e9gis egyforma. Nincs ezzel semmi gond, mert a v\u00e9letlen sz\u00e1m sorsol\u00e1s els\u0151 l\u00e9p\u00e9se a megfelel\u0151 m\u00e9ret\u0171 sorsol\u00e1si intervallum meghat\u00e1roz\u00e1sa, ami ism\u00e9tl\u00e9sk\u00e9pp: <strong>fels\u0151-als\u00f3+1<\/strong><\/p>\n<p>Ha ez megvan, akkor m\u00e1r csak ezt a megfelel\u0151 m\u00e9ret\u0171 intervallumot kell eltolni a sz\u00e1megyenesen a megfelel\u0151 ir\u00e1nyba \u00fagy, hogy az intervallum als\u00f3 hat\u00e1ra a megfelel\u0151 kezd\u0151pontban legyen. Ez puszt\u00e1n csak annyit jelent, hogy az oszt\u00e1s ut\u00e1n hozz\u00e1adom az intervallum als\u00f3 hat\u00e1r\u00e1t (ami negat\u00edv \u00e9rt\u00e9k eset\u00e9n term\u00e9szetesen kivon\u00e1st jelent). Z\u00e1r\u00f3jelezni nem sz\u00fcks\u00e9ges, a m\u0171veletek sorrendje miatt \u00fagyis az oszt\u00e1st hajtja v\u00e9gre el\u0151sz\u00f6r. L\u00e1ssuk \u00edgy a megold\u00e1sokat:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n&#x5B;0;20]     rand() % 21; \/\/ a null\u00e1t nem adom hozz\u00e1\r\n&#x5B;10;30]    rand() % 21 + 10;\r\n&#x5B;-10;10]   rand() % 21 - 10;\r\n&#x5B;-20;0]    rand() % 21 - 20;\r\n&#x5B;-40;-20]  rand() % 21 - 40;\r\n<\/pre>\n<p>V\u00e9g\u00fcl \u00e1lljon itt p\u00e1r feladat adott intervallumb\u00f3l t\u00f6rt\u00e9n\u0151 sorsol\u00e1s gyakorl\u00e1s\u00e1hoz:<\/p>\n<p><strong>[-55;15] [-40;5] [60;105] [-50;35] [45;95] [50;50] [10;25] [20;105] [80;95]<br \/>\n[-30;-25] [40;60] [-20;45] [-10;15] [-20;25] [-45;-20] [-25;75] [-20;15] [-15;95]<br \/>\n<\/strong><\/p>\n<p>\u00c1lljon itt akkor egy komplex p\u00e9lda egy kis \u00fajdons\u00e1ggal megf\u0171szerezve. Igaz ugyan, hogy itt egy \u00faj szerkezetet, az \u00fagynevezett ciklust is haszn\u00e1lom, de te csak a v\u00e9letlen sz\u00e1m sorsol\u00e1si r\u00e9szeket figyeld meg:<\/p>\n<pre class=\"brush: cpp; highlight: [3,9]; title: ; notranslate\" title=\"\">\r\n#include &lt;iostream&gt;\r\n#include &lt;cstdlib&gt;\r\n#include &lt;ctime&gt;\r\n\r\nusing namespace std;\r\n\r\nint main()\r\n{\r\n    srand(time(0));\r\n\r\n    cout &lt;&lt; &quot;&#x5B;-10;20]&quot; &lt;&lt; endl;\r\n    for( int i = 0; i &lt; 50; i++ )\r\n    {\r\n        cout &lt;&lt; rand() % 31 - 10 &lt;&lt; &quot; &quot;;\r\n    }\r\n    cout &lt;&lt; endl;\r\n\r\n    return 0;\r\n}\r\n<\/pre>\n<p>A k\u00e9t kiemelt sorr\u00f3l eddig nem volt sz\u00f3. Az els\u0151 kiemel\u00e9sre az\u00e9rt van sz\u00fcks\u00e9g, hogy m\u0171k\u00f6dj\u00f6n a m\u00e1sodik kiemel\u00e9s. A C++ rand() f\u00fcggv\u00e9nye egy \u00fagynevezett pszeudo-random v\u00e9letlen sz\u00e1m gener\u00e1torral dolgozik. Ez gyakorlatilag annyit jelent, hogy ha elind\u00edtjuk, akkor gener\u00e1l egy v\u00e9letlen sz\u00e1mot. Ha \u00fajra haszn\u00e1ljuk, akkor egy k\u00f6vetkez\u0151t. De ez a sz\u00e1msorozat, amit mondjuk 10 sz\u00e1m gener\u00e1l\u00e1sakor el\u0151\u00e1ll\u00edt minden esetben ugyanaz lesz. Pr\u00f3b\u00e1ld csak ki. Ha gener\u00e1lsz egy v\u00e9letlen sz\u00e1mot, akkor a program k\u00f6vetkez\u0151 fut\u00e1sakor ugyanazt kapod. Ha 50 v\u00e9letlen sz\u00e1mot gener\u00e1lsz, mind mondjuk a fenti p\u00e9ldaprogramban is l\u00e1thatod, akkor ez minden programind\u00edt\u00e1skor ugyanaz az 50 sz\u00e1m lesz. Hol itt a v\u00e9letlen? Erre szolg\u00e1l a m\u00e1sodik kiemel\u00e9s, ami az aktu\u00e1lis g\u00e9pid\u0151vel egy kicsit belekever a sorsol\u00e1sba, \u00edgy &#8211; mivel az id\u0151 minden programfuttat\u00e1skor m\u00e1r m\u00e1s \u00e9rt\u00e9ket mutat &#8211; mindig m\u00e1shogy kever bele, \u00edgy val\u00f3ban v\u00e9letlennek t\u0171nik.<\/p>\n<h4>Val\u00f3s sz\u00e1mok sorsol\u00e1sa<\/h4>\n<p>Azt m\u00e1r tudjuk, hogy a rand() f\u00fcggv\u00e9ny csak eg\u00e9sz sz\u00e1mokat sorsol. Hogyan lesz akkor val\u00f3s v\u00e9letlen sz\u00e1munk? Nem nagy titok, hogy oszt\u00e1ssal. Itt azonban nem szabad eg\u00e9sz vagy marad\u00e9kos oszt\u00e1st v\u00e9gezni, hiszen azok eg\u00e9sz eredm\u00e9nyeket adnak, nek\u00fcnk pedig pont nem erre van sz\u00fcks\u00e9g\u00fcnk. Val\u00f3s v\u00e9letlen sz\u00e1m sorsol\u00e1sakor a k\u00f6vetkez\u0151 l\u00e9p\u00e9seket kell v\u00e9grehajtanunk:<\/p>\n<ol>\n<li>Sz\u00fcks\u00e9g van egy val\u00f3s sz\u00e1mra a [0;1] intervallumb\u00f3l.<\/li>\n<li>Ezt \u00e1talak\u00edtjuk a megfelel\u0151 m\u00e9ret\u0171 intervallumra.<\/li>\n<li>A l\u00e9trehozott intervallumot eltoljuk a sz\u00fcks\u00e9ges ir\u00e1nyba.<\/li>\n<\/ol>\n<p>N\u00e9zz\u00fck akkor l\u00e9p\u00e9senk\u00e9nt. Els\u0151k\u00e9nt a [0;1] val\u00f3s sz\u00e1m el\u0151\u00e1ll\u00edt\u00e1sa:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">(double)rand() \/ RAND_MAX<\/pre>\n<p>El\u0151sz\u00f6r ugyanabb\u00f3l indulunk ki, hogy kell a rand() \u00e1ltal gener\u00e1lt eg\u00e9sz sz\u00e1m az ismert intervallumb\u00f3l. R\u00f6gt\u00f6n ott van egy fura k\u00f3d az elej\u00e9n: <strong>(double) <\/strong>Ez az \u00fagynevezett <strong>t\u00edpusk\u00e9nyszer\u00edt\u00e9s,<\/strong> angolul typecast. Ez azt jelenti, hogy a k\u00f6zvetlen\u00fcl ut\u00e1na szerepl\u0151 \u00e9rt\u00e9knek k\u00f6zvetlen\u00fcl megmondja, hogy milyen t\u00edpusa legyen. A rand(), ha eml\u00e9kszel, egy eg\u00e9sz sz\u00e1mot sorsolt, de az intervallum val\u00f3s sz\u00e1mokat kell majd, hogy tartalmazzon. Ezzel megadtuk, hogy a <strong>(double)<\/strong> ut\u00e1n l\u00e9v\u0151 sz\u00e1m legyen val\u00f3s. Minderre az\u00e9rt volt sz\u00fcks\u00e9g, mert \u00edgy az ut\u00e1na k\u00f6vetkez\u0151 oszt\u00e1s nem k\u00e9t eg\u00e9sz sz\u00e1mmal t\u00f6rt\u00e9nik, hogy az oszt\u00e1s is val\u00f3s oszt\u00e1s lesz. A RAND_MAX egy be\u00e9p\u00edtett v\u00e1ltoz\u00f3, amely a rand() \u00e1ltal sorsolhat\u00f3 legnagyobb \u00e9rt\u00e9ket r\u00f6gz\u00edti, vagyis a sorsolhat intervallum fels\u0151 hat\u00e1r\u00e1t. Maga az oszt\u00e1s v\u00e9geredm\u00e9nyk\u00e9nt a [0;1] intervallumb\u00f3l ad egy double, vagyis val\u00f3s sz\u00e1mot, mivel az osztand\u00f3 legnagyobb \u00e9rt\u00e9ke a legnagyobb sorsolhat\u00f3 sz\u00e1m lesz, amit osztasz az elm\u00e9letileg legnagyobb sorsolhat\u00f3 sz\u00e1mmal, \u00edgy az oszt\u00e1s eredm\u00e9ny\u00e9nek maximuma \u00edgy 1 lehet. A legkisebb term\u00e9szetesen a 0, ha a rand() eredm\u00e9nye 0 lett.<\/p>\n<p>Ha megvan egy ekkora val\u00f3s sz\u00e1m, akkor \u00e1talak\u00edtjuk ezt a pici [0;1] intervallumot a k\u00edv\u00e1nt m\u00e9ret\u0171re. Itt egyszer\u0171en csak arr\u00f3l van sz\u00f3, hogy megszorozzuk az eredm\u00e9nyk\u00e9nt \u00f3hajtott intervallum m\u00e9ret\u00e9vel.<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n((double)rand() \/ RAND_MAX) * (intervallum m\u00e9rete)\r\n<\/pre>\n<p>Az intervallum m\u00e9rete nagyon fontos, hogy val\u00f3s sz\u00e1mok eset\u00e9n nem kell, hogy tartalmazza az ottani +1-et, vagyis<strong> itt csak a fels\u0151-als\u00f3 k\u00e9plettel dolgozzunk<\/strong>! Ennek megfelel\u0151en ez a l\u00e9p\u00e9s teljes eg\u00e9sz\u00e9ben \u00edgy n\u00e9z ki:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n((double)rand() \/ RAND_MAX) * (fels\u0151-als\u00f3)\r\n<\/pre>\n<p>Az utols\u00f3 l\u00e9p\u00e9s az intervallum eltol\u00e1sa hasonl\u00f3 az eg\u00e9sz sz\u00e1mokhoz k\u00e9pest, ami negat\u00edv als\u00f3 hat\u00e1r eset\u00e9n term\u00e9szetesen kivon\u00e1s lesz:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n((double)rand() \/ RAND_MAX) * (fels\u0151-als\u00f3) + als\u00f3;\r\n<\/pre>\n<p>N\u00e9zz\u00fck meg az eg\u00e9sz v\u00e9letlen sz\u00e1mokhoz megadott gyakorl\u00f3 feladatokat \u00fajra (csak hogy ne kelljen feljebb lapozni):<\/p>\n<p><strong>[-55;15] [-40;5] [60;105] [-50;35] [45;95] [50;50] [10;25] [20;105] [80;95]<br \/>\n[-30;-25] [40;60] [-20;45] [-10;15] [-20;25] [-45;-20] [-25;75] [-20;15] [-15;95]<br \/>\n<\/strong><\/p>\n<p>Itt egy komplex p\u00e9lda adott intervallumb\u00f3l val\u00f3s sz\u00e1m sorsol\u00e1s\u00e1ra:<\/p>\n<pre class=\"brush: cpp; highlight: [3,9]; title: ; notranslate\" title=\"\">\r\n#include &lt;iostream&gt;\r\n#include &lt;cstdlib&gt;\r\n#include &lt;ctime&gt;\r\n\r\nusing namespace std;\r\n\r\nint main()\r\n{\r\n    srand(time(0));\r\n\r\n    cout &lt;&lt; &quot;&#x5B;-10;20]&quot; &lt;&lt; endl;\r\n    for( int i = 0; i &lt; 50; i++ )\r\n    {\r\n        cout &lt;&lt; ((double)rand() \/ RAND_MAX) * 30 - 10 &lt;&lt; &quot; &quot;;\r\n    }\r\n    cout &lt;&lt; endl;\r\n\r\n    return 0;\r\n}\r\n<\/pre>\n<h4>K\u00f6vetkez\u0151 lecke: <a href=\"http:\/\/www.webotlet.hu\/?p=1814\">Ciklusok<\/a><\/h4>\n","protected":false},"excerpt":{"rendered":"<p>V\u00e9letlen sz\u00e1mok, avagy b\u00edzzuk a sorsra Programoz\u00e1s sor\u00e1n sokszor el\u0151fordul, hogy valamilyen \u00e9rt\u00e9ket v\u00e9letlenszer\u0171en kell megadni, vagy fel kell t\u00f6lteni egy t\u00f6mb\u00f6t v\u00e9letlen sz\u00e1mokkal. A v\u00e9letlen sz\u00e1m gener\u00e1l\u00e1s\u00e1nak m\u00f3dszere att\u00f3l f\u00fcgg, hogy eg\u00e9sz vagy val\u00f3s sz\u00e1mokat szeretn\u00e9nk sorsolni. Miel\u0151tt azonban <a class=\"more-link\" href=\"https:\/\/www.webotlet.hu\/?p=1798\">Tov\u00e1bb <span class=\"screen-reader-text\">  C++ programoz\u00e1s 12. &#8211; V\u00e9letlen sz\u00e1mok<\/span><span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[151],"tags":[158,159,143,83,172,171],"class_list":["post-1798","post","type-post","status-publish","format-standard","hentry","category-cplusplus-alap-leckek","tag-c","tag-c-programozas","tag-programozas","tag-random","tag-sorsolas","tag-veletlen-szam"],"_links":{"self":[{"href":"https:\/\/www.webotlet.hu\/index.php?rest_route=\/wp\/v2\/posts\/1798","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.webotlet.hu\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.webotlet.hu\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.webotlet.hu\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.webotlet.hu\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1798"}],"version-history":[{"count":13,"href":"https:\/\/www.webotlet.hu\/index.php?rest_route=\/wp\/v2\/posts\/1798\/revisions"}],"predecessor-version":[{"id":2075,"href":"https:\/\/www.webotlet.hu\/index.php?rest_route=\/wp\/v2\/posts\/1798\/revisions\/2075"}],"wp:attachment":[{"href":"https:\/\/www.webotlet.hu\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1798"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.webotlet.hu\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1798"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.webotlet.hu\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1798"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}