- Philips LCD és LED TV-k
- HiFi műszaki szemmel - sztereó hangrendszerek
- NVIDIA GeForce RTX 3080 / 3090 / Ti (GA102)
- Szünetmentes tápegységek (UPS)
- Nvidia GPU-k jövője - amit tudni vélünk
- Előrendelhető a OnePlus Pad 3
- A Microsoft átépítette a ROG Ally-t
- Milyen belső merevlemezt vegyek?
- Fujifilm X
- AMD K6-III, és minden ami RETRO - Oldschool tuning
Új hozzászólás Aktív témák
-
EQMontoya
veterán
////////////////////////////////////////////////////////////////////////////////////////////////
// Internal data and functions, do not access outside of this file!
//////////////////////////////////////////////////////////////////////////////////////////////// -
Boryszka
tag
válasz
dabadab #3094 üzenetére
Ez egyetemi linprog házi - amit megírtam már de állítólag totál rosszul értelmeztem és új progit kér (mindegy milyen nyelven van írva). Ha ismernétek a körülményeket, akkor nem csodálkoznátok a feladat szövegezésén, ami a következő:
"Adott pozitív egész számoknak egy 1, n2, · · · , nm növekvo sorozata, nevezzük a sorozatot mintának.
Legyen N > nm pozitív egész. Szeretnénk olyan S ⊆ [1, ... , N] részhalmazokat keresni, amelyben nincs
meg az 1, n2, ... , nm minta! Ez azt jelenti, hogy S -nek nem részhalmaza a minta egyik eltoltja sem, tehát nem részhalmaza az 1 + k, n2 + k, · · · , nm + k halmaz minden k = 0, 1, ... , N − nm esetén. Szeretnénk minél nagyobb elemszámú S halmazokat megadni az 1, n2, ... , nm mintához! Jó lenne sok mintához meghatározni a legnagyobb minta-mentes S halmazt. Kisebb méretre biztos eredményt kaphatunk azzal, hogy minden lehetséges S-et kipróbálunk jó-e! Nagyobb számok esetén érdemes több jónak tűnő elképzelést kipróbálni!" -
dabadab
titán
válasz
Boryszka #3091 üzenetére
"Ekkor a feladat az, hogy az (1,2,3,...,18,19,20) számokból (1-től 20-ig mindegyik) töröljünk minél kevesebbet úgy, hogy a megmaradt számok között ne forduljon elő a (2,3,6,8,13) minta és eltoltjai!"
Ne törölj semmit, probléma megoldva.
Következő kérdés?Egyébként ez C vagy C++ házi?
(És hol adnak ilyen rettenetesen rosszul megírt feladatokat?)
-
LordX
veterán
válasz
Boryszka #3091 üzenetére
Ha letörlöd a minta első elemét az 1-20 listából, az nem oldja meg a problémát? 1 elem törlése, 2 sor:
std::vector<int> minta = ...;
std::vector<int> egytolhuszig = ...;
auto torlendo = std::find(begin(egytolhuszig), end(egytolhuszig), minta.front())
if (torlendo != end(egytolhuszig)) { egytolhuszig.erase(torlendo); } -
EQMontoya
veterán
-
Boryszka
tag
Sziasztok! Ehhez a feladathoz lenne forráskódja valakinek, vagy lenne ötletetek, hogy milyen technikával lehetne megoldani leggyorsabban a feladatot? Köszi!
Tehát: van egy minta: pl. 2,3, 6, 8, 13 (m=5).
S legyen pl. 20.
Ekkor a feladat az, hogy az (1,2,3,...,18,19,20) számokból (1-től 20-ig mindegyik) töröljünk minél kevesebbet úgy, hogy a megmaradt számok között ne forduljon elő a (2,3,6,8,13) minta és eltoltjai!Tehát pl. az (1,2,3,4,5,6,7,9,11,14,15,17,19,20) részhalmaza a (1,2,3,...,18,19,20)-nak akkor minta-mentes, ha nincs meg benne a (2,3,6,8,13) egyik eltoltja sem!
Ezt kell ellenőrizni!Keresendő az a legtöbb (1,2,3,...,18,19,20)-beli számot tartalmazó részhalmaz, amely mintamentes.
-
dobragab
addikt
Boldog karácsonyt mindenkinek!
On the first day of Christmas my true love gave to me
a partridge in a pear tree.
On the second day of Christmas my true love gave to me
two turtle doves
and a partridge in a pear tree.
On the third day of Christmas my true love gave to me
three french hens, two turtle doves
and a partridge in a pear tree.
On the fourth day of Christmas my true love gave to me
four calling birds, three french hens, two turtle doves
and a partridge in a pear tree.
On the fifth day of Christmas my true love gave to me
five gold rings;
four calling birds, three french hens, two turtle doves
and a partridge in a pear tree.
On the sixth day of Christmas my true love gave to me
six geese a-laying, five gold rings;
four calling birds, three french hens, two turtle doves
and a partridge in a pear tree.
On the seventh day of Christmas my true love gave to me
seven swans a-swimming,
six geese a-laying, five gold rings;
four calling birds, three french hens, two turtle doves
and a partridge in a pear tree.
On the eigth day of Christmas my true love gave to me
eight maids a-milking, seven swans a-swimming,
six geese a-laying, five gold rings;
four calling birds, three french hens, two turtle doves
and a partridge in a pear tree.
On the ninth day of Christmas my true love gave to me
nine ladies dancing, eight maids a-milking, seven swans a-swimming,
six geese a-laying, five gold rings;
four calling birds, three french hens, two turtle doves
and a partridge in a pear tree.
On the tenth day of Christmas my true love gave to me
ten lords a-leaping,
nine ladies dancing, eight maids a-milking, seven swans a-swimming,
six geese a-laying, five gold rings;
four calling birds, three french hens, two turtle doves
and a partridge in a pear tree.
On the eleventh day of Christmas my true love gave to me
eleven pipers piping, ten lords a-leaping,
nine ladies dancing, eight maids a-milking, seven swans a-swimming,
six geese a-laying, five gold rings;
four calling birds, three french hens, two turtle doves
and a partridge in a pear tree.
On the twelfth day of Christmas my true love gave to me
twelve drummers drumming, eleven pipers piping, ten lords a-leaping,
nine ladies dancing, eight maids a-milking, seven swans a-swimming,
six geese a-laying, five gold rings;
four calling birds, three french hens, two turtle doves
and a partridge in a pear tree. -
Boryszka
tag
Működik: minden dll-t a SySWOW64 mappából másoltam át! Örülés!
-
Boryszka
tag
Csináltam egy setup fájlt, benne 4 dll állománnyal (- ucrtbased.dll - msvcp140D.dll - vcruntime14D.dll), de még így is be kellett raknom a xinput1_3.dll-t és még továbbra sem hajlandó elindulni Win10-ben!
-
Boryszka
tag
Sziasztok!
Kéne egy kis segítség, mégpedig: tanárnak készítettem beadandót de nem fut a gépén az exe fájl, mert kér 3 féle dll fájlt! Hogy tudnám megcsinálni h 100% lefusson nála?
-
jattila48
aktív tag
válasz
EQMontoya #3080 üzenetére
Azt hiszem, te ragaszkodsz egy koncepcióhoz, miszerint a különálló funkciókat külön osztályokban kell megvalósítani. Ez nálam is így van. Azonban létre kell hozni egy (és nem több) objektumot, ami ezeket a funkciókat egyben látja el. Tehát itt különbség van a funkciók implementálása (külön osztályokban), és azok használata között. A külön implementált funkciókat (a már említett okok miatt) egyben kell felhasználni. Erre én a származtatást használom, te pedig az egyébként máshol nem használt funkciókat unique_ptr-en keresztül "beinjektálod" a használt objektumba (ami innentől kezdve egyedül létezik, és szintén minden szükséges (egyébként külön implementált) funkciót ellát). Nálam egyik osztály sem tud önállóan létezni, csak a származtatás által összekapcsoltan, ahogy ez is a cél. Nálad a SourceReadFile ogjektum önállóan is tud létezni (sőt példányosítanod is kell), holott ennek semmi értelme, mert úgy is csak a másik osztályban tudod használni.
-
jattila48
aktív tag
válasz
EQMontoya #3080 üzenetére
Persze elég. Amit most példának írtam, abban is így van. Nem egészen erre gondoltam, rosszul fogalmaztam. Ettől függetlenül a fenit megállapításaimat fent tartom. Bonyolultabb, több hibalehetőséget magában rejtő megoldás, mint az enyém.
"Az a bajom az egybe pakolt megoldással, amiért nem is akar sézpen működni: teljesen különböző funkciókat szeretnénk bepakolni egy logikai csoportba."
A teljesen különböző funkciókat teljesen külön is választom: a blob feldolgozás az ősosztályba, a forrás kezelés/beolvasás a leszármazott osztályba. Persze amikor már példányosítom a leszármazott osztályt, akkor ezek a funkciók egy objektumban működnek, mint ahogy ez is a cél. (ld, ugyanaz a hatókör, a blob-ot vissza kell tudni írni, egységes RAII). A te megoldásodban sem fog külön önállóan létezni a SourceReadFile objektum (legalábbis nem sokáig, mert bele teszed egy unique_ptr-be), hanem rögtön "beinjektálod" a BlobProcess objektumba. Innentől kezdve, pedig ugyanúgy a BlobProcess objektum fogja ellátni az összes feladatot (blob feldolgozás, forrásba visszaírás). A SourceReadFile objektum önálló létének nincs is értelme, sőt a legjobb, ha minél előbb megszabadulunk tőle (RAII miatt), ezért legjobb, ha önállóan létre sem hozzuk. Persze a tényleg szükséges objektum leszármazott részeként marad.
Egyébként az "egybepakolt" megoldásom szépen működik. Miből gondolod, hogy nem akar? A te megoldásodat így gondoltad, ahogy a példában írtam? -
EQMontoya
veterán
válasz
jattila48 #3079 üzenetére
Szerintem a readet (elég, ha csak szignatúrájában egységes) a source-ba kellene tenni, és egyébként csak processzálás van.
Az a bajom az egybe pakolt megoldással, amiért nem is akar sézpen működni: teljesen különböző funkciókat szeretnénk bepakolni egy logikai csoportba.
-
jattila48
aktív tag
válasz
EQMontoya #3078 üzenetére
Más a fájlból olvasás paraméterezése, más a registry olvasásé, más a resource olvasásé, más a hálózatról olvasásé, stb. De még ha lehetne is egységes read-et írni, akkor is nálad 3 osztály kell hozzá, amiből kettőt példányosítasz is, majd az elsőt "beinjektálod" shared_ptr-en keresztül a másodikba (hogy rendesen működjön a RAII), és tovább erre az objektumra a létrehozás helyén nincs is szükséged. Továbbá BlobProcess ctor-ában ugyanúgy meg KELL hívnod egy "külső" fv.-t, mint nálam az ősosztály init_blob-ját. Ráadásul nálam ez nem is annyira külső fv., hiszen az ős protected tfv.-e. És mivel a forrás, a blob számára lefoglalt memória és maga a BlobProcess objektum teljesen összetartozóak (ugyanakkor keletkeznek, ugyanaz az érvényességi körük, ugyanakkor kell megszűnniük), ezért tök fölösleges azon görcsölni (legalábbis szerintem), hogy szétválasszuk őket, aztán valahogy mégis csak egybe gyúrjuk (shared_ptr-rel). Erre sokkal természetesebb az én megoldásom. Azt hiszem ez is egy olyan eset, amikor nem biztos hogy vakon kell követni a "kőbe vésett szabályokat" (osztályt a ctor-a teljesen kell hogy inicializálni tudjon), persze érdemes tudni ezekről, de még fontosabb hogy az okát/értelmét ismerjük, és ha az adott feladatban ennek nem felel meg, akkor el lehet tekinteni tőle. Szerintem!
-
jattila48
aktív tag
válasz
jattila48 #3076 üzenetére
Végül is ez is a BlobProcess kétfázisú inicializálása, mert a ctor-ában meg KELL hívni az sp->read() fv.-t a blob_ptr és blob_length tagok inicializálására. Ez persze nem baj, hiszen a tagokat a ctor-ban inicializálni kell. Logikailag azonban nem különbözik az én megoldásomtól, ahol az ős osztályt (és itt tekintheted tagnak, mivel nem példányosítható) szintén egy fv. hívással KELLETT inicializálni.
-
jattila48
aktív tag
válasz
EQMontoya #3075 üzenetére
Végül is tudná. Ahogy említettem, nem tudok minden forrásra egységes virtuális read_blob-ot írni. Egyébként erre gondoltál?
Az utolsó néhány sor így módosul:
class BlobProcess{
public:
BlobProcess(std::shared_ptr<SourceRead> sp):source_read_shared_ptr(sp){sp->read();process_blob(sp->get_blob_ptr(),sp->get_blob_length);}
private:
void process_blob(void *,DWORD);
std::shared_ptr<SourceRead> source_read_shared_ptr;
};
void main(){
auto source_read_file=std::make_shared<SourceReadFile>(new SourceReadFile("blob_file"));
BlobProcess blob_process(source_read_file);
} -
jattila48
aktív tag
válasz
EQMontoya #3073 üzenetére
"Amivel olvasol (legyen source), az legyen egy külön osztály, valami interface-szel. Ebből lehet leszarmaztatni sok félét"
Ezzel ugyan az a gond, mint az én megoldásomban. Az interface hogyan kapja meg a forrástól a blob-ot? A leszármazott osztály ctor-ának ugyanúgy meg kell hívni az intarface egy nem virtuális init_blob tfv.-ét, amivel ezt megteszi. Az interface-nek nem lehet a blob beolvasásra virtuális tfv.-e, mert a források különböző paraméterezést igényelnének erre (másrészt az interface ctor-ából nem szokás virtuális tfv.-t hívni). De ha lehetne is virtuális tfv.-e a forrás beolvasására, akkor is előbb létre kéne hozni az objektumot, majd meghívni rá a virtuális read-et (kétfázisú inicializálás). Gondolom az interface itt sem lenne példányosítható (hiszen ezért interface).
Valahogy így gondoltad?class SourceRead{
public:
SourceRead():blob_ptr(0),blob_length(0){}
bool read(){
return read_blob(&blob_ptr,&blob_length);
}
virtual ~SourceRead()=0{}
void * get_blob_ptr(){return blob_ptr;}
DWORD get_blob_length(){return blob_length;}
private:
virtual bool read_blob(void **blob_ptr,DWORD *blob_length)=0;
void *blob_ptr;
DWORD blob_length;
};
class SourceReadFile : public SourceRead{
public:
SourceReadFile(const std::string & source_name):source_name(source_name){}
~SourceReadFile(){/*megnyitott fajl lezarasa, allokalt memoria felszabaditasa*/}
private:
virtual bool read_blob(void **blob_ptr,DWORD *blob_length){
//source_name forras megnyitasa,beolvasando meret meghatarozasa, *blob_ptr=allokalt memoria cime,blob_length=merete
return true;
}
const std::string & source_name;
};
class BlobProcess{
public:
BlobProcess(std::shared_ptr<SourceRead> sp):source_read_shared_ptr(sp){process_blob(sp->get_blob_ptr(),sp->get_blob_length);}
private:
void process_blob(void *,DWORD);
std::shared_ptr<SourceRead> source_read_shared_ptr;
};
void main(){
auto source_read_file=std::make_shared<SourceReadFile>(new SourceReadFile("blob_file"));
source_read_file->read(); //ketfazisu inicializalas
BlobProcess blob_process(source_read_file);
}És itt már nem 2, hanem 3 osztály van, meg shared_ptr (tényleg! miért nem unique_ptr), amit nagyon nem szívesen használok. Ezzel szembem nálam 2 osztály van, amiből csak 1-et kell példányosítani, és nincs shared_ptr (sem_unique_ptr).
-
EQMontoya
veterán
válasz
jattila48 #3066 üzenetére
Nem volt időm az egészet végigolvasni, csak úgy nagyjából látom a problémát:
-Különböző forrásokból összeszedsz valami bináris adatot
-Ezt kb. egységesen olvashatod.Szerintem ennek a két funkcionalitásnak nem egy osztályban van a helye. Amivel olvasol (legyen source), az legyen egy külön osztály, valami interface-szel. Ebből lehet leszarmaztatni sok félét, aztán az olvasgató osztályod konstruktorban paraméterként kap egy shared ptr-t egy source-ra. Így lesz raii is, mert az olvasó destruálja a shared ptrt is, ami meg magát az objektumot. A shared ptren keresztül meg hívogathat rajta mindenfélét.
-
jattila48
aktív tag
-
dobragab
addikt
válasz
jattila48 #3068 üzenetére
Remek, tényleg félreértettem. Azt eddig nem mondtad, hogy a blob formátuma egységes. Azt hittem, hogy a init az adattagokat kapja paraméternek. Így kicsit félrevezető, én nem init-nek nevezném, hanem read-nek, és tkp. ő végzi a deszerializációt.
Legközelebb inkább példakódot írj, azt hamarabb megértjük, mint fél oldal szöveget
Ebben az esetben viszont rendben van így is. Egyetértek veled, jobb ez a megoldás. Én nem kettős inicializálásnak hívnám, hanem a szerializálást kiraktad a D osztályba a RAII miatt.
-
jattila48
aktív tag
válasz
dobragab #3067 üzenetére
De hát a fájl lezárás most is a dtor-ban van, de nem a ctor-ban van a megnyitás.
B leszármazottai abban különböznek egymástól, hogy más-más helyről olvassák be az egyébként ugyanolyan formátumú bináris adatot. Tehát a leszármazott osztályok egyetlen dolga, hogy ezt megtegyék, és a blob-ot átadják az ősosztálynak (erre van az init). A B nem függ a leszármazottaktól, mert ő már csak a blob-on dolgozik, de nincs értelme önálló B objektumot létrehozni, mert a blob-ot mégis csak be kell olvasni valahonnan.
"Tényleg jobb lenne D konstruktorába pakolni az allokációt, de ebben a formában nem lehet megoldani. Az ős-ctor hívása mindenképp előbb van, mint a ctor törzse, úgyhogy arra nincs esélyed normálisan megoldani."
Hát pont erről beszélek. Ha viszont a D ctor-ában szeretném megoldani az allokációt, akkor mindenképpen B::init-et kell hívnom a D ctor-ának törzsében. Ez lehet, hogy szerinted nem normális megoldás (alapesetben szerintem sem az), de mivel hogy B nem példányosítható, ezért elnézhetőnek tartom. Ha ezt nem teszem meg, akkor valóban csak ez a fajta factory megoldás marad amit írtál, azonban itt az erőforrások átvétele (shared vagy unique pointerek vagy egyéb erre a célra létrehozott osztályok formájában) sokkal macerásabb és több hibalehetőséget rejt, mint az init fv."Mindenesetre a kötelezően hívandó init() szerintem ennél sokkal büdösebb: el lehet felejteni a hívását, és B többet tud, mint a feladata."
Mint ahogy fent írtam, szerintem nem, de ez már ízlés kérdése. Azt hogy el lehet felejteni a hívását, ennyi erővel D bármely más tagjának az inicializálását is el lehet felejteni, ahogy írtam. Tulajdonképpen úgy tekinthető, hogy az init nem a B-t inicializálja, hanem a D inicializálásához szükséges. "Normál" esetben is szokás a ctor-ban különböző tagokat inicializáló fv.-eket hívni. B egyáltalán nem tud többet mint a feladata, mert a forrásról semmit sem tud, csak a blob-ot kapja meg, ami minden leszármazott esetén ugyanolyan formátumú.
"Alapesetben nem kéne, hogy egy osztálynak legyen ctor-ként működő init-je."
Valóban. De ha nem példányosítható? Erről szólt az egész elmélkedésem."Kicsit más jellegű lenne az a megoldás, ha B kap tisztán virtuális read() és write() függvényeket, és azokat override-olja D. Viszont read()-et nem hívhatod ctorból, úgyhogy ez nem működik."
Azon kívül, hogy ctor-ból nem működik, nem lehet megcsinálni, mert forrásonként különböző paraméterezést igényelne. Másrészt ekkor már tényleg fölöslegesen sokat tudna a B és függne a leszármazott osztálytól.
Minden esetre köszönöm az eddigi hozzászólásaidat, most ezt a kétféle megoldást látom alkalmasnak, a mondott okok miatt azonban a sajátomat fogom választani.
-
dobragab
addikt
válasz
jattila48 #3064 üzenetére
Az std::string filename RAII-ra átalakításánál úgy gondoltam, a kissé kreatívabban oldod meg. Pl. kap még egy paramétert a privát ctor, ami átveszi az erőforrást, és felszabadítja. Így effektíven a D-nek a read_from_file a konstruktora. A hármas szabállyal most nem tököltem.
class D : public B
{
std::string filename;
FILE * fp = nullptr;
D(FILE * fp,
std::string const& filename,
std::vector<std::string> const& param1,
std::map<int, int> const& param2) :
B{param1, param2},
filename{filename},
fp{fp}
{ }
public:
static D read_from_file(std::string const& filename)
{
fp = fopen(filename.c_str(), "r+b");
std::vector<std::string> myvec;
std::map<int, int> mymap;
// load data from file to my___
return D{fp, filename, myvec, mymap};
}
virtual void pure_virtual_func() override
{ }
virtual ~D()
{
fclose(fp);
}
};Tehát a fájl megnyitás, és a memória terület foglalás nem a D ctor-ában történik, viszont az erőforrás felszabadítást (legalábbis a fájl lezárást) a dtor-ban akarod megoldani.
Nem ott van, szándékosan. Ha jól értem, B leszármazottai abban különböznek egymástól, hogy más külső reprezentációja. B-nek az a dolga, hogy ezeken felülemelkedjen, nélkülük legyen teljes értékű. Épp ezért B-nek nem szabad függnie tőle, azt oldják meg a leszármazottak.
Tényleg jobb lenne D konstruktorába pakolni az allokációt, de ebben a formában nem lehet megoldani. Az ős-ctor hívása mindenképp előbb van, mint a ctor törzse, úgyhogy arra nincs esélyed normálisan megoldani.
Ez egy felemás RAII lenne, ami szerintem koncepcionálisan hibás.
std::shared_ptr és make_shared? Szerintem ez a megoldás pont arra hasonlít. Mindenesetre a kötelezően hívandó init() szerintem ennél sokkal büdösebb: el lehet felejteni a hívását, és B többet tud, mint a feladata. Alapesetben nem kéne, hogy egy osztálynak legyen ctor-ként működő init-je.
Kicsit más jellegű lenne az a megoldás, ha B kap tisztán virtuális read() és write() függvényeket, és azokat override-olja D. Viszont read()-et nem hívhatod ctorból, úgyhogy ez nem működik.
-
jattila48
aktív tag
válasz
jattila48 #3064 üzenetére
Arra minden esetre jó volt ez az eszmefuttatás, hogy legalább magamat sikerült meggyőzni (remélem titeket is. Vagy nem?) a megoldásom helyességéről. Vagyis ha egy osztályból csak származtatni lehet és őt magát nem lehet példányosítani, akkor nem koncepcionális hiba az osztály kétfázisú inicializálása protected init tfv.-nyel. Sőt úgy gondolom, hogy az ilyen osztályból származtatott osztály teljes értékű RAII kezelése (a ctor. foglalja le a példány "létezéséhez"/működéséhez szükséges erőforrásokat, a dtor szabadítja fel azokat) adott esetben (ha az ősosztálynak szüksége van az erőforrásokra) nem is valósítható meg másként. A free/static fv.-ek alkalmazása szükség szerűen megsérti a RAII koncepciót, hiszen már az objektum létrejötte előtt le kell foglalnia az erőforrásokat. Ezen az sem segít (sőt...), ha a felszabadítást már a dtor végzi.
-
jattila48
aktív tag
válasz
dobragab #3062 üzenetére
Ezzel csak az a bajom, hogy ez a megoldás lényegében nem különbözik attól, hogy "kívül" megnyitod a fájlt, memória területet foglalsz, oda beolvasod a fájlt, majd ezt a memória területet átadod a D ctor.-ának. Tehát a fájl megnyitás, és a memória terület foglalás nem a D ctor-ában történik, viszont az erőforrás felszabadítást (legalábbis a fájl lezárást) a dtor-ban akarod megoldani. Ez egy felemás RAII lenne, ami szerintem koncepcionálisan hibás. Az, hogy ezt az egészet bele tetted egy statikus factory fv.-be, a lényegen nem változtat. Sőt az allokált memória terület már a factory fv. lefutásával felszabadulhat (bár itt mivel const & hivatkozás van rá, valószínűleg kitart annak élettartamáig. Egyébként a const & nekem nem lesz jó, mert változni fog a memória terület, amit az objektum "elhalásakor" vissza szeretnék írni a fájlba. nem const referencia pedig tudtommal nem tartja életben a temporális objektumot. Lehet hogy tévedek!). Ha közvetlenül a D ctor-ával hozod létre az objektumot, akkor a helyzet ugyanez. Tehát a statikus factory fv. használata semmit nem tesz jobbá, a zárójeles megjegyzésem értelmében még esetleg rosszabb is lehet.
Ellenben az én megoldásommal a D ctor-ába lehet tenni mind a fájl, mind pedig a blob allokálását, és ezáltal ezeket az erőforrásokat RAII módon lehet kezelni, ahogy "kell". Ennek az ára a B kétfázisú inicializálása, ami azért nem hibás koncepcionálisan, mert sem félig, sem teljesen konstruált B objektumot nem lehet létrehozni. Mindössze a D konstruálása során van olyan pont, amikor a D B része félig konstruált, de ekkor a D még kész sincs. A protected init fv.-t kell meghívni kötelezően a D ctor.-ában, ennek elmulasztása azonban nem különbözik attól, mintha "elfelejtenénk" D valamelyik tagját inicializálni (végül is az ős osztály is egy "tagnak tekinthető"). A tagok inicializálása pedig nem csak inicializációs listában, hanem a ctor törzsében is megtörténhet, pont akkor, ha az inicalizáláshoz számításokat kell végezni. A lényeg, hogy ezzel a módszerrel D-ből csak teljesen konstruált objektumot lehet létrehozni, B-ből pedig semilyet. -
dobragab
addikt
válasz
jattila48 #3061 üzenetére
Mutatok példát egyszerű osztályokkal. Én erre gondoltam, de a te eseted ezek szerint nem pont ilyen.
Kicsit elnéztem én is, ugyanis B-t (absztrakt osztályt) nem adhat vissza érték semmilyen a függvény...
class B
{
std::vector<std::string> member1;
std::map<int, int> member2;
public:
B() = delete;
B(const B& other) = default;
B& operator=(const B& other) = default;
B(B&& old) = default;
B& operator=(B&& old) = default;
B(std::vector<std::string> const& param1,
std::map<int, int> const& param2) :
member1{param1},
member2{param2}
{ }
virtual void pure_virtual_func() = 0;
virtual ~B() { }
};
class D : public B
{
std::string filename;
public:
D(std::string const& filename,
std::vector<std::string> const& param1,
std::map<int, int> const& param2) :
B{param1, param2},
filename{filename}
{ }
static D read_from_file(std::string const& filename)
{
std::ifstream file(filename);
std::vector<std::string> myvec;
std::map<int, int> mymap;
// load data from file to my___
return D{filename, myvec, mymap};
}
virtual void pure_virtual_func() override
{ }
};Ha valamit félreértettem a feladattal kapcsolatban, szólj
Kódból jobban értek -
jattila48
aktív tag
válasz
dobragab #3059 üzenetére
"Ha B önmagában nem olvasható be, vagy D-vel együtt kellene, mert B beolvasása után kellenek még az adatok, D-t is adhat vissza a beolvasó függvény."
Factory? És ez a D-t hogy állítja elő? Egy másik construktorral? Ugyanezzel nem lehet, mert végtelen rekurzió lenne. Hogyan inicializálná a B részét a visszaadott D-nek? Hiszen most pont ezen küzdünk. Vagy ha már a beolvasó fv. visszaad D-t, akkor minek ezt újra felhasználni a D egy másik ctor-ában? Akkor már jó a most visszaadott is. Vagy a beolvasó fv. inicializálatlan B részű D-t adna vissza? Ez ismét csak kétfázisú inicializálás lenne, ráadásul rosszabb mint az enyém, mert konkrétan létre is kéne hoznod félig konstruált D-t.
A statikus tfv.-nyel való inicializálás (nem több, hanem osztályonként csak egyetlen stfv.) életképes lehet, ha nem B-t ad vissza (főleg nem pedig D-t), hanem valami egyszerű struktúrában a bináris adatot (pointer+méret: röviden blob). Itt viszont megint csak az történik, hogy a D ctor-ában meg KELL hívnod egy bizonyos fv.-t (a beolvasó statikus tfv.-t), ugyanúgy ahogy az én megoldásomban is meg KELL hívni a B init tfv.-ét. A különbség annui, hogy nálad a D ctor-ának inicializáló listájában, míg nálam a törzsben kell ezt megtenni. Ja, és szükség lesz egy "köztes" blob struktúrára (amit a beolvasó visszaad), aminél már csak az a kérdés, hogy mikor, és hogy szűnik meg. -
jattila48
aktív tag
válasz
dobragab #3059 üzenetére
Ha jól értem, akkor fájlból, innen-onnan binárisan beolvasó statikus függvény a D osztály statikus fv.-e. Minden egyes D osztályhoz csak 1 ilyen statikus fv. van (nem több forrástól függően), hiszen ha a forrás különböző, akkor az osztálynak is különbözőnek kell lenni. Vagyis igazából a forrás beolvasása a D osztály feladata, bár ha jól értem, szerinted nem. Azonban pl. a fájlból való beolvasáshoz tartozik egy file handle, amit az objektum megszűnésekor le kell zárni (RAII). Ez a file handle természetesen nem lehet a B osztály tagja, mert registryből olvasva már egy registry handle fog hozzá tartozni, stb. Vagyis egész természetes módon adódik, hogy a beolvasó fv.-nek nem statikusnak, hanem rendes tfv.-nek kell lenni. Ha egyetlen D osztály lenne, aminek forrásonként külön beolvasó statikus fv.-ei lennének, akkor a D osztály valójában felesleges, hiszen free fv.-ekkel ugyanez megoldható, a bináris adat pedig közvetlenül átadható lenne B konstruktorának.
Ha valóban a D statikus tfv.-eiről írtál, akkor a
"A statikus függvények meg lehetnek protected-ek, hogy a RAII-t ne lehessen kívülről zavarni, és hívhasd B / D ctorából." mondatodat nem értem. Ez a mondatod arra utal, hogy a B statikus tfv.-eiben valósítanád meg a beolvasást, ami azért nem lenne jó, mert előre nem tudhatja a B írója, hogy milyen forrásokból lesz a beolvasás.
"B innentől önállóan is működőképes osztály": Mármint úgy, hogy a konstruktorának meg tudunk adni bináris adatot is (pointer+méret: röviden blob)? Erre egyáltalán nincs szükség, hiszen ha ilyen osztály kellene, írnék egy leszármaztatott D-t ami pont ezt tudja. -
dobragab
addikt
válasz
jattila48 #3058 üzenetére
Most már nekem is kicsit koncepcióhiba-szagú, persze simán lehet, hogy indokolt.
B ellátja a funkcióját, valamilyen adatokon dolgozik. Adsz neki egy ctort, ami az adattagjait darabonként inicializálja, és nem bűvészkedik a bináris adatokkal.
A bináris memóriaterületből olvasás, feldolgozhatóvá alakítás ilyen formában (pointer + méret) nem egy osztály dolga, hanem egy függvényé. Tipikusan egy statikus függvényé, ami megkapja fájlnevet, akármit, és visszaad érték szerint egy B-t. Én ebből csinálnék többet, attól függően, hogy fájl / registry / memória a forrás. Ezek hívják majd B adattagonként inicializáló konstruktorát. A statikus függvények meg lehetnek protected-ek, hogy a RAII-t ne lehessen kívülről zavarni, és hívhasd B / D ctorából. Írj B-nek move ctort, akár default is jó lehet.
Ezzel különválasztottad a program egyáltalán nem összetartozó részeit. B innentől önállóan is működőképes osztály, és hogy a te programodban mindig fájlból érkezik, az mellékes.
Ezután D konstruktora valahogy így nézhet ki:
D::D(std::string filename, T data) :
B{std::move(D::ReadFrom(filename))},
data{data}
{ }Ha B önmagában nem olvasható be, vagy D-vel együtt kellene, mert B beolvasása után kellenek még az adatok, D-t is adhat vissza a beolvasó függvény.
-
jattila48
aktív tag
válasz
dobragab #3057 üzenetére
Akkor egy kicsit konkrétabban: B egy olyan osztály, ami bináris adatot tartalmazó memória területet dolgoz fel. A memória terület pointerét, és méretét kapja meg az init tfv.-ből. Van nem default ctor-a, amiben egyéb paramétereket vár. A leszármazott D osztály valahonnan (pl. file, registry, stb.) beolvassa a bináris adatot, lefoglalja a megfelelő memória területet, és ennek a címét és méretét a B::init-nek argumentumként átadva B::init meghívásával (a D ctor-ában) teljesen inicializálja B-t. A D ctorának fájl név a paramétere, ha fájlból olvas, vagy registry kulcs, ha registryből, stb. A probléma az, hogy ha nem az init-et hívom, hanem a B ctorának akarnám átadni a memória területet, akkor az adatot előbb kellene beolvasni, mint ahogy a B ctora meghívódik. Azonban az adat beolvasást mindenképpen a D ctor-ában szeretném elvégezni, nem pedig kívül (pl. RAII miatt). Ha a B ctor-ának az egyéb paraméterek mellett a memória pointer és a méret is paramétere lenne, akkor ezeket valahogy az inicializáló listában kéne előállítani (akár D statikus fv.-ei segítségével). Ehelyett én azt mondom, hogy mivel B-t nem lehet példányosítani, a D pedig nem tekinthető teljesen megkonstruáltnak ha nem hívja meg ctor-ából az init-et, talán elfogadható a B kétfázisú inicializálása. Ez koncepcionálisan nem mond ellent annak, hogy ne hozzunk létre félig konstruált objektumot, mivel ha D a konstruktorában nem hívja meg az init-et, akkor maga a D tekinthető félig konstruáltnak.
-
dobragab
addikt
válasz
jattila48 #3055 üzenetére
Írj B-nek konstruktort init helyett. Absztrakt osztálynak simán lehet konstruktora, pont az ilyen esetekre, és default ctor-t tiltsd le. D ctor-ban pedig B{args} az inicializáló listában.
A számításokat pedig szerintem el lehet végezni az inicializáló listában is, az ős-ctor hívása előtt, a paraméterekben, ha máshogy nem, vessző operátor segítségével
Szerk: ha bonyolultabbak a számítások, a statikus függvény jó ötlet
Factory? -
EQMontoya
veterán
-
jattila48
aktív tag
A kétfázisú inicializálást általában nem kívánatosnak (esetleg tervezési hibának) tartják. De mi a helyzet olyan bázis osztály (B) esetén, amit nem lehet példányosítani (pl. pure virtual tfv. miatt), hanem csak leszármaztatni lehet belőle? A B-nek van egy protected nem virtuális init tfv.-e, ami elvégzi a B teljes inicializálását. A leszármaztatott D osztály konstruktorából ezt az init-et kell meghívni az éppen most kiszámított argumentumokkal. Sajnos az init meghívását nem lehet kikényszeríteni. Szerintetek elfogadható-e a B kétfázisú inicializálása (szerintem igen), vagy valami elegánsabb (idiomatikusabb) megoldást kéne alkalmazni?
-
EQMontoya
veterán
válasz
ToMmY_hun #3050 üzenetére
Végezhető munka mellett, de szerintem nem ad annyi hasznos tudást, amennyi szopás van vele.
Főleg, hogy BME-n pl. csak nappalin van, OE-n meg van esti, de sajna eléggé gittegylet.
Ráadásul az értelmes tárgyak leginkább szabadon választhatók, amikkel nem fogsz foglalkozni, ha meló mellett végzed.Szóval én nem vágnék bele.
-
ToMmY_hun
senior tag
OFF: Gyakorlati szempontokat figyelembe véve, úgy mint megszerzett tudás (ami fel is használható), fizetés illetve későbbi előbbre lépési lehetőség szerint érdemes MSc-re menni? (Számomra a legfontosabb paraméter a megszerezhető ismeretanyag, a többi csak plusz tényezőként lett felsorolva jóval kisebb súllyal.)
Felvetődött ötletként, hogy jelentkeznék villamosmérnöki diploma után mérnök informatika MSc képzésre a BME-re, de egyelőre még csak puhatolózok a témában. Úgy érzem hasznos lenne az a matematikai ismeretanyag, amit ott meg lehet szerezni (Óbudain tanultam és itt elég gyenge a matek oktatás), nem beszélve a többi szakmához szorosan kapcsolódó ismeretről. Csinálta valaki az MSc-t munka mellett? Vannak esetleg erről tapasztalatok?Előre is köszönöm a válaszokat, akár privátban is megkereshet akinek lenne információja.
-
EQMontoya
veterán
válasz
mrhitoshi #3048 üzenetére
Nem fogtam fel teljesen a kódot, de ha jól értem a ciklust, csak akkor áll le a program, ha x==s && y==0 állapot áll fenn egyszerre. (legalábbis egymás epszilon sugarú környezetében van)
Valószínűleg ez nem teljesül valamilyen számítási hiba miatt soha.
Az 1g ram pedig azért van, mert mindig eltárolod az eredményt, de a végtelenségig tárolgatsz.
Valamelyik képleted lesz rossz, ennek pillanatok alatt kellene lefutnia.Erre a részre gondolok:
for (t = 0; 1; t += TIME_STEP)
{
x = get_x(type, v_0, t, alfa, k, m);
y = get_y(type, v_0, t, alfa, k, m);
//A MARGIN szerepe, hogy hova kerüljön a koordináta rendszer, margóként szolgál, és a SIZE adja meg a nagyságát.
draw_x = (int)round(SIZE * (x / s)) + MARGIN;
draw_y = (int)round(fabs(SIZE * (y / max_y) - SIZE)) + MARGIN;
graph_x = (int)round((x / s) * GRAPH);
graph_y = (int)round((y / max_y) * GRAPH);
graph_set(&graph, graph_x, graph_y);
//Itt kapja meg a koordinátákat az .svg fájloknak megfelelő stílusban.
fprintf(f, "%s %d %d ", (t == 0 ? "M" : "L"), draw_x, draw_y);
if (comp(x, s) && comp(y, 0))
{
graph_draw(&graph);
break;
}
} -
mrhitoshi
veterán
Üdv! Írtam egy programot arra, hogy hogyan fog repülni egy ágyúgolyó a kilövés után. A program figyelembe veszi a légellenállást is, elvileg.
Az lenne a gond, hogy a program gyorsan lefut, ha nincs légellenállás... ki hitte volna, az matematikailag könnyebb feladat. A kódot úgy írtam meg, hogy fogtam a dolog fizikáját, és megoldottam a differenciálegyenletet, majd pedig a kapott függvényeket leprogramoztam. A program jól működik, ha nincs légellenállás, szépen megadja a kilövési sebességhez, és a távolsághoz tartozó szöget, és szépen ki is rajzolja, tehát ezzel nincs gond. A légellenállásos egyenletekkel viszont nem tud megbirkózni. 16 percen keresztül számolt, közben 1 GB memóriát elhasznált, és semmi eredmény. Igaz sajnos, csak egy szálon fut a program.
Van valami ötlet esetleg erre a problémára ? Nem tudom linkeljek programkódot ?A vicces a dologban az, hogy még így is csak közelítek a valósághoz.
-
dobragab
addikt
Ez klasszikus
-
cattus
addikt
Ha már mindenki bedobálja a "mit ír ki" kódjait, itt egy tőlem is:
#include <stdio.h>
main(t, _, a) char *a; {
return!0<t ? t<3 ? main(-79, -13, a + main(-87, 1 - _, main(-86, 0, a + 1) + a)) :
1, t<_ ? main(t + 1, _, a) : 3, main(-94, -27 + t, a) && t == 2 ? _<13 ?
main(2, _ + 1, "%s %d %d\n") : 9 : 16 : t<0 ? t<-72 ? main(_, t,
"@n'+,#'/*{}w+/w#cdnr/+,{}r/*de}+,/*{*+,/w{%+,/w#q#n+,/#{l+,/n{n+,/+#n+,/#\
;#q#n+,/+k#;*+,/'r :'d*'3,}{w+K w'K:'+}e#';dq#'l \
q#'+d'K#!/+k#;q#'r}eKK#}w'r}eKK{nl]'/#;#q#n'){)#}w'){){nl]'/+#n';d}rw' i;#\
){nl]!/n{n#'; r{#w'r nc{nl]'/#{l,+'K {rw' iK{;[{nl]'/w#q#n'wk nw' \
iwk{KK{nl]!/w{%'l##w#' i; :{nl]'/*{q#'ld;r'}{nlwb!/*de}'c \
;;{nl'-{}rw]'/+,}##'*}#nc,',#nw]'/+kd'+e}+;#'rdq#w! nr'/ ') }+}{rl#'{n' ')# \
}'+}##(!!/")
: t<-50 ? _ == *a ? putchar(31[a]) : main(-65, _, a + 1) : main((*a == '/') + t, _, a + 1)
: 0<t ? main(2, 2, "%s") : *a == '/' || main(0, main(-61, *a,
"!ek;dc i@bK'(q)-[w]*%n+r3#l,{}:\nuwloca-O;m .vpbks,fxntdCeghiry"), a + 1);
} -
dobragab
addikt
Napi mitírki. Az első C, a második C++. Feltéve, hogy a char 1, az int 4 bájtos.
1.
printf("%d", sizeof('a'));
printf("%d", sizeof(+'a'));2.
std::cout << sizeof('a');
std::cout << sizeof(+'a'); -
dobragab
addikt
Nyissunk nektek Optimalizálás topikot?
-
jattila48
aktív tag
válasz
jattila48 #3025 üzenetére
Kissé off topic, de azért érdekes:
A legkisebb dobás meghatározásakor EQMontoya kifogásolta, hogy fölöslegesen vezettem be a legkisebb_dobas változót, mert tömb indexeléssel is megoldható lett volna. Ez igaz, azonban ahogy írtam, valószínűleg hatékonyabb így, mert a feltétel kiértékelésben megspórolom az egyébként költséges tömb indexelést, ezzel szemben az if törzsben "bevásárolok" egy értékadást. Ha az értékadások össz költsége kisebb mint a tömbindexelések össz költsége, akkor ez megéri (itt most figyelmen kívül hagyom az egyetlen tömb indexelés, és értékadás közötti költségek viszonyát). Mivel a feltétel jóval ritkábban értékelődik igazra, ezért az értékadás is jóval ritkábban lesz végrehajtva. Nos, kiszámoltam, hogy mennyi is az annyi. A konkrét feladatban [0,10] intervallumból generáltunk egyenletes eloszlással egy 10 elemű tömböt. Ekkor nyilván a generált sorozatok eloszlása is egyenletes. Kiszámoltam, hogy a konkrét feladatban mi a várható értéke a feltétel igazra értékelődésének, és 2,55 adódott, bele számolva a legkisebb_dobas kezdő értékadását is. A tömb indexelős megoldással ezzel szemben 10 indexelés adódik. Tehát tényleg hatékonyabb az értékadós megoldás. -
LordX
veterán
válasz
EQMontoya #3035 üzenetére
Lehet jó falura, de ugyanannyit kell írni (na jó, a függvény/osztálynevek hosszabbak), ha rendesen használsz <random>-ot.
Map: Nem értek egyet: mivel a map node-okban tárolja az adatot, amiben benne van a kulcs, az érték, és jellemzően 3 pointer (left, right, parent), ezért masszívan több memóriát foglal, mint a vector: Az összes általam ismert 64 bites implementációban 32 byte + sizeof(pair<K,V>) a node méret + allocation overhead. Win x64-en a sizeof 16 bye, tehát 40 byte a blokk, ahol az overhead átlagosan 56 byte (!!), azaz 96 byte. Per node. Ja, és a map-nek kell egy extra node (az end node). Szóval 10 elemhez kell 1056 byte heap memória map-el.
Vector esetében ez N*sizeof(int) + overhead, ami most 10*4+56 = 96, összesen a 10 elemre. 100 elemre ez 9696 vs 449 byte.
Szóval ha a cellák több, mint ~9%-át használod ki, akkor a vector nyer map ellen. És még nem is beszéltünk mennyire cache-friendly a vector, és mennyire cache-ellenséges a map; hogy a vektorban indexelsz, nem keresel.
Azért ha tényleg el kell tárolnod a kulcsot, egy kategóriával szebben áll a map, de még mindig vesztésre áll, nem véletlen van a flat_map a boost-ban (ami gyakorlatilag egy map interfész vector felett).
-
-
jattila48
aktív tag
-
jattila48
aktív tag
válasz
EQMontoya #3024 üzenetére
Részben igazad van, viszont az if feltételben megspóroltam egy tömb indexelést. Talán ez a megoldás hatékonyabb, és jobban átlátható. A gi-t sem kellett volna bevezetni, de ugyanezért lett az is. Nem tartozik ide, de szoktál assembly kódot debuggolni? Ott látszik, hogy egy tömb indexelés költségesebb mint egy sima változó elérés. Az értékadás pedig csak az if törzsében történik meg, ami feltehetően jóval ritkábban fut le, mint a feltétel kiértékelése.
-
jattila48
aktív tag
válasz
EQMontoya #3022 üzenetére
Nem szoktatom én sehogy, de hát a GURIT és TAR neveket nem én adtam, pedig szerintem magyarul vannak. Egyébként fogd fel úgy, hogy komment helyett adtam ilyen neveket. Vagy magyarul kommentezni is főbenjáró bűn?
"jobb helyen hirtelen felindulásból leggépuskáznak érte!" Ilyen helyekre én nem járok."A legkisebb dobás és a sorszámának külön eltárolása meg elég béna, ha egy egyszerű tömbindexeléssel elérhető hozzá az adat."
Ezt nem értem. Elmagyaráznád? -
-
jattila48
aktív tag
válasz
Mikeboy666 #3019 üzenetére
srand(time(NULL)); // véletlen generátor inicializálása
int GURIT[10], TAR[11] = { 0 }, i; // A TAR[] -ban számoljuk, hogy az egyes dobásokból mennyi volt
for (i = 0; i<10; i++) //ellenőrzött dobás bekérés
{
GURIT[i] = rand() % 11 ;
}
int dbparos = 0, guritasok_osszege=0,legkisebb_dobas=GURIT[0],legkisebb_dobas_sorszama=0;
//kezdetben feltetelezed, hogy az elso guritas a legkisebb
for (i = 0; i<10; i++) // eredmények megszámlálása
{
int gi=GURIT[i]; //segedvaltozo, hogy ne kellje mindig kiindexelni az i. guritast (hatekonyabb)
++TAR[gi];
if (gi % 2 == 0)dbparos++;
guritasok_osszege+=gi;
if(gi<legkisebb_dobas){
//a most vizsgalt guritas kisebb, mint az eddig megtalalt legkisebb, most mar ez lesz a legkisebb
legkisebb_dobas=gi;
legkisebb_dobas_sorszama=i;
}
}
for (i = 0; i<11; i++) // eredmények kiíratása
cout << "\nA(z) " << i << "-es dobasok szama:\t" << TAR[i];
cout << endl;
cout << "A paros dobasok szama:\t" << dbparos;
cout << endl;
cout << "A dobasok osszege:\t" << guritasok_osszege;
cout << endl;
cout << "Az (elso) legkisebb dobas erteke:\t" << legkisebb_dobas << "sorszama: " << legkisebb_dobas_sorszama+1;
cout << endl; -
Mikeboy666
csendes tag
válasz
sztanozs #3004 üzenetére
Bocsi még kezdő vagyok... Csak próbálkozom.... Abban tudnál segíteni még, hogyan kellene a tömböket összeadás, pontosan arra gondolok, hogy mennyi a guritások összege, azt, hogy csinalnád??? Illetve, hogy kiírja a legkisebb dobás sorszámát... Maxindex és minindex értékadással??? Sorry a hülye kérdésekért...
-
dobragab
addikt
válasz
jattila48 #3012 üzenetére
Ha észrevetted, kapott már olyan választ, amilyet te elvársz. EQ megmutatta, hogy ezt igazán C++-osan hogyan illik. Pl. tőlem mindenképpen kapott volna egyszerű választ.
Ajánlom figyelmedbe Stroustrup intelmeit az Újszövetségből. (The C++ Programming Language 4th Edition)
[8] Minimize the use of arrays and C-style strings. C++ standard-library strings (§4.2), arrays (§8.2.4), and vectors (§4.4.1) can often be used to write simpler and more maintainable code compared to the traditional C style. In general, try not to build yourself what has already been provided by the standard library.
[10] Do not assume that something laboriously written in C style (avoiding C++ features such as classes, templates, and exceptions) is more efficient than a shorter alternative (e.g., using standard-library facilities). Often (but of course not always), the opposite is true.
-
jattila48
aktív tag
válasz
EQMontoya #3011 üzenetére
Nekem úgy tűnt, hogy a kérdező erre a konkrét feladatra volt kíváncsi, nem pedig az STL rejtelmeire. Szerintem ez számára nem könnyíti meg a dolgot. Annál is inkább, hogy alapvető dolgokkal van problémája (ld. case szerkezet), inkább ezekben kéne segíteni neki. Itt többen, többször elkövetitek azt a hibát (akinek nem inge ne vegye magára), hogy nem a kérdésre válaszoltok, hanem egyfajta összekacsintós bennfentes módon csillogtatjátok a magas szintű tudásotokat, ami a kérdezőnek ugyan nem segít, viszont fellengzőssé és lekezelővé teszi a hozzászólásotokat.
-
EQMontoya
veterán
válasz
jattila48 #3009 üzenetére
Ez nem a teljesítményről szólt éppen (nyilván erről 10 elemnél nem lehet beszélni), hanem arról, hogy használjuk kihasználjunk olyan működéséket, amik kényelmesek és megkönnyítik a dolgunkat.
Ha gyors kódot akarsz írni, akkor meg static array, ami alapból zero inites, és csinálod rajta ugyanezt.dobragab: kihasználtam az int zero initjét, amit a static array ugyan tud, de tömb vagy vektor nem. Illetve ha megnézed az utolsó mondatomat, a kulcsok rendezettségét és validálását is ki tudod használni.
A map azért elég jó olyan felhasználásra, amikor a kulcsaid csak az értékkészlet kis részét (<20%) fedik le.
-
jattila48
aktív tag
válasz
EQMontoya #3008 üzenetére
"Erre való a map"
Hogyne! Mindjárt ágyúval verébre. Így lehet egy nagyon egyszerű, jó esetben pár száz byte-ra leforduló programból több megás lomha bloatware-t csinálni. Sajnos manapság tényleg ez a tendencia, és ez nem kis részben a "mindenre jó" template könyvtáraknak köszönhetö. Semmi funkcionalitású pimfli kis programok akkorák, hogy nem is olyan régen egy op. rendszer kisebb volt. Ide pl. nagyon nem kell a map a maga red-black tree megvalósításával, erősen túllövése a dolognak. -
EQMontoya
veterán
válasz
sztanozs #3006 üzenetére
Valami init kellene annak a randomnak, hogy ne ugyanaz potyogjon belőle mindig.
Amúgy jól elbonyolítottad Te is.
Erre való a map.
Ugye map<int, int>, aztán index operátorral rányomulsz. Mivel van defualt initializaiton a value-ra, ha nem létezett az adott key, és ezt intnél pont 0, ezért nyugodtan lehet indexelni. Másrészt kulcs szerint rendezett, tehát az első elemre, amelyiknél nem 0 a value, megvan a legkisebb generált érték.Valahogy így:
map<int,int> results;
int num_of_even=0;
srand (time(NULL));
for(int i=0; i<11; results[rand() % 11]++,++i);
for(int i=0; i<11; num_of_even += results[i], i+=2);
auto it = find_if(results.begin(), results.end(), [] (const std::pair<int, int>& v) { return v.second > 0; } );És kész is. *kezét összecsapja smiley*
Nyilván a dolog még egyszerűbb amúgy, mert a minimum simán results.begin()-ben van a feltöltés után, de jól esett megírni egy lambdát.
-
sztanozs
veterán
válasz
Mikeboy666 #3002 üzenetére
Amúgy
GURIT[i] = rand() % 11+ 1;# include <iostream>
#include<ctime>
using namespace std;
int main()
{
srand((unsigned int)time(NULL)); // véletlen generátor inicializálása
int GURIT[10]; //10 guritas
int TAR[11] = { 0 }; // A TAR[] -ban számoljuk, hogy az egyes dobásokból [0, 10]
int i; //index
int dbparos = 0; //paros dobasok szama
//mennyi volt
for (i = 0; i<10; i++) //ellenőrzött dobás bekérés
{
GURIT[i] = rand() % 11; // [0, 10]
}
for (i = 0; i<10; i++) // eredmények megszámlálása
{
++TAR[GURIT(i)];
if (GURIT(i) % 2 == 0) ++dbparos;
}
for (i = 0; i<10; i++) // eredmények kiíratása
{
cout << "\nA(z) " << i << "-es dobasok szama:\t" << TAR(i);
cout << endl;
}
cout << "\nA(z) paros dobasok szama:\t" << dbparos;
cout << endl;
system("pause");
return 0;
} -
sztanozs
veterán
válasz
Mikeboy666 #3002 üzenetére
switch (GURIT(i))
{
case 1: TAR[0]++; break;
case 2: TAR[1]++; break;
case 3: TAR[2]++; break;
case 4: TAR[3]++; break;
case 5: TAR[4]++; break;
case 6: TAR[5]++; break;
case 7: TAR[6]++; break;
case 8: TAR[7]++; break;
case 9: TAR[8]++; break;
case 10: TAR[9]++; break;
case 11: TAR[10]++; break;
}btw akkor már az else ág hol marad?
-
Mikeboy666
csendes tag
Most itt tartok, azt, hogy 0 és 10 közé eshet (0 és 10 is lehet) hogyan tudom megcsinálni, bocs a buta kérdésért...
# include <iostream>
#include<ctime>
using namespace std;
int main()
{srand((unsigned int)time(NULL)); // véletlen generátor inicializálása
int GURIT[10], TAR[10] = { 0 }, i; // A TAR[] -ban számoljuk, hogy az egyes dobásokból
//mennyi voltfor (i = 0; i<11; i++) //ellenőrzött dobás bekérés
{
GURIT = rand() % 11 + 1;
}
int dbparos = 0;
for (i = 0; i<10; i++) // eredmények megszámlálása
{
switch (GURIT(i))
{
case 1: TAR[0]++; break;
case 2: TAR[1]++; break;
case 3: TAR[2]++; break;
case 4: TAR[3]++; break;
case 5: TAR[4]++; break;
case 6: TAR[5]++; break;
case 7: TAR[6]++; break;
case 8: TAR[7]++; break;
case 9: TAR[8]++; break;
case 10: TAR[9]++; break;
case 11: TAR[10]++; break;
}
if (GURIT(i) % 2 == 0)dbparos++;
}
for (i = 0; i<10; i++) // eredmények kiíratása
cout << "\nA(z) " << i + 1 << "-es dobasok szama:\t" << TAR(i);
cout << endl;
cout << "\nA(z) paros dobasok szama:\t" << dbparos;cout << endl;
system("pause");
return 0; -
Karma
félisten
válasz
Mikeboy666 #3000 üzenetére
Olvashatatlan leginkább. A fórummotor alaphelyzetben kiveszi az indentálásokat, és a [i]-t szereti dőlt formázásnak értelmezni, amitől elrontja a kódodat végig. Kérlek, használd a Programkód gombot, amikor kódot másolsz be.
(Most átformázom kézzel grátisz.)
Új hozzászólás Aktív témák
Hirdetés
● ha kódot szúrsz be, használd a PROGRAMKÓD formázási funkciót!
- iPad Pro 11 gen 2 + magic keyboard magyar makulátlan új állapot
- AMD Radeon RX 6700 XT 12GB
- X13 Yoga Gen2 13.3" FHD+ IPS érintő i5-1135G7 16GB 256GB NVMe ujjlolv IR kam aktív toll gar
- HP Elitebook Folio 9470M laptop (14/i7-G3/6GB/256SSD)
- iPhone XS Max 64GB Független Újszerű/1 hónap gar./Akku 100%/p4303
Állásajánlatok
Cég: CAMERA-PRO Hungary Kft
Város: Budapest
Cég: PCMENTOR SZERVIZ KFT.
Város: Budapest