Procházení vektoru - iterátor nebo index? – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama
Reklama

Procházení vektoru - iterátor nebo index? – C / C++ – Fórum – Programujte.comProcházení vektoru - iterátor nebo index? – C / C++ – Fórum – Programujte.com

 

Hledá se programátor! Plat 1 800 € + bonusy (firma Boxmol.com)
hlucheucho+10
Posthunter
3. 2. 2015   #1
-
0
-

Ahoj,

mám projít vektor ukazatelů od druhého prvku vč. po konec vektoru (vynechat první prvek). Který postup byste zvolili - iterátor nebo index?

hu

Nahlásit jako SPAM
IP: 2001:67c:1222:800:e478:81...–
Reklama
Reklama
ondrej39+1
Věrný člen
4. 2. 2015   #2
-
0
-
Nahlásit jako SPAM
IP: 46.39.172.–
Inject all the dependencies!
BDS+2
Věrný člen
4. 2. 2015   #3
-
0
-

#1 hlucheucho
Když mi nikdo, kdysi neuměl vysvětlit z jakého důvodu bych měl nahradit index iterátory (jde o běžné procházení indexovaného vektoru), tak jsem si udělal několik testů rychlosti, a z těch mi vyšlo jako rychlejší (rozdíl nebyl nijak závratný) způsob procházení vektoru indexem a navíc mě přijde lst[i] přehlednější, než iterator, tak pokud si mohu vybrat, jsem pro index. Jaký udělat jiný test, než test rychlosti mě nenapadá.

Nahlásit jako SPAM
IP: 31.47.99.–
Visual Studio C/C#/C++
(pouze samouk)
hlucheucho+10
Posthunter
4. 2. 2015   #4
-
0
-

#3 BDS
Přehlednost zápisu není od věci :) 

hu

Nahlásit jako SPAM
IP: 193.86.81.–
ondrej39+1
Věrný člen
4. 2. 2015   #5
-
0
-

#4 hlucheucho

Pokud chceš vektor traverzovat od druhého prvku, nebude v tvém případě nejlepší použít úplně normální for cyklus?

for (int i = 1; i < vektor.size(); ++i) {
	vektor[i];
}
Nahlásit jako SPAM
IP: 46.39.172.–
Inject all the dependencies!
hlucheucho+10
Posthunter
4. 2. 2015   #6
-
0
-

#5 ondrej39
i v případě iterátoru to bude normální for cyklus 

for (it = vektor.begin()+1; it <= vektor.end(), it++)  {

}

hu

Nahlásit jako SPAM
IP: 193.86.81.–
ondrej39+1
Věrný člen
4. 2. 2015   #7
-
0
-

#6 hlucheucho
Jojo, ono je celkem fuk, jak to uděláš. Jak psal BDS, rozdíly ve výkonu jsou použitím iterátorů, nebo indexu, stejně zcela zanedbatelné, takže si asi zvol to, co ti vyhovuje víc. :)

Nahlásit jako SPAM
IP: 46.39.172.–
Inject all the dependencies!
hlucheucho+10
Posthunter
4. 2. 2015   #8
-
0
-

on je to vektor ukazatelů na struktury. Přístup k položce struktury pomocí iterátoru 

(*it)->polozka;

působí to krkolomně stejně tak zápis cyklu. Zřejmě ty indexy budou vhodnější kvůli čitelnosti kódu.

hu

Nahlásit jako SPAM
IP: 193.86.81.–
KIIV+42
God of flame
4. 2. 2015   #9
-
0
-

#8 hlucheucho
kdyby to nebylo od druhyho prvku, tak nejlip vypada range based loop:

for (Typ * ptr : pole) {
  ptr->...
}

ale od druhyho, to aby clovek mel zase nejaky wrapper objekt, kterymu bys predhodil pole a on vratil spravnej begin a originalni end... jen bacha na prazdny pole.. by se to mohlo trosku zacyklit

hlavne se moc nepouziva iter <= end, protoze to pak neni obecny a spoleha to na to, ze jdou prvky po sobe (respektive to potrebuje random access iterator) - proste se pouziva !=

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
hlucheucho+10
Posthunter
4. 2. 2015   #10
-
0
-

#9 KIIV
!= je problém v případě, že bude ve vektoru jen jeden prvek, to nese riziko, že se hrábne do paměti kam nemá

hu

Nahlásit jako SPAM
IP: 193.86.81.–
KIIV+42
God of flame
4. 2. 2015   #11
-
0
-

#10 hlucheucho
Kdyz bude prazdny tak ano, s jednim prvkem se posune akorat na end().

Ale zato ho maji vsechny typy iteratoru. Muzes to pak vymenit prakticky za cokoliv.

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
ondrej39+1
Věrný člen
4. 2. 2015   #12
-
0
-

#10 hlucheucho
To už podle mě řešíš něco, co nemá vůbec smysl řešit, protože se dá vyřešit úplně jednoduchou podmínkou...

if (vektor.size() == 1)
{
	//udělej toto, protože tam 2. prvek není
}
else
{
	//jinak vektor prostě projeď
}
Nahlásit jako SPAM
IP: 46.39.172.–
Inject all the dependencies!
hlucheucho+10
Posthunter
4. 2. 2015   #13
-
0
-

#12 ondrej39
jak jsi napsal cyklus s indexem, tam ta podmínka odpadá. Cyklus neproběhne pokud tam nejsou aspoň dva prvky. Toto chování potřebuji. Navíc jednoduchost a čitelnost kódu se mi líbí. 

hu

Nahlásit jako SPAM
IP: 193.86.81.–
hlucheucho+10
Posthunter
4. 2. 2015   #14
-
0
-

#11 KIIV

Kdyz bude prazdny tak ano, s jednim prvkem se posune akorat na end().

což znamená na první prvek, který se má vynechat.

hu

Nahlásit jako SPAM
IP: 193.86.81.–
KIIV+42
God of flame
4. 2. 2015   #15
-
0
-

#14 hlucheucho
ted nechapu odkud pocitas, jestli myslis index 0 jako nulty prvek, index 1 jako prvni..  Ja pocitam jako prvni prvek ten s indexem 0.

A begin ukazuje na prvni prvek, po pricteni 1 bude ukazovat na end, pokud je tam jen ten jeden prvek, nebo na druhy prvek, pokud jich je vicero.

Respektive:

0 polozek:   begin == end

1 polozka:   begin == end+1

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
hlucheucho+10
Posthunter
4. 2. 2015   #16
-
0
-

myslel jsem, že end ukazuje na poslední prvek

hu

Nahlásit jako SPAM
IP: 193.86.81.–
KIIV+42
God of flame
4. 2. 2015   #17
-
+1
-
Zajímavé

#16 hlucheucho
ukazuje za posledni prvek, nejsou tam uz platny data - je to velice univerzalni, neco jako \0 na konci retezce

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
KIIV+42
God of flame
4. 2. 2015   #18
-
0
-

coz mi pripomelo, ze ani  <=  neni dobrej napad :D Kdyz uz, tak aspon <

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
hlucheucho+10
Posthunter
4. 2. 2015   #19
-
0
-

 #18 KIIV
ano, máš pravdu

hu

Nahlásit jako SPAM
IP: 193.86.81.–
KIIV+42
God of flame
4. 2. 2015   #20
-
0
-

nakonec by bylo lepsi pouzit treba:

std::for_each(pole.begin()+1,pole.end(), [](typ * ptr){ ptr->metoda(); } );

- cim min mist, kde se da udelat chyba, tim spolehlivejsi kod :)

samo s if (! pole.empty())

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
hlucheucho+10
Posthunter
4. 2. 2015   #21
-
0
-

for_each je až od C++11? Myslím, že ano, takže nelze použít. Embarcadero implementovalo C++11 jen na půl :(, některé věci u 32-bitového překladače nejdou

hu

Nahlásit jako SPAM
IP: 193.86.81.–
KIIV+42
God of flame
4. 2. 2015   #22
-
0
-
Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
hlucheucho+10
Posthunter
4. 2. 2015   #23
-
0
-

Pořád se mi zdají ty indexy jednodušší a srozumitelnější

hu

Nahlásit jako SPAM
IP: 193.86.81.–
KIIV+42
God of flame
4. 2. 2015   #24
-
0
-

#23 hlucheucho
jasny, je to o zvyku. Ty algoritmy jsou zase overeny - ono se totiz i pri prochazeni podle indexu da nadelat spousta chyb uz v kostre cyklu :)

Pak existujou i specialni iteratory pro  std::copy ... napriklad pro cout - pak pomoci copy vypises vsechny prvky pole...

Back inserter iterator se zase navaze na vector a pomoci copy se tim da vkladat na konec..

Z examplu na tom cppreference.com:

#include <algorithm>
#include <iostream>
#include <vector>
#include <iterator>
#include <numeric>
 
int main()
{
    std::vector<int> from_vector(10);
    std::iota(from_vector.begin(), from_vector.end(), 0);
 
    std::vector<int> to_vector;
    std::copy(from_vector.begin(), from_vector.end(),
              std::back_inserter(to_vector));
// or, alternatively,
//  std::vector<int> to_vector(from_vector.size());
//  std::copy(from_vector.begin(), from_vector.end(), to_vector.begin());
// either way is equivalent to
//  std::vector<int> to_vector = from_vector;
 
    std::cout << "to_vector contains: ";
 
    std::copy(to_vector.begin(), to_vector.end(),
              std::ostream_iterator<int>(std::cout, " "));
    std::cout << '\n';
}

tady je z c++11 ta std::iota co to ma za ukol naplnit cislama od 0 do 9 :)

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
hlucheucho+10
Posthunter
4. 2. 2015   #25
-
0
-

S tou lambda funkcí jsme to tady kdysi řešili a C++ Builder s tím měl problémy. Co jsem pak dělal pokusy s verzí XE5, byla pro mne zklamáním. Od té doby mám chuť přejít na MS VS.

S chybama u procházení vektoru pomocí indexů bych to neviděl až tak dramaticky. Mnohem větší riziko vidím u věcí, se kterými jsem neměl nikdy nic do činění.

hu

Nahlásit jako SPAM
IP: 193.86.81.–
ondrej39+1
Věrný člen
4. 2. 2015   #26
-
0
-

#25 hlucheucho
VS je super v dnešní době už i na C++, a pokud by ses někdy přesunul na C#, na to je ještě mnohem lepší. Resharper je dokonalá fíčura :-).

Nahlásit jako SPAM
IP: 46.39.172.–
Inject all the dependencies!
KIIV+42
God of flame
4. 2. 2015   #27
-
0
-

#25 hlucheucho
ja se nastesti venuju vyvoji v gcc/g++, a tam sem mel maximalne problemy s libstdc++ (ci v cem to bylo) a naprosto nefunkcni regex (musel se dal pouzivat boost::regex)

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
hlucheucho+10
Posthunter
4. 2. 2015   #28
-
0
-

dělám i na jednočipech, z tohoto důvodu je mi C/C++ bližší. Změna IDE mne asi bude stát hodně času než se naučím jiný framework (znalost vcl mi asi moc nepomůže) a pak přenositelnost kódu. Hodně věcí napsaných s použitím vcl bude asi nepoužitelných

hu

Nahlásit jako SPAM
IP: 193.86.81.–
vitamin+8
Grafoman
4. 2. 2015   #29
-
0
-

#28 hlucheucho
Ja pouzivam iterovanie pomocou indexov len ak potrebujem modifikovat vector pocas iterovania. Ak by som pouzil iteratory tak by to neskoncilo dobre :). Ak mas c++11 tak samozrejme vstavany foreach, ak mas c++14 tak std::for_each a polymorficke lambdy.

Nahlásit jako SPAM
IP: 95.105.229.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
hlucheucho+10
Posthunter
4. 2. 2015   #30
-
0
-

#29 vitamin
a pokud máš C++ builder XE5 tak máš akorát zlost, že tam není ani jedno z vyjmenovaného. 

hu

Nahlásit jako SPAM
IP: 193.86.81.–
vitamin+8
Grafoman
4. 2. 2015   #31
-
0
-

#30 hlucheucho
V poslednm case programujem D a robi sa v nom ovela lepsie ako v C++.

V tvojom pripade bude asi lpsie pouzit indexi, lebo rucne vypisovat typy iteratorov je strasna otrava (predpokladam ze builder nema auto z c++11)..

Nahlásit jako SPAM
IP: 95.105.229.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
hlucheucho+10
Posthunter
4. 2. 2015   #32
-
0
-

D?

Předpokládáš správně, nemá auto. (trochu mimo téma) a já taky ne, už více než rok.

hu

Nahlásit jako SPAM
IP: 193.86.81.–
vitamin+8
Grafoman
4. 2. 2015   #33
-
0
-
Nahlásit jako SPAM
IP: 95.105.229.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
hlucheucho+10
Posthunter
4. 2. 2015   #34
-
0
-

Vypadá to zajímavě

hu

Nahlásit jako SPAM
IP: 193.86.81.–
KIIV+42
God of flame
4. 2. 2015   #35
-
0
-

#31 vitamin
no aspon ze c++ ma narozdil od treba javy typedef.. clovek si udela alias jakej chce (teda je dobry mit nejaky rozumny nazvy)

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
hlucheucho+10
Posthunter
4. 2. 2015   #36
-
0
-

typedef je třeba používat s rozumem. Mít alias na kdejaký prd a nebo 20 aliasů pro totéž je spíš na nadělání zmatků.

Jsme se vzdálili od tématu :)

hu

Nahlásit jako SPAM
IP: 193.86.81.–
BDS+2
Věrný člen
5. 2. 2015   #37
-
0
-

Měl bych doplňující otázku:
Jakou funkci by jste použili? Nebo je to úplně jedno?

void Fc1()
{
 //1. verze
 for(int i=0; i<100000; i++)
 {
   v1.push_back(hodnota());
   v2.push_back(hodnota());
 }
}
//---------------------------------------------------------------------------
void Fc2()
{
 //2. verze
 for(int i=0; i<100000; i++)v1.push_back(hodnota());
 for(int i=0; i<100000; i++)v2.push_back(hodnota());
}
//---------------------------------------------------------------------------
Nahlásit jako SPAM
IP: 94.113.253.–
Visual Studio C/C#/C++
(pouze samouk)
KIIV+42
God of flame
5. 2. 2015   #38
-
0
-

#37 BDS
prvni, jeden cyklus je lepsi nez dva - obzvlaste, kdyz jsou to ty samy

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
ondrej39+1
Věrný člen
5. 2. 2015   #39
-
0
-

#37 BDS

#include "stdafx.h"
#include <iostream>
#include <time.h>
#include <vector>

using std::cout;
using std::endl;
using std::cin;

int _tmain(int argc, _TCHAR* argv[])
{	
	int hodnota = 10;
	
	std::vector<int> vektor1;
	std::vector<int> vektor2;

	cout << "V jednom for cyklu: " << endl;
	for (size_t i = 0; i < 10; i++)
	{
		const clock_t begin_time = clock();

		for (size_t i = 0; i < 5000000; i++)
		{
			vektor1.push_back(hodnota);
			vektor2.push_back(hodnota);
		}

		cout << float(clock() - begin_time) / CLOCKS_PER_SEC;
		cout << endl;

		vektor1.clear();
		vektor2.clear();
	}

	cout << endl;
	cout << "Ve dvou for cyklech " << endl;
	for (size_t i = 0; i < 10; i++)
	{
		const clock_t begin_time = clock();

		for (size_t i = 0; i < 5000000; i++)
		{
			vektor1.push_back(hodnota);
		}

		for (size_t i = 0; i < 5000000; i++)
		{
			vektor2.push_back(hodnota);
		}

		cout << float(clock() - begin_time) / CLOCKS_PER_SEC;
		cout << endl;

		vektor1.clear();
		vektor2.clear();
	}

	return 0;
}

Připojen obrázek.

Nahlásit jako SPAM
IP: 46.39.172.–
Inject all the dependencies!
hlucheucho+10
Posthunter
5. 2. 2015   #40
-
0
-

Verze 1 s jedním cyklem. V souladu s Application Note od Atmelu, měla v názvu efektivní C kódování, je dobré se vyhnout nadbytečným iteracím cyklu. Ono to na jednočipu je víc poznat, když plýtváš strojovým časem. Stejně tak se to vymstí u větších projektů na výkonnějším stroji.

hu

Nahlásit jako SPAM
IP: 2001:67c:1222:800:4c70:ef...–
vitamin+8
Grafoman
5. 2. 2015   #41
-
0
-

#37 BDS

a pred cyklus daj:

v1.reserve(100000);
v2.reserve(100000);
Nahlásit jako SPAM
IP: 195.28.77.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
BDS+2
Věrný člen
5. 2. 2015   #42
-
0
-

Díky za reakce. Rychlost provádějí jsem na mysli neměl, spíš mi šlo správu paměti.

Nahlásit jako SPAM
IP: 94.113.253.–
Visual Studio C/C#/C++
(pouze samouk)
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, 99 hostů

Podobná vlákna

Iterator — založil JouiBart

Iterátor — založil Martin Heller

C++ iterator — založil l1zard

Moderátoři diskuze

 

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