Inicializace dvojrozmerneho pole v konstruktoru tridy – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Inicializace dvojrozmerneho pole v konstruktoru tridy – C / C++ – Fórum – Programujte.comInicializace dvojrozmerneho pole v konstruktoru tridy – C / C++ – Fórum – Programujte.com

 

Laďas
~ Anonymní uživatel
12 příspěvků
15. 3. 2009   #1
-
0
-

Zdravím všechny,
vytvořil sem si jednoduchou třídu Oblasti, která má jednu
privátní proměnnou. Dvojrozměrné pole vector obsahující
dvojice : ukazatel na objekt Node a boolovskou proměnnou.
Počet řádků i sloupců toho pole je předem známý, je určen makry
PPRV_RADKY a PPRV_SLOUPCE. ( Proto bych chtěl předem vymezit
celý prostor pole a ne jednotlivě přidávat řádky ) Toto pole bych
chtěl inicializovat (alokovat prostor) v konstruktoru třídy. Průběh
Inicializace si představuji následovně. Nejprve by se měli naalokovat řádky.
Takze nejak takhle pprv(PPRV_RADKY) a potom ve for cyklu by se
alokovali sloupce. for(int i = 0; (int) i < pprv.size(); i++)
pprv[i] = vector < pair <Node *, bool> >(PPRV_SLOUPCE, pair<NULL, true>);
Přičemž hodnota každé dvojice pole by byla NULL a true.
Snažil sem se to vygooglit ale nenašel sem nic použitelného. Buď
sem hledal špatně a nebo to nejde. Budu rád za jakýkoliv příspěvek,
případně pokud by to někdo věděl a mohl uvést příklad bylo by to
uplně super !

Předem díky všem.

#include <vector>

#define PPRV_RADKY 20
#define PPRV_SLOUPCE 6

using std::vector;
using std::pair;

class Oblasti
{
vector < vector < pair <Node *, bool> > > pprv;
public:
Oblasti() {
// !!!sem doplnit kod inicializace pole pprv !!!
}
~Oblasti();
};

Nahlásit jako SPAM
IP: 88.100.12.–
tmi0
Věrný člen
15. 3. 2009   #2
-
0
-

pokud dopredu vis rozmery pole, pak je dle me lepsi ho alokovat staticky, a ne jako vector. tedy jednoduse pair<Node*,bool> pole [H][W];
inicializace v konstruktoru je primocara. pokud presto chces vector, pak si alokaci dostatecneho poctu polozek zaridis volanim reserve, popr. resize (rozdil je v tom, ze reserve pouze alokuje misto, a vector se stale bude tvarit jako prazdny: tedy nemuzes indexovat vsechny polozky, a prvky pridavas pomoci push_back; zatimco resize primo zmeni udaj o velikosti vectoru, a muzes vsechny polozky rovnou indexovat).
tedy neco jako:
pole.resize( H );
for(i=0;i<H:i++)
pole[i].resize(W); /* nevyhoda tohoto reseni je, ze te stoji docela dost casu (obzvlaste pokud takovychto trid bude vice) */
jak je to s bezparametrickym konstruktorem pairu nevim, radsi si od pairu vyded vlastni tridu ktere napis bezparametricky konstruktor nastavujici zadane hodnoty.

Nahlásit jako SPAM
IP: 213.226.226.–
ksp.mff.cuni.cz -- doporučuje 5 z 0 přetečených bufferů!
Laďas
~ Anonymní uživatel
12 příspěvků
15. 3. 2009   #3
-
0
-

No ono takhle, abych to uvedl na správnou míru. Předem je známý
jen počet řádků toho pole, ale počet sloupců ne, a navíc počet těch
položek na řádku se bude v průběhu vykonávání programu také měnit.
Proto potřebuji mít to pole nestatické. Jinak na inicializovanych hodnotach
v tom poli tak uplně nezáleží. Neni podstatne jestli tam bude NULL, a true.
To se bude upravovat později. Takže pokud sem dobře pochopil to s tím
reserve bude to v konstruktoru vypadat asi takhle...




pprv.reserve(PPRV_RADKY);
vector< pair<Node *, bool > > vp;
for(vector<vector <pair <Node *, bool> > >::iterator h = pprv.begin(); h < pprv.end(); h++)
{
h.push_back(vp);
h.reserve(NEJAKE_PREDEM_NEZNAME_CISLO);
}



Nahlásit jako SPAM
IP: 88.100.12.–
Laďas
~ Anonymní uživatel
12 příspěvků
15. 3. 2009   #4
-
0
-

Pardon oprava. Jde mi jen o prostor ne prvky, ty si tam vlozim pozdeji. Chci jen dost mista, aby nedoslo
k prekopirovavani z nedostatku vymezeneho mista...



pprv.reserve(PPRV_RADKY);

for(vector<vector <pair <Node *, bool> > >::iterator h = pprv.begin(); h < pprv.end(); h++)

{
h->reserve(NEJAKE_PREDEM_NEZNAME_CISLO);
}


Nahlásit jako SPAM
IP: 88.100.12.–
tmi0
Věrný člen
15. 3. 2009   #5
-
0
-

To Laďas : jasne to je ta myslenka. ale jeste bych dodal, ze ac jsou iteratory sexy, tak nejsou uplne rychle. v takove situaci bych se vubec nestydel pouzit klasicky pruchod po jedne... vznikly pocet instrukci je odhadem trikrat mensi nez pri iteratoru

ale v obou pripdach volej resize a ne reserve (tedy alespon v situaci pprv.resize; u prvku tohoto vectoru uz to zalezi na pozdejsi situaci). pokud totiz zavolas reserve na prazdny vector, tak zustane prazdny, jen bude zabirat vice pameti: tedy jeho size bude rovna nule, stejne tak end == begin, a pristup k nekteremu prvku vectoru vyvola chybu. pokud zavolas resize, primo ovlivnis zminene atributy.

Nahlásit jako SPAM
IP: 213.226.226.–
ksp.mff.cuni.cz -- doporučuje 5 z 0 přetečených bufferů!
Laďas
~ Anonymní uživatel
12 příspěvků
15. 3. 2009   #6
-
0
-

to tmi To tmi : Dik chlape pomohl jsi mi :smile2: Jasne to sem pochopil. Na sexy iteratory :smile5: si dam pozor, budu to ale muset jeste overit. Prislo mi prave efektivnejsi pouzit iteratory, protoze pri pouziti for cyklu kde bych to pole indexoval dochazi k vypoctu adresy daneho prvku v poli. Coz mi prislo neefektivni...

Nahlásit jako SPAM
IP: 88.100.12.–
tmi0
Věrný člen
15. 3. 2009   #7
-
0
-

To Laďas : a myslis ze pri iteratorech se to nedeje?:) adresu kam zapisovat musis zjistovat vzdy, a pokud indexujes celym cislem da se to zvladnout jedinou instrukci, konkretne lea. jak presne to delaji iteratory nevim, ale rychleji z principu ani nemuzou (nehlede na to, ze pokud tech radku mas mas malo a je dopredu znam jejich pocet, chytry kompilator to u klasickeho pruchodu zoptimalizuje tak ze se vubec nepouzije cyklus)

Nahlásit jako SPAM
IP: 213.226.226.–
ksp.mff.cuni.cz -- doporučuje 5 z 0 přetečených bufferů!
Laďas
~ Anonymní uživatel
12 příspěvků
15. 3. 2009   #8
-
0
-

To tmi : Nez bych to tu rozepisoval radeji uvedu priklad.




#define ROZMER
int pole[10][10];

// neefektivne
for(int i=0;i< ROZMER: i++)
for(int j=0;j< ROZMER: j++)
pole[i][j]= 0;

//efektivne
int rozsah = ROZMER * ROZMER;
int *pint = &pole[0][0];
for(int i=0; i < rozsah: i++)
{
*pint = 0;
++pint;
}




Rekl bych ze ten druhy for cyklus bude efektivnejsi protoze se tam neustale neprepocitava ta adresa jako u toho prvniho, pouze inkrementuje. POdobne sem myslel ze je to i s iteratory.

Nahlásit jako SPAM
IP: 88.100.12.–
tmi0
Věrný člen
20. 3. 2009   #9
-
0
-

To Laďas : pravda je ze bez zapnute optimalizace bude ten druhy cyklus o neco lepsi, kompilator (gcc) ten vnoreny cyklus prelozil docela hloupe - zatimco v druhem cyklu primocare projede pole, v prvnim adresu vypocitava docela podivne s pouzitim tri registru... ale v praxi by se to dle me moc neprojevilo (snad jen kdyz by to pole bylo hodne velike, v takovem pripade by to ale stejne bylo prebito poctem cache misu), obzvlaste kdyz by se kompilovalo se zapnutou optimalizaci. ona totiz slozitejsi adresova reference nestoji zadnou instrukci navic,
takze jedine co vadi je tech par aritmetickych operaci, ktere jsou ale velice rychle.

kazdopadne je ale pouziti iteratoru je vyrazne pomalejsi nez jakykoli primocary pristup... vyzkousej a uvidis:)

Nahlásit jako SPAM
IP: 213.226.226.–
ksp.mff.cuni.cz -- doporučuje 5 z 0 přetečených bufferů!
Laďas
~ Anonymní uživatel
12 příspěvků
24. 3. 2009   #10
-
0
-

To tmi : Ja sem to pak jeste zkousel v kombinaci ukazatel na pocatek pole + nejaky offset a bylo to jeste rychlejsi nez obe vyse zminovane moznosti. Mas urcite pravdu, aritmeticke operace byvaji co do poctu taktu provedeny mnohem rychleji nez samotna adresace pameti, takze ten vypocet by na rychlost nemel mit vliv. Nezkousel sem to, ale verim, ze pouziti iteratoru bude v tomto pripade pomalejsi nez "klasicky" for cyklus. Bohužel ale, tento přístup nelze použít u spousty jiných dost často používaných kontejnerů, které alokují pamět nespojitě. Např list nebo set atp. Takže pokud nejde vyloženě o rychlost je někdy pohodlnější použít metodu COPY & PASTE, když už to bylo někde předtím napsané, třeba pro jiný kontejner.

Nahlásit jako SPAM
IP: 88.100.12.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 63 hostů

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý