Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > pl.comp.programming > #28613 > unrolled thread
| Started by | Borneq <borneq@antyspam.hidden.pl> |
|---|---|
| First post | 2016-05-20 15:46 +0200 |
| Last post | 2016-05-20 13:18 -0700 |
| Articles | 6 — 2 participants |
Back to article view | Back to pl.comp.programming
Matching - rozszerzone porównanie dwóch posortowanych list Borneq <borneq@antyspam.hidden.pl> - 2016-05-20 15:46 +0200
Re: Matching - rozszerzone porównanie dwóch posortowanych list Borneq <borneq@antyspam.hidden.pl> - 2016-05-20 17:13 +0200
Re: Matching - rozszerzone porównanie dwóch posortowanych list "M.M." <mmarszik@gmail.com> - 2016-05-20 08:20 -0700
Re: Matching - rozszerzone porównanie dwóch posortowanych list Borneq <borneq@antyspam.hidden.pl> - 2016-05-20 17:55 +0200
Re: Matching - rozszerzone porównanie dwóch posortowanych list Borneq <borneq@antyspam.hidden.pl> - 2016-05-20 19:14 +0200
Re: Matching - rozszerzone porównanie dwóch posortowanych list "M.M." <mmarszik@gmail.com> - 2016-05-20 13:18 -0700
| From | Borneq <borneq@antyspam.hidden.pl> |
|---|---|
| Date | 2016-05-20 15:46 +0200 |
| Subject | Matching - rozszerzone porównanie dwóch posortowanych list |
| Message-ID | <nhn4f9$d67$1@node2.news.atman.pl> |
Mam fazę przygotowania:
vector<int> vecA;
vector<int> vecB;
srand(1000);
for (int i = 0; i < 16; i++) vecA.push_back(rand() % 20);
for (int i = 0; i < 12; i++) vecB.push_back(rand() % 20);
sort(vecA.begin(), vecA.end());
sort(vecB.begin(), vecB.end());
Algorytm:
int i1 = 0, i2 = 0;
while (i1 < vecA.size() && i2 < vecB.size())
{
if (vecA[i1] < vecB[i2])
{
printf("w pierwszym %d\n", vecA[i1]);
i1++;
}
else if (vecA[i1] > vecB[i2])
{
printf("w drugim %d\n", vecB[i2]);
i2++;
}
else
{
printf("w obu %d\n", vecA[i1]);
i1++;
i2++;
}
}
printf("dokończenie A\n");
while (i1 < vecA.size())
{
printf("w pierwszym %d\n", vecA[i1]);
i1++;
}
printf("dokończenie B\n");
while (i2 < vecB.size())
{
printf("w drugim %d\n", vecB[i2]);
i1++;
}
Dobre do porównywania czy w obu katalogach te same pliki na przykład,
ale: gdy mamy: 0 0 1 2 4 4 7 oraz 1 4 5 5 6 8
to wtedy wypisze:
w pierwszym 2
w obu 4
w pierwszym 4
w drugim 5
pierwszą czwórkę kwalifikując do "w obu", drugą do "w pierwszym", a mi
tym razem chodzi o to by wypisywać tylko w obu, wszystkie powtarzające
się elementy, czyli ma wypisać:
w obu 4
w obu 4
Jak należy zmodyfikować algorytm?
[toc] | [next] | [standalone]
| From | Borneq <borneq@antyspam.hidden.pl> |
|---|---|
| Date | 2016-05-20 17:13 +0200 |
| Message-ID | <nhn9j8$i1r$1@node2.news.atman.pl> |
| In reply to | #28613 |
W dniu 20.05.2016 o 15:46, Borneq pisze:
> if (vecA[i1] < vecB[i2])
> {
> printf("w pierwszym %d\n", vecA[i1]);
> i1++;
> }
> else if (vecA[i1] > vecB[i2])
> {
> printf("w drugim %d\n", vecB[i2]);
> i2++;
> }
Dwa pliki:
0 1 5 8 9 11 11 15 17 17 20 25
1 1 1 3 4 4 8 8 8 11 16 17 17 17 25
0 < 1 - czyta pierwszy plik
1 = 1 - wypisuje że w obu
zapamiętuje pozycję w obu, czyta oba
5 > 1 ale 1=poprzednia pozycja w obu, więc wypisuje 1 z drugiej listy
czyta drugi plik
5 > 1 wypisuj 1 z drugiej listy
5 > 3 czyta drugi plik
5 > 4 czyta drugi plik
5 > 4 czyta drugi plik
5 < 8 - czyta pierwszy plik
8 = 8 zapamiętuje klucz 8
czyli trzeba mieć flagę: ostatnio był w obu
[toc] | [prev] | [next] | [standalone]
| From | "M.M." <mmarszik@gmail.com> |
|---|---|
| Date | 2016-05-20 08:20 -0700 |
| Message-ID | <41188837-396f-41ff-983d-fd516cb6bd3e@googlegroups.com> |
| In reply to | #28614 |
On Friday, May 20, 2016 at 5:13:45 PM UTC+2, Borneq wrote:
> W dniu 20.05.2016 o 15:46, Borneq pisze:
> > if (vecA[i1] < vecB[i2])
> > {
> > printf("w pierwszym %d\n", vecA[i1]);
> > i1++;
> > }
> > else if (vecA[i1] > vecB[i2])
> > {
> > printf("w drugim %d\n", vecB[i2]);
> > i2++;
> > }
>
> Dwa pliki:
>
> 0 1 5 8 9 11 11 15 17 17 20 25
>
> 1 1 1 3 4 4 8 8 8 11 16 17 17 17 25
>
> 0 < 1 - czyta pierwszy plik
> 1 = 1 - wypisuje że w obu
> zapamiętuje pozycję w obu, czyta oba
> 5 > 1 ale 1=poprzednia pozycja w obu, więc wypisuje 1 z drugiej listy
> czyta drugi plik
> 5 > 1 wypisuj 1 z drugiej listy
> 5 > 3 czyta drugi plik
> 5 > 4 czyta drugi plik
> 5 > 4 czyta drugi plik
> 5 < 8 - czyta pierwszy plik
> 8 = 8 zapamiętuje klucz 8
>
> czyli trzeba mieć flagę: ostatnio był w obu
Ja bym trzymał ostatni wczytany element. Wczytuję tam gdzie jest
najmniejszy (albo największy, zależy jak były posortowane) element.
Jeśli to działa na pamięci RAM, to wersja z hash-table może
zadziałać szybciej niż z sortowaniem.
Pozdrawiam
[toc] | [prev] | [next] | [standalone]
| From | Borneq <borneq@antyspam.hidden.pl> |
|---|---|
| Date | 2016-05-20 17:55 +0200 |
| Message-ID | <nhnc15$khu$1@node2.news.atman.pl> |
| In reply to | #28615 |
W dniu 20.05.2016 o 17:20, M.M. pisze:
> Jeśli to działa na pamięci RAM, to wersja z hash-table może
> zadziałać szybciej niż z sortowaniem.
Zrobiłem tak:
int i1 = 0, i2 = 0;
int valueBoth = 0;
bool lastBoth = false;
while (i1 < vecA.size() && i2 < vecB.size())
{
if (vecA[i1] < vecB[i2])
{
if (lastBoth)
{
if (vecA[i1] == valueBoth)
printf("match - pierwsza lista %d\n", vecA[i1]);
else
lastBoth = false;
}
i1++;
}
else if (vecA[i1] > vecB[i2])
{
if (lastBoth)
{
if (vecB[i2] == valueBoth)
printf("match - druga lista %d\n", vecB[i2]);
else
lastBoth = false;
}
i2++;
}
else
{
printf("match - dwie listy %d\n", vecA[i1]);
valueBoth = vecA[i1];
lastBoth = true;
i1++;
i2++;
}
}
printf("dokończenie A\n");
while (i1 < vecA.size())
{
if (lastBoth)
{
if (vecA[i1] == valueBoth)
printf("match - pierwsza lista %d\n", vecA[i1]);
else
lastBoth = false;
}
i1++;
}
printf("dokończenie B\n");
while (i2 < vecB.size())
{
if (lastBoth)
{
if (vecB[i2] == valueBoth)
printf("match - druga lista %d\n", vecB[i2]);
else
lastBoth = false;
}
i2++;
}
Mam dwie pomocnicze zmienne, nie wystarczy valueBoth, które na początku
trzeba by inicjować na +maxint (nawet to nie pewne, bo co gdy w tablicy
się pojawi maxint?) ale porównanie z bool lastBoth jest znacznie szybsze
niż valueBoth, które będzie kluczem i trzeba będzie użyć strcmp()
A to przykładowe dane:
vecA.push_back(0);
vecA.push_back(1);
vecA.push_back(5);
vecA.push_back(8);
vecA.push_back(9);
vecA.push_back(11);
vecA.push_back(11);
vecA.push_back(15);
vecA.push_back(17);
vecA.push_back(17);
vecA.push_back(20);
vecA.push_back(25);
vecA.push_back(25);
vecB.push_back(1);
vecB.push_back(1);
vecB.push_back(1);
vecB.push_back(3);
vecB.push_back(4);
vecB.push_back(4);
vecB.push_back(8);
vecB.push_back(8);
vecB.push_back(8);
vecB.push_back(11);
vecB.push_back(16);
vecB.push_back(17);
vecB.push_back(17);
vecB.push_back(17);
vecB.push_back(25);
[toc] | [prev] | [next] | [standalone]
| From | Borneq <borneq@antyspam.hidden.pl> |
|---|---|
| Date | 2016-05-20 19:14 +0200 |
| Message-ID | <nhngm6$p2c$1@node2.news.atman.pl> |
| In reply to | #28616 |
W dniu 20.05.2016 o 17:55, Borneq pisze:
> Zrobiłem tak:
> while (i1 < vecA.size() && i2 < vecB.size())
Ale potrzebne wersja strumieniowa, która jednak się różni, bo każdy
odczyt ze strumienia oznacza zwiększenie indeksu.
Potrzebne flagi , czy bufor aktualny czy pusty.
int i1 = 0, i2 = 0;
int valueBoth = 0;
bool lastBoth = false;
int recA; int recB;
bool recAEmpty = true;//get ustawia na false, odczyt z bufora na true
bool recBEmpty = true;
while ((i1 < vecA.size() || !recAEmpty) && (i2 < vecB.size() ||
!recBEmpty) )
{
if (recAEmpty)
{
recA = vecA[i1]; i1++;
recAEmpty = false;
}
if (recBEmpty)
{
recB = vecB[i2]; i2++;
recBEmpty = false;
}
if (recA < recB)
{
if (lastBoth)
{
if (recA == valueBoth)
printf("match - pierwsza lista %d\n", recA);
else
lastBoth = false;
}
recAEmpty = true;
}
else if (recA > recB)
{
if (lastBoth)
{
if (recB == valueBoth)
printf("match - druga lista %d\n", recB);
else
lastBoth = false;
}
recBEmpty = true;
}
else
{
printf("match - dwie listy %d\n", recA);
valueBoth = recA;
lastBoth = true;
recAEmpty = true;
recBEmpty = true;
}
}
printf("dokończenie A\n");
while (i1 < vecA.size())
{
recA = vecA[i1]; i1++;
if (lastBoth)
{
if (recA == valueBoth)
printf("match - pierwsza lista %d\n", recA);
else
lastBoth = false;
}
i1++;
}
printf("dokonczenie B\n");
while (i2 < vecB.size())
{
recB = vecA[i2]; i2++;
if (lastBoth)
{
if (recB == valueBoth)
printf("match - druga lista %d\n", recB);
else
lastBoth = false;
}
i2++;
}
[toc] | [prev] | [next] | [standalone]
| From | "M.M." <mmarszik@gmail.com> |
|---|---|
| Date | 2016-05-20 13:18 -0700 |
| Message-ID | <f27bfdb4-0561-45b4-a230-b9e143ae0fa2@googlegroups.com> |
| In reply to | #28617 |
On Friday, May 20, 2016 at 7:14:47 PM UTC+2, Borneq wrote:
> W dniu 20.05.2016 o 17:55, Borneq pisze:
> > Zrobiłem tak:
> > while (i1 < vecA.size() && i2 < vecB.size())
A tak jak poniżej, dla dowolnej ilości wektorów?
isEnd( vec[] ) {
int i=0;
while( i<vec.size() && vec[i].isEnd() )
i++;
return i==vec.size();
}
getMin( vec[] ) {
min = -1 ;
for( i=0 ; i<vec.size() ; i++ ) {
if( vec[i].isEnd() )
continue;
if( min == -1 )
min = i;
else if( vec[min].next() > vec[i].next() )
min = i;
}
return vec[min].getNext();
}
for( i=0 ; i<vec.size() ; i++ )
sort( vec[i] );
val1 = getMin( vec );
while( ! isEnd( vec ) ) {
val2 = getMin( vec );
if( val1 == val2 )
print val1;
val1 = val2;
}
Pozdrawiam
[toc] | [prev] | [standalone]
Back to top | Article view | pl.comp.programming
csiph-web