przeglądanie kontenera od końca + referencja

0

Mam taki problem, mam taki kawałek kodu i chcę przglądać listę od końca, ale przy powrocie z referencji wywala mi błąd. Nie wiem czy nie można dekrementować iteratora do listy czy coś innego. Próbowałem też z vectorem, ale to samo. Lista przeglądana od przodu działa bez zarzutu.

void dfs1(int v)
{
	odwiedzone[v]=1;
        for (list<int>::iterator z=nas[v].end(); z!=nas[v].begin(); z--)
	{
                z--;
		if (odwiedzone[*z]==0)
		{
			dfs1(*z);
		}
	}
	post_order[po]=v;
	po++;
}
0
  1. masz dwa razy z-- raz w parametrze for i raz wewnątrz pętli, więc coś napsułeś (będziesz chodził po co drugim elemencie!)
  2. Do takich wypadków stosuje się iteratory odwrotne, bo zmiana iteratora końcowego end zawsze daje end nawet dla operatora -- (choć nie jestem tego pewien). Wynika to z tego że end wskazuje już "poza" kontener:
void dfs1(int v)
{
        odwiedzone[v]=1;
        for (list<int>::reverse_iterator z=nas[v].rbegin(); z!=nas[v].rend(); ++z )
        {
                // po co to: z--;
                if (odwiedzone[*z]==0)
                {
                        dfs1(*z);
                }
        }
        post_order[po++]=v;
}

Sam algorytm i tak wygląda podejrzanie, ale nie wiem co to ma robić.

0

To co ty podałeś działa, wielkie dzięki. [browar]

Masz rację, nie zauważyłem, że chodziłbym co drugi element :-D , a zmniejszałem to z, ponieważ z=nas[v].end() zwraca element za kontenerem, więc musiałem go zmniejszyć, żeby na coś wskazywał, a reszta to skutek uboczny.

Więc wystarczyło zrobić tak:

void dfs1(int v)
{
	odwiedzone[v]=1;
	for (list<int>::iterator z=nas[v].end(); z!=nas[v].begin();)
	{
		z--;
		if (odwiedzone[*z]==0)
		{
			dfs1(*z);
		}
	}
	post_order[po]=v;
	po++;
}

A ta funkcja to część algorytmu znajdowania silnych spójnych składniowych :-)

0

A jeszcze jedna rada: używaj typedef! To ci zaoszczędzisz dużo pisania szczególnie w przypadku kontenerów STL-a.

typedef list<int> MyList;

Załóżmy, że w dużym programie chcesz zmienić tego int-a na long int-a, to bez typedef-a dostaniesz bublu głowy, zawłaszcza, że może się zdażyć, że nie wszystkie list<int> mają być poprawione. Poza tym czy to nie lepiej wygląda:

for (MyList::iterator z=nas[v].end(); z!=nas[v].begin();)
...

1 użytkowników online, w tym zalogowanych: 0, gości: 1