TProcura
Biblioteca em C++ para testes paramétricos de algoritmos, e coleção de algoritmos de procura e otimização
Loading...
Searching...
No Matches
TVector.h
Go to the documentation of this file.
1#pragma once
2
15#include <stdlib.h>
16#include "TRand.h"
17
19 // TVector
21
22template <class Item>
24{
25private:
26 TVector<int>* idx = nullptr;
27 Item* v = nullptr;
28 int sz = 0;
29 int count = 0;
32 void Size(int size);
33
35 void QuickSort(int start, int end);
36
38 void Insertion(int start, int end);
39
41 void Exch(int i, int j) { Item a = v[i]; v[i] = v[j]; v[j] = a; }
42
44 void QuickSortIdx(int start, int end);
45
47 void ExchIdx(int i, int j) { int a = (*idx)[i]; (*idx)[i] = (*idx)[j]; (*idx)[j] = a; }
48
50 static inline int Min(int a, int b) noexcept { return (a < b) ? a : b; }
51
53 static inline int Max(int a, int b) noexcept { return (a > b) ? a : b; }
54
55public:
56 static Item erro;
60
61 TVector(int size = 0);
62
64 TVector(int size, Item const* init);
65
67 virtual ~TVector() noexcept;
68
71
76 TVector(const TVector& o);
77
83 TVector& operator=(const TVector& o);
84
90 TVector(TVector&& o) noexcept;
91
97 TVector& operator=(TVector&& o) noexcept;
99
108 TVector& operator+=(const TVector& o);
109
111
114
115 inline TVector<Item>& Add(Item a) { operator[](count) = a; return *this; }
116
118 TVector<Item>& Insert(Item a, int index = 0);
119
121 TVector<Item>& Insert(TVector<Item>& v, int index = 0);
122
124 inline TVector<Item>& Push(Item a) { return Add(a); }
125
127 inline Item& Pop() { return (count > 0 ? v[--count] : TVector<Item>::erro); }
128
140 Item& operator[](int i);
141
150 const Item& operator[](int i) const;
151
152
154 inline Item& First() { return (count > 0 ? v[0] : TVector<Item>::erro); }
155
157 inline Item& Last() { return (count > 0 ? v[count - 1] : TVector<Item>::erro); }
158
160 int Count() const { return count; }
161
172 {
173 if (value > sz)
174 Size(value);
175 count = value;
176 return *this;
177 }
178
180 Item& Random() { return (count > 0 ? operator[](TRand::rand() % count) : TVector<Item>::erro); }
182
185
187
190
193
196
198 bool Equal(const TVector<Item>& v) const;
199
201 bool Contained(const TVector<Item>& v) const;
203
206
208
210 TVector<Item>& Remove(Item const& i);
211
213 int Find(Item& i, bool binary = false, int left = 0, int right = -1);
214
216 TVector<Item>& Replace(Item const& iold, Item const& inew);
217
219 TVector<Item>& Sort(TVector<int>* idxvect = nullptr);
220
222 void Sort(int start, int end = -1);
223
226
229
231 TVector<Item>& Reset(Item const& i);
232
241 int Distance(TVector<Item>& v, int type = 0);
243
246 Item* begin() noexcept { return v; }
247 Item* end() noexcept { return v + count; }
248 const Item* begin() const noexcept { return v; }
249 const Item* end() const noexcept { return v + count; }
251
254
255 TVector<Item>& operator+=(const Item& x);
256
258 TVector<Item>& operator-=(const Item& x);
259
262 {
263 a += b; return a;
264 }
265
267 friend bool operator==(const TVector<Item>& a, const TVector<Item>& b)
268 {
269 return a.Equal(b);
270 }
271
273 friend bool operator!=(const TVector<Item>& a, const TVector<Item>& b)
274 {
275 return !a.Equal(b);
276 }
278};
279
280//----------------------------------------------------------------------------
281// instanciação da variável com o conteúdo de erro
282//----------------------------------------------------------------------------
283
288template <class Item>
290
291
292
293
294//----------------------------------------------------------------------------
295// Redimensionamento interno
296//----------------------------------------------------------------------------
297
307template <class Item>
308void TVector<Item>::Size(int size)
309{
310 Item* aux = new Item[size];
311 if (v != nullptr) {
312 for (int k = 0; k < count; ++k)
313 aux[k] = v[k];
314 delete[] v;
315 }
316 v = aux;
317 sz = size;
318}
319
320
321//----------------------------------------------------------------------------
322// Construtor com inicialização
323//----------------------------------------------------------------------------
324
325
331template <class Item>
333 : idx(nullptr), v(nullptr), sz(0), count(0)
334{
335 if (size > 0)
336 Size(size);
337}
338
339
349template <class Item>
350TVector<Item>::TVector(int size, Item const* init)
351{
352 v = nullptr;
353 sz = 0;
354 count = 0;
355 if (size > 0) {
356 Size(size);
357 for (int k = 0; k < size; ++k)
358 operator[](k) = init[k];
359 }
360}
361
367template <class Item>
369{
370 delete[] v;
371}
372
373
374template <class Item>
380{
381 *this = o;
382}
383
384template <class Item>
391{
392 if (this != &o) {
393 // garante capacidade e atualiza count
394 Count(o.count);
395 // copia elementos
396 for (int i = 0; i < o.count; ++i) {
397 v[i] = o.v[i];
398 }
399 }
400 return *this;
401}
402
403template <class Item>
410 : v(o.v), sz(o.sz), count(o.count)
411{
412 o.v = nullptr;
413 o.sz = 0;
414 o.count = 0;
415}
416
417template <class Item>
424{
425 if (this != &o) {
426 delete[] v;
427 v = o.v;
428 sz = o.sz;
429 count = o.count;
430 o.v = nullptr;
431 o.sz = 0;
432 o.count = 0;
433 }
434 return *this;
435}
436
437template <class Item>
447{
448 int oldCount = count;
449 // ajusta tamanho lógico e realoca se necessário
450 Count(oldCount + o.count);
451 // copia elementos
452 for (int k = 0; k < o.count; ++k) {
453 v[oldCount + k] = o.v[k];
454 }
455 return *this;
456}
457
458
459
460//----------------------------------------------------------------------------
461// Implementação de operator[] para auto-expansão
462//----------------------------------------------------------------------------
463
467template <class Item>
469{
470 if (i >= sz)
471 Size(2 * (i + 1));
472
473 if (i >= count)
474 count = i + 1;
475
476 return v[i];
477}
478
479
483template <class Item>
484const Item& TVector<Item>::operator[](int i) const
485{
486 if (i < 0 || i >= count)
487 return TVector<Item>::erro;
488
489 return v[i];
490}
491
492//----------------------------------------------------------------------------
493// Pesquisa de elementos
494//----------------------------------------------------------------------------
495
504template <class Item>
505int TVector<Item>::Find(Item& i, bool binary, int left, int right)
506{
507 if (binary) {
508 if (right < 0 || right > count - 1) right = count - 1;
509 if (left < 0 || left > right) left = 0;
510 while (left <= right) {
511 int mid = (left + right) >> 1;
512 if (v[mid] == i) return mid;
513 if (v[mid] < i) left = mid + 1;
514 else right = mid - 1;
515 }
516 }
517 else {
518 for (int k = 0; k < count; ++k)
519 if (v[k] == i)
520 return k;
521 }
522 return -1;
523}
524
525
526
527
528
529//----------------------------------------------------------------------------
530// Ordenação
531//----------------------------------------------------------------------------
532
538template <class Item>
540{
541 if (idxvect == nullptr) {
542 QuickSort(0, count - 1);
543 Insertion(0, count - 1);
544 }
545 else {
546 idx = idxvect;
547 idx->Count(count);
548 for (int k = 0; k < count; ++k)
549 (*idx)[k] = k;
550 QuickSortIdx(0, count - 1);
551 }
552 return *this;
553}
554
555
561template <class Item>
562void TVector<Item>::Sort(int start, int end)
563{
564 if (end > count - 1 || end < 0) end = count - 1;
565 if (start < 0) start = 0;
566 if (start < end) {
567 QuickSort(start, end);
568 Insertion(start, end);
569 }
570}
571
572
579template <class Item>
580void TVector<Item>::QuickSort(int start, int end)
581{
582 if (end - start > 32) {
583 // pivôs median-of-three
584 Exch((start + end) >> 1, end - 1);
585 if (v[end - 1] < v[start]) Exch(end - 1, start);
586 if (v[end] < v[start]) Exch(end, start);
587 if (v[end] < v[end - 1]) Exch(end, end - 1);
588
589 start++; end--;
590
591 // partição
592 int i = start - 1, j = end;
593 Item pivot = v[end];
594 for (;;) {
595 while (v[++i] < pivot);
596 while (pivot < v[--j] && j > start);
597 if (i >= j) break;
598 Exch(i, j);
599 }
600 Exch(i, end);
601
602 QuickSort(start - 1, i - 1);
603 QuickSort(i + 1, end + 1);
604 }
605}
606
607
613template <class Item>
614void TVector<Item>::Insertion(int start, int end)
615{
616 for (int i = end; i > start; --i)
617 if (v[i - 1] > v[i])
618 Exch(i - 1, i);
619
620 for (int i = start + 2; i <= end; ++i) {
621 Item tmp = v[i];
622 int j = i;
623 while (tmp < v[j - 1]) {
624 v[j] = v[j - 1];
625 --j;
626 }
627 v[j] = tmp;
628 }
629}
630
631
632
638template <class Item>
639void TVector<Item>::QuickSortIdx(int start, int end)
640{
641 if (end - start < 3) {
642 // pequenos casos
643 if (end - start == 1) {
644 if (v[(*idx)[end]] < v[(*idx)[start]])
645 ExchIdx(end, start);
646 }
647 else if (end - start == 2) {
648 if (v[(*idx)[end - 1]] < v[(*idx)[start]])
649 ExchIdx(end - 1, start);
650 if (v[(*idx)[end]] < v[(*idx)[start]])
651 ExchIdx(end, start);
652 if (v[(*idx)[end]] < v[(*idx)[end - 1]])
653 ExchIdx(end, end - 1);
654 }
655 }
656 else {
657 // pivôs median-of-three em idx
658 ExchIdx((start + end) >> 1, end - 1);
659 if (v[(*idx)[end - 1]] < v[(*idx)[start]])
660 ExchIdx(end - 1, start);
661 if (v[(*idx)[end]] < v[(*idx)[start]])
662 ExchIdx(end, start);
663 if (v[(*idx)[end]] < v[(*idx)[end - 1]])
664 ExchIdx(end, end - 1);
665
666 start++; end--;
667
668 // partição em idx
669 int i = start - 1, j = end;
670 Item pivot = v[(*idx)[end]];
671 for (;;) {
672 while (v[(*idx)[++i]] < pivot);
673 while (pivot < v[(*idx)[--j]] && j > start);
674 if (i >= j) break;
675 ExchIdx(i, j);
676 }
677 ExchIdx(i, end);
678
679 if (i > start) QuickSortIdx(start - 1, i - 1);
680 if (i < end) QuickSortIdx(i + 1, end + 1);
681 }
682}
683
684
685//----------------------------------------------------------------------------
686// Baralhar
687//----------------------------------------------------------------------------
688
693template <class Item>
695{
696 for (int k = count - 1; k > 0; --k)
697 Exch(k, TRand::rand() % (k + 1));
698 return *this;
699}
700
706template <class Item>
708{
709 int k = 0;
710 for (int w = 0; w < count; ++w) {
711 if (v[w] != i) {
712 v[k++] = v[w];
713 }
714 }
715 count = k;
716 return *this;
717}
718
719
725template <class Item>
727{
728 for (int j = 0; j < count; ++j) {
729 v[j] = i;
730 }
731 return *this;
732}
733
734
741template <class Item>
742TVector<Item>& TVector<Item>::Replace(const Item& iold, const Item& inew)
743{
744 for (int k = 0; k < count; ++k) {
745 if (v[k] == iold) {
746 v[k] = inew;
747 }
748 }
749 return *this;
750}
751
752
758template <class Item>
760{
761 for (int k = i; k < count - 1; ++k) {
762 v[k] = v[k + 1];
763 }
764 --count;
765 return *this;
766}
767
768
777template <class Item>
779{
780 if (count > 0) {
781 Sort();
782 int k = 0, w = 1;
783 while (w < count) {
784 if (v[k] != v[w]) {
785 v[++k] = v[w];
786 }
787 ++w;
788 }
789 count = k + 1;
790 }
791 return *this;
792}
793
794
800template <class Item>
802{
803 int k = 0, w = 0, s = Count();
804 while (k < other.Count()) {
805 while (w < s && operator[](w) < other[k]) {
806 ++w;
807 }
808 if (w >= s || operator[](w) > other[k]) {
809 Add(other[k++]);
810 }
811 else {
812 ++k;
813 }
814 }
815 Sort();
816 return *this;
817}
818
819
825template <class Item>
827{
828 int k = 0, w = 0, z = 0;
829 while (k < other.Count() && w < Count()) {
830 if (operator[](w) < other[k]) {
831 ++w;
832 }
833 else if (operator[](w) == other[k]) {
834 v[z++] = v[w++];
835 ++k;
836 }
837 else {
838 ++k;
839 }
840 }
841 Count(z);
842 return *this;
843}
844
845
851template <class Item>
853{
854 int k = 0, w = 0, z = 0;
855 while (k < other.Count() && w < Count()) {
856 if (v[w] < other[k]) {
857 v[z++] = v[w++];
858 }
859 else if (v[w] == other[k]) {
860 ++w; ++k;
861 }
862 else {
863 ++k;
864 }
865 }
866 while (w < Count()) {
867 v[z++] = v[w++];
868 }
869 Count(z);
870 return *this;
871}
872
878template <class Item>
879bool TVector<Item>::Equal(const TVector<Item>& other) const
880{
881 if (count != other.Count()) return false;
882 for (int k = 0; k < count; ++k) {
883 if (v[k] != other[k]) return false;
884 }
885 return true;
886}
887
888
894template <class Item>
896{
897 if (count > other.Count()) return false;
898 int k2 = 0;
899 for (int k = 0; k < count; ++k) {
900 while (k2 < other.Count() && v[k2] < v[k]) {
901 ++k2;
902 }
903 if (k2 >= other.Count() || other[k2] != v[k]) {
904 return false;
905 }
906 }
907 return true;
908}
909
910
917template <class Item>
919{
920 if (index < 0) index = Count();
921 int w = src.Count();
922 if (w > 0) {
923 int oldCount = Count();
924 Count(oldCount + w);
925 if (index > oldCount) index = oldCount;
926 for (int k = oldCount - 1; k >= index; --k) {
927 v[k + w] = v[k];
928 }
929 for (int k = 0; k < w; ++k) {
930 v[index + k] = src[k];
931 }
932 }
933 return *this;
934}
935
936
943template <class Item>
945{
946 if (index < 0) index = Count();
947 int oldCount = Count();
948 Count(oldCount + 1);
949 if (index > oldCount) index = oldCount;
950 for (int k = oldCount - 1; k >= index; --k) {
951 v[k + 1] = v[k];
952 }
953 v[index] = a;
954 return *this;
955}
956
961template <class Item>
963{
964 for (int k = 0; k < count / 2; ++k) {
965 Exch(k, count - 1 - k);
966 }
967 return *this;
968}
969
970
981template <class Item>
983{
984 int result = 0;
985 int n1 = Count(), n2 = other.Count();
986
987 if (type == 0) {
988 result = abs(n1 - n2);
989 int m = Min(n1, n2);
990 for (int i = 0; i < m; ++i) {
991 if (v[i] != other[i]) ++result;
992 }
993 }
994 else if (type == 1) {
995 int m = Min(n1, n2);
996 for (int i = 0; i < m; ++i) {
997 result += abs(v[i] - other[i]);
998 }
999 }
1000 else if (type == 2) {
1001 result = Max(n1, n2);
1002 for (int i = 0; i + 1 < n1; ++i) {
1003 int j = other.Find(v[i]);
1004 if (j >= 0 && j + 1 < n2 && v[i + 1] == other[j + 1]) {
1005 --result;
1006 }
1007 }
1008 }
1009 else if (type == 3) {
1010 int rows = n1 + 1, cols = n2 + 1;
1011 TVector<int> mtx(rows * cols);
1012 // inicialização da matriz
1013 for (int i = 0; i < rows; ++i) mtx[i] = i;
1014 for (int j = 1; j < cols; ++j) mtx[j * rows] = j;
1015 // cálculo da distância de edição
1016 for (int i = 1; i < rows; ++i) {
1017 for (int j = 1; j < cols; ++j) {
1018 int cost = (v[i - 1] == other[j - 1] ? 0 : 1);
1019 int val = mtx[(i - 1) + rows * (j - 1)] + cost;
1020 val = Min(val, mtx[(i - 1) + rows * j] + 1);
1021 val = Min(val, mtx[i + rows * (j - 1)] + 1);
1022 mtx[i + rows * j] = val;
1023 }
1024 }
1025 result = mtx[n1 + rows * n2];
1026 }
1027
1028 return result;
1029}
1030
Interface para geração de números aleatórios independentes do sistema operativo.
friend bool operator!=(const TVector< Item > &a, const TVector< Item > &b)
Definition TVector.h:273
Item * end() noexcept
Definition TVector.h:247
Item & First()
Definition TVector.h:154
TVector< Item > & Count(int value)
Ajusta o tamanho lógico do vetor para value.
Definition TVector.h:171
TVector< Item > & BeASet()
Converte o vetor num conjunto: remove duplicados e ordena.
Definition TVector.h:778
virtual ~TVector() noexcept
Destrutor.
Definition TVector.h:368
static Item erro
Valor retornado em casos de acesso inválido.
Definition TVector.h:56
bool Equal(const TVector< Item > &v) const
Verifica se dois vetores-conjunto são iguais.
Definition TVector.h:879
friend TVector< Item > operator+(TVector< Item > a, const TVector< Item > &b)
Definition TVector.h:261
Item & Pop()
Definition TVector.h:127
TVector< Item > & Replace(Item const &iold, Item const &inew)
Substitui todas as ocorrências de um valor antigo por um novo.
Definition TVector.h:742
Item & operator[](int i)
Acesso por índice com auto-expansão.
Definition TVector.h:468
TVector & operator=(const TVector &o)
Operador de atribuição por cópia.
Definition TVector.h:390
const Item * begin() const noexcept
Definition TVector.h:248
TVector< Item > & Insert(TVector< Item > &v, int index=0)
Insere um vetor de itens na posição indicada.
Definition TVector.h:918
TVector< Item > & RandomOrder()
Coloca os elementos em ordem aleatória (Fisher–Yates shuffle).
Definition TVector.h:694
TVector< Item > & Difference(const TVector< Item > &v)
Diferença deste conjunto em relação a outro.
Definition TVector.h:852
TVector< Item > & Sort(TVector< int > *idxvect=nullptr)
Ordena todo o vetor, opcionalmente devolvendo índices ordenados.
Definition TVector.h:539
TVector< Item > & operator+=(const Item &x)
Item & Random()
Definition TVector.h:180
TVector & operator+=(const TVector &o)
Concatena outro vetor a este.
Definition TVector.h:446
TVector< Item > & operator-=(const Item &x)
friend bool operator==(const TVector< Item > &a, const TVector< Item > &b)
Definition TVector.h:267
TVector< Item > & Remove(Item const &i)
Remove todas as ocorrências de um dado elemento.
Definition TVector.h:707
int Distance(TVector< Item > &v, int type=0)
Calcula várias métricas de “distância” entre vetores.
Definition TVector.h:982
TVector< Item > & Intersection(const TVector< Item > &v)
Interseção deste conjunto com outro.
Definition TVector.h:826
const Item & operator[](int i) const
Acesso constante por índice sem modificação de tamanho.
Definition TVector.h:484
bool Contained(const TVector< Item > &v) const
Verifica se este conjunto está contido no outro.
Definition TVector.h:895
TVector< Item > & Add(Item a)
Definition TVector.h:115
Item & Last()
Definition TVector.h:157
TVector< Item > & Reset(Item const &i)
Preenche todo o vetor com um mesmo valor.
Definition TVector.h:726
TVector< Item > & Invert()
Inverte a ordem dos elementos no vetor.
Definition TVector.h:962
TVector< Item > & Insert(Item a, int index=0)
Insere um único elemento na posição indicada.
Definition TVector.h:944
void Sort(int start, int end=-1)
Ordena um subintervalo [start,end] do vetor.
Definition TVector.h:562
TVector< Item > & Delete(int i)
Remove o elemento na posição i deslocando os seguintes.
Definition TVector.h:759
Item * begin() noexcept
Definition TVector.h:246
int Count() const
Definition TVector.h:160
int Find(Item &i, bool binary=false, int left=0, int right=-1)
Procura um elemento no vetor.
Definition TVector.h:505
TVector(int size, Item const *init)
Constrói um vetor pré-carregado a partir de um array.
Definition TVector.h:350
TVector< Item > & Union(const TVector< Item > &v)
Realiza a união deste conjunto com outro.
Definition TVector.h:801
TVector(int size=0)
Construtor.
Definition TVector.h:332
const Item * end() const noexcept
Definition TVector.h:249
TVector< Item > & Push(Item a)
Definition TVector.h:124
unsigned int rand(int seq)
Retorna o próximo valor pseudo-aleatório.
Definition TRand.cpp:46