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 <string.h>
17#include <stdio.h>
18#include <initializer_list>
19#include <cstdarg>
20#include <cstdint>
21#include <locale>
22#include "TRand.h"
23
25 // TVector
27
28template <class Item>
30{
31private:
32 TVector<int>* idx = nullptr;
33 Item* v = nullptr;
34 int sz = 0;
35 int count = 0;
38 void Size(int size);
39
41 void QuickSort(int start, int end);
42
44 void Insertion(int start, int end);
45
47 void Exch(int i, int j) { Item a = v[i]; v[i] = v[j]; v[j] = a; }
48
50 void QuickSortIdx(int start, int end);
51
53 void ExchIdx(int i, int j) { int a = (*idx)[i]; (*idx)[i] = (*idx)[j]; (*idx)[j] = a; }
54
56 static inline int Min(int a, int b) noexcept { return (a < b) ? a : b; }
57
59 static inline int Max(int a, int b) noexcept { return (a > b) ? a : b; }
60
61public:
62 static Item erro;
66
67 TVector(int size = 0);
68
70 TVector(int size, Item const* init);
71
73 virtual ~TVector() noexcept;
74
77
82 TVector(const TVector& o);
83
89 TVector& operator=(const TVector& o);
90
96 TVector(TVector&& o) noexcept;
97
102 TVector(std::initializer_list<Item> init) {
103 Count(static_cast<int>(init.size())); // ajusta capacidade
104 int i = 0;
105 for (const auto& val : init)
106 v[i++] = val;
107 }
108
109
129 TVector(const char* str) {}
130
136 TVector& operator=(TVector&& o) noexcept;
138
139
149
155 TVector& operator+=(std::initializer_list<Item> init) {
156 int oldCount = Count();
157 Count(oldCount + static_cast<int>(init.size()));
158 int i = 0;
159 for (const auto& val : init)
160 v[oldCount + i++] = val;
161 return *this;
162 }
163
174 TVector<Item>& operator+=(const char* str) = delete; // desabilitado para tipos genéricos; implementado para TVector<int>
175
177
180
181 inline TVector<Item>& Add(Item a) { operator[](count) = a; return *this; }
182
184 TVector<Item>& Insert(TVector<Item>& v, int index = 0);
185
187 TVector<Item>& Insert(Item a, int index = 0);
188
190 inline TVector<Item>& Push(Item a) { return Add(a); }
191
193 inline Item& Pop() { return (count > 0 ? v[--count] : TVector<Item>::erro); }
194
206 Item& operator[](int i);
207
216 const Item& operator[](int i) const;
217
219 Item* Data() { return v; }
221 const Item* Data() const { return v; }
222
224 inline Item& First() { return (count > 0 ? v[0] : TVector<Item>::erro); }
225
227 inline Item& Last() { return (count > 0 ? v[count - 1] : TVector<Item>::erro); }
228
230 int Count() const { return count; }
231
233 virtual bool Empty() const { return (count == 0); }
234
245 {
246 if (value > sz)
247 Size(value);
248 count = value;
249 return *this;
250 }
251
253 Item& Random() { return (count > 0 ? operator[](TRand::rand() % count) : TVector<Item>::erro); }
255
258
260
263
266
269
271 bool Equal(const TVector<Item>& v) const;
272
274 bool Contained(const TVector<Item>& v) const;
276
279
281
283 TVector<Item>& Remove(Item const& i);
284
286 int Find(Item& i, bool binary = false, int left = 0, int right = -1);
287
289 TVector<Item>& Replace(Item const& iold, Item const& inew);
290
292 TVector<Item>& Sort(TVector<int>* idxvect = nullptr);
293
295 void Sort(int start, int end = -1);
296
299
302
304 TVector<Item>& Reset(Item const& i);
305
314 int Distance(TVector<Item>& v, int type = 0);
316
319 Item* begin() noexcept { return v; }
320 Item* end() noexcept { return v + count; }
321 const Item* begin() const noexcept { return v; }
322 const Item* end() const noexcept { return v + count; }
324
327
328 TVector<Item>& operator+=(const Item& x) { return Add(x); }
329
331 TVector<Item>& operator-=(const Item& x) { return Remove(x); }
332
334 friend TVector<Item> operator+(TVector<Item> a, const TVector<Item>& b) { a += b; return a; }
335
337 friend bool operator==(const TVector<Item>& a, const TVector<Item>& b) { return a.Equal(b); }
338
340 friend bool operator!=(const TVector<Item>& a, const TVector<Item>& b) { return !a.Equal(b); }
342};
343
344//----------------------------------------------------------------------------
345// instanciação da variável com o conteúdo de erro
346//----------------------------------------------------------------------------
347
352template <class Item>
354
355
356
357
358//----------------------------------------------------------------------------
359// Redimensionamento interno
360//----------------------------------------------------------------------------
361
371template <class Item>
372void TVector<Item>::Size(int size)
373{
374 if (size <= 0) {
375 delete[] v;
376 v = nullptr;
377 sz = 0;
378 return;
379 }
380 Item* aux = new Item[size];
381 if (v != nullptr) {
382 int limite = (count < size ? count : size);
383 for (int k = limite - 1; k >= 0; --k)
384 aux[k] = v[k];
385 delete[] v;
386 }
387 v = aux;
388 sz = size;
389}
390
391
392//----------------------------------------------------------------------------
393// Construtor com inicialização
394//----------------------------------------------------------------------------
395
396
402template <class Item>
404 : idx(nullptr), v(nullptr), sz(0), count(0)
405{
406 if (size > 0)
407 Size(size);
408}
409
410
420template <class Item>
421TVector<Item>::TVector(int size, Item const* init)
422{
423 v = nullptr;
424 sz = 0;
425 count = 0;
426 if (size > 0) {
427 Size(size);
428 for (int k = 0; k < size; ++k)
429 operator[](k) = init[k];
430 }
431}
432
438template <class Item>
440{
441 delete[] v;
442}
443
444
445template <class Item>
451{
452 *this = o;
453}
454
455template <class Item>
462{
463 if (this != &o) {
464 // garante capacidade e atualiza count
465 Count(o.count);
466 // copia elementos
467 for (int i = 0; i < o.count; ++i) {
468 v[i] = o.v[i];
469 }
470 }
471 return *this;
472}
473
474template <class Item>
481 : v(o.v), sz(o.sz), count(o.count)
482{
483 o.v = nullptr;
484 o.sz = 0;
485 o.count = 0;
486}
487
488template <class Item>
495{
496 if (this != &o) {
497 delete[] v;
498 v = o.v;
499 sz = o.sz;
500 count = o.count;
501 o.v = nullptr;
502 o.sz = 0;
503 o.count = 0;
504 }
505 return *this;
506}
507
508template <class Item>
518{
519 int oldCount = count;
520 // ajusta tamanho lógico e realoca se necessário
521 Count(oldCount + o.count);
522 // copia elementos
523 for (int k = 0; k < o.count; ++k) {
524 v[oldCount + k] = o.v[k];
525 }
526 return *this;
527}
528
529
530
531//----------------------------------------------------------------------------
532// Implementação de operator[] para auto-expansão
533//----------------------------------------------------------------------------
534
538template <class Item>
540{
541 if (i >= sz)
542 Size(2 * (i + 1));
543
544 if (i >= count)
545 count = i + 1;
546
547 return v[i];
548}
549
550
554template <class Item>
555const Item& TVector<Item>::operator[](int i) const
556{
557 if (i < 0 || i >= count)
558 return TVector<Item>::erro;
559
560 return v[i];
561}
562
563//----------------------------------------------------------------------------
564// Pesquisa de elementos
565//----------------------------------------------------------------------------
566
575template <class Item>
576int TVector<Item>::Find(Item& i, bool binary, int left, int right)
577{
578 if (binary) {
579 if (right < 0 || right > count - 1) right = count - 1;
580 if (left < 0 || left > right) left = 0;
581 while (left <= right) {
582 int mid = (left + right) >> 1;
583 if (v[mid] == i) return mid;
584 if (v[mid] < i) left = mid + 1;
585 else right = mid - 1;
586 }
587 }
588 else {
589 for (int k = 0; k < count; ++k)
590 if (v[k] == i)
591 return k;
592 }
593 return -1;
594}
595
596//----------------------------------------------------------------------------
597// Ordenação
598//----------------------------------------------------------------------------
599
605template <class Item>
607{
608 if (idxvect == nullptr) {
609 QuickSort(0, count - 1);
610 Insertion(0, count - 1);
611 }
612 else {
613 idx = idxvect;
614 idx->Count(count);
615 for (int k = 0; k < count; ++k)
616 (*idx)[k] = k;
617 QuickSortIdx(0, count - 1);
618 }
619 return *this;
620}
621
622
628template <class Item>
629void TVector<Item>::Sort(int start, int end)
630{
631 if (end > count - 1 || end < 0) end = count - 1;
632 if (start < 0) start = 0;
633 if (start < end) {
634 QuickSort(start, end);
635 Insertion(start, end);
636 }
637}
638
639
646template <class Item>
647void TVector<Item>::QuickSort(int start, int end)
648{
649 if (end - start > 32) {
650 // pivôs median-of-three
651 Exch((start + end) >> 1, end - 1);
652 if (v[end - 1] < v[start]) Exch(end - 1, start);
653 if (v[end] < v[start]) Exch(end, start);
654 if (v[end] < v[end - 1]) Exch(end, end - 1);
655
656 start++; end--;
657
658 // partição
659 int i = start - 1, j = end;
660 Item pivot = v[end];
661 for (;;) {
662 while (v[++i] < pivot);
663 while (pivot < v[--j] && j > start);
664 if (i >= j) break;
665 Exch(i, j);
666 }
667 Exch(i, end);
668
669 QuickSort(start - 1, i - 1);
670 QuickSort(i + 1, end + 1);
671 }
672}
673
674
680template <class Item>
681void TVector<Item>::Insertion(int start, int end)
682{
683 for (int i = end; i > start; --i)
684 if (v[i - 1] > v[i])
685 Exch(i - 1, i);
686
687 for (int i = start + 2; i <= end; ++i) {
688 Item tmp = v[i];
689 int j = i;
690 while (tmp < v[j - 1]) {
691 v[j] = v[j - 1];
692 --j;
693 }
694 v[j] = tmp;
695 }
696}
697
698
699
705template <class Item>
706void TVector<Item>::QuickSortIdx(int start, int end)
707{
708 if (end - start < 3) {
709 // pequenos casos
710 if (end - start == 1) {
711 if (v[(*idx)[end]] < v[(*idx)[start]])
712 ExchIdx(end, start);
713 }
714 else if (end - start == 2) {
715 if (v[(*idx)[end - 1]] < v[(*idx)[start]])
716 ExchIdx(end - 1, start);
717 if (v[(*idx)[end]] < v[(*idx)[start]])
718 ExchIdx(end, start);
719 if (v[(*idx)[end]] < v[(*idx)[end - 1]])
720 ExchIdx(end, end - 1);
721 }
722 }
723 else {
724 // pivôs median-of-three em idx
725 ExchIdx((start + end) >> 1, end - 1);
726 if (v[(*idx)[end - 1]] < v[(*idx)[start]])
727 ExchIdx(end - 1, start);
728 if (v[(*idx)[end]] < v[(*idx)[start]])
729 ExchIdx(end, start);
730 if (v[(*idx)[end]] < v[(*idx)[end - 1]])
731 ExchIdx(end, end - 1);
732
733 start++; end--;
734
735 // partição em idx
736 int i = start - 1, j = end;
737 Item pivot = v[(*idx)[end]];
738 for (;;) {
739 while (v[(*idx)[++i]] < pivot);
740 while (pivot < v[(*idx)[--j]] && j > start);
741 if (i >= j) break;
742 ExchIdx(i, j);
743 }
744 ExchIdx(i, end);
745
746 if (i > start) QuickSortIdx(start - 1, i - 1);
747 if (i < end) QuickSortIdx(i + 1, end + 1);
748 }
749}
750
751
752//----------------------------------------------------------------------------
753// Baralhar
754//----------------------------------------------------------------------------
755
760template <class Item>
762{
763 for (int k = count - 1; k > 0; --k)
764 Exch(k, TRand::rand() % (k + 1));
765 return *this;
766}
767
773template <class Item>
775{
776 int k = 0;
777 for (int w = 0; w < count; ++w) {
778 if (v[w] != i) {
779 v[k++] = v[w];
780 }
781 }
782 count = k;
783 return *this;
784}
785
786
792template <class Item>
794{
795 for (int j = 0; j < count; ++j) {
796 v[j] = i;
797 }
798 return *this;
799}
800
801
808template <class Item>
809TVector<Item>& TVector<Item>::Replace(const Item& iold, const Item& inew)
810{
811 for (int k = 0; k < count; ++k) {
812 if (v[k] == iold) {
813 v[k] = inew;
814 }
815 }
816 return *this;
817}
818
819
825template <class Item>
827{
828 for (int k = i; k < count - 1; ++k) {
829 v[k] = v[k + 1];
830 }
831 --count;
832 return *this;
833}
834
835
844template <class Item>
846{
847 if (count > 0) {
848 Sort();
849 int k = 0, w = 1;
850 while (w < count) {
851 if (v[k] != v[w]) {
852 v[++k] = v[w];
853 }
854 ++w;
855 }
856 count = k + 1;
857 }
858 return *this;
859}
860
861
867template <class Item>
869{
870 int k = 0, w = 0, s = Count();
871 while (k < other.Count()) {
872 while (w < s && operator[](w) < other[k]) {
873 ++w;
874 }
875 if (w >= s || operator[](w) > other[k]) {
876 Add(other[k++]);
877 }
878 else {
879 ++k;
880 }
881 }
882 Sort();
883 return *this;
884}
885
886
892template <class Item>
894{
895 int k = 0, w = 0, z = 0;
896 while (k < other.Count() && w < Count()) {
897 if (operator[](w) < other[k]) {
898 ++w;
899 }
900 else if (operator[](w) == other[k]) {
901 v[z++] = v[w++];
902 ++k;
903 }
904 else {
905 ++k;
906 }
907 }
908 Count(z);
909 return *this;
910}
911
912
918template <class Item>
920{
921 int k = 0, w = 0, z = 0;
922 while (k < other.Count() && w < Count()) {
923 if (v[w] < other[k]) {
924 v[z++] = v[w++];
925 }
926 else if (v[w] == other[k]) {
927 ++w; ++k;
928 }
929 else {
930 ++k;
931 }
932 }
933 while (w < Count()) {
934 v[z++] = v[w++];
935 }
936 Count(z);
937 return *this;
938}
939
945template <class Item>
946bool TVector<Item>::Equal(const TVector<Item>& other) const
947{
948 if (count != other.Count()) return false;
949 for (int k = 0; k < count; ++k) {
950 if (v[k] != other[k]) return false;
951 }
952 return true;
953}
954
955
961template <class Item>
963{
964 if (count > other.Count()) return false;
965 int k2 = 0;
966 for (int k = 0; k < count; ++k) {
967 while (k2 < other.Count() && v[k2] < v[k]) {
968 ++k2;
969 }
970 if (k2 >= other.Count() || other[k2] != v[k]) {
971 return false;
972 }
973 }
974 return true;
975}
976
977
984template <class Item>
986{
987 if (index < 0) index = Count();
988 int w = src.Count();
989 if (w > 0) {
990 int oldCount = Count();
991 Count(oldCount + w);
992 if (index > oldCount) index = oldCount;
993 for (int k = oldCount - 1; k >= index; --k) {
994 v[k + w] = v[k];
995 }
996 for (int k = 0; k < w; ++k) {
997 v[index + k] = src[k];
998 }
999 }
1000 return *this;
1001}
1002
1009template <class Item>
1011{
1012 if (index < 0) index = Count();
1013 int oldCount = Count();
1014 Count(oldCount + 1);
1015 if (index > oldCount) index = oldCount;
1016 for (int k = oldCount - 1; k >= index; --k) {
1017 v[k + 1] = v[k];
1018 }
1019 v[index] = a;
1020 return *this;
1021}
1022
1027template <class Item>
1029{
1030 for (int k = 0; k < count / 2; ++k) {
1031 Exch(k, count - 1 - k);
1032 }
1033 return *this;
1034}
1035
1036
1047template <class Item>
1049{
1050 int result = 0;
1051 int n1 = Count(), n2 = other.Count();
1052
1053 if (type == 0) {
1054 result = abs(n1 - n2);
1055 int m = Min(n1, n2);
1056 for (int i = 0; i < m; ++i) {
1057 if (v[i] != other[i]) ++result;
1058 }
1059 }
1060 else if (type == 1) {
1061 int m = Min(n1, n2);
1062 for (int i = 0; i < m; ++i) {
1063 result += abs(v[i] - other[i]);
1064 }
1065 }
1066 else if (type == 2) {
1067 result = Max(n1, n2);
1068 for (int i = 0; i + 1 < n1; ++i) {
1069 int j = other.Find(v[i]);
1070 if (j >= 0 && j + 1 < n2 && v[i + 1] == other[j + 1]) {
1071 --result;
1072 }
1073 }
1074 }
1075 else if (type == 3) {
1076 int rows = n1 + 1, cols = n2 + 1;
1077 TVector<int> mtx(rows * cols);
1078 // inicialização da matriz
1079 for (int i = 0; i < rows; ++i) mtx[i] = i;
1080 for (int j = 1; j < cols; ++j) mtx[j * rows] = j;
1081 // cálculo da distância de edição
1082 for (int i = 1; i < rows; ++i) {
1083 for (int j = 1; j < cols; ++j) {
1084 int cost = (v[i - 1] == other[j - 1] ? 0 : 1);
1085 int val = mtx[(i - 1) + rows * (j - 1)] + cost;
1086 val = Min(val, mtx[(i - 1) + rows * j] + 1);
1087 val = Min(val, mtx[i + rows * (j - 1)] + 1);
1088 mtx[i + rows * j] = val;
1089 }
1090 }
1091 result = mtx[n1 + rows * n2];
1092 }
1093
1094 return result;
1095}
1096
1097
1098class TString : public TVector<char> {
1099private:
1100 // Função auxiliar para fopen compatível com MSVC
1101 // usado em readLines e writeLines
1102 static FILE* fopen_compat(const char* filename, const char* mode) {
1103#ifdef _MSC_VER
1104 FILE* f = nullptr;
1105 fopen_s(&f, filename, mode);
1106 return f;
1107#else
1108 return std::fopen(filename, mode);
1109#endif
1110 }
1111
1112public:
1113 using TVector<char>::TVector; // herdar construtores
1114
1116 Count(1);
1117 Last() = 0;
1118 }
1119
1120 // construtor a partir de const char*
1121 TString(const char* s) {
1122 if (!s) {
1123 Count(1);
1124 Last() = 0;
1125 return;
1126 }
1127 int n = (int)strlen(s);
1128 Count(n + 1);
1129 memcpy(Data(), s, n + 1);
1130 Last() = 0;
1131 }
1132
1133 // permite converter int direto: TString(valorInt)
1134 TString(int v) {
1135 printf("%d", v);
1136 }
1137
1138 // conversão implícita para const char*
1139 operator const char* () const noexcept {
1140 return Data();
1141 }
1142
1143 // devolve const char* de forma curta:
1144 // em vez de printf("%s",(const char*)nome); basta printf("%s",*nome);
1145 const char* operator*() const noexcept {
1146 return Data();
1147 }
1148
1149 // printf, adiciona o texto formatado à string atual
1150 TString& printf(const char* fmt, ...) {
1151 // calcular tamanho necessário
1152 va_list args;
1153 va_start(args, fmt);
1154 int needed = vsnprintf(nullptr, 0, fmt, args);
1155 va_end(args);
1156
1157 if (needed < 0)
1158 return *this;
1159
1160 // remover o '\0' anterior
1161 Pop();
1162 int old = Count();
1163
1164 // expandir para conter o novo texto + '\0'
1165 Count(Count() + needed + 1);
1166
1167 // escrever no fim
1168 va_start(args, fmt);
1169 vsnprintf(Data() + old, needed + 1, fmt, args);
1170 va_end(args);
1171
1172 return *this;
1173 }
1174
1175 // concatenação com outra TString
1176 TString& operator+=(const TString& other) {
1177 Pop(); // remover '\0'
1179 Last() = 0;
1180 return *this;
1181 }
1182
1184 bool Empty() const { return (Count() <= 1); }
1185
1186 // hash da string usando o algoritmo djb2
1187 unsigned int Hash() const
1188 {
1189 unsigned int hash = 5381;
1190 for (unsigned char c : *this)
1191 hash = ((hash << 5) + hash) + c; // hash * 33 + c
1192 return hash;
1193 }
1194
1195 // tokenização: divide a string em partes usando os delimitadores fornecidos
1196 TVector<TString> tok(const char* delim = " \t\n\r") const {
1197 TVector<TString> out;
1198 const char* s = Data();
1199 int n = Count();
1200 int i = 0;
1201 while (i < n) {
1202 // saltar delimitadores
1203 while (i < n && strchr(delim, s[i]))
1204 i++;
1205
1206 if (i >= n || s[i] == 0)
1207 break;
1208
1209 int start = i;
1210
1211 // avançar até próximo delimitador
1212 while (i < n && s[i] != 0 && !strchr(delim, s[i]))
1213 i++;
1214
1215 // extrair token
1216 int len = i - start;
1217 TString tok;
1218 tok.Count(len + 1);
1219 memcpy(tok.Data(), s + start, len);
1220 tok[len] = 0;
1221
1222 out += tok;
1223 }
1224
1225 return out;
1226 }
1227
1228 // métodos de conveniência (leitura/gravação em ficheiros de texto)
1230 TVector<TString> lines;
1231 TString line;
1232 int c;
1233 FILE* f = fopen_compat(Data(), "r");
1234 if (!f) return lines;
1235 while ((c = fgetc(f)) != EOF)
1236 if (c == '\n') { // tratar apenas \n como quebra de linha
1237 lines += line;
1238 line = TString();
1239 }
1240 else if (c != '\r') { // ignorar sempre \r
1241 line.Last() = c;
1242 line.Add(0);
1243 }
1244 lines += line;
1245 fclose(f);
1246 return lines;
1247 }
1248 TString& writeLines(const TVector<TString>& lines, bool append = false) {
1249 FILE* f = fopen_compat(Data(), append ? "ab" : "wb");
1250 if (!f) return *this;
1251 for (const auto& line : lines)
1252 fprintf(f, "%s\n", *line);
1253 fclose(f);
1254 return *this;
1255 }
1256
1257
1258};
1259
1260class TBits : public TVector<uint64_t> {
1261public:
1262 // Construtores herdados
1263 TBits(int words = 0) : TVector<uint64_t>(words) { Count(words); Reset(0ULL); }
1264
1265 inline unsigned int Hash() const;
1266
1267 // --- Operações binárias entre TBits ---
1268 inline TBits operator&(const TBits& other) const;
1269 inline TBits operator|(const TBits& other) const;
1270 inline TBits operator^(const TBits& other) const;
1271 inline TBits operator~() const;
1272
1273 TBits& operator&=(const TBits& other) { return *this = *this & other; }
1274 TBits& operator|=(const TBits& other) { return *this = *this | other; }
1275 TBits& operator^=(const TBits& other) { return *this = *this ^ other; }
1276
1277 // permite usar if (a & b) em que a e b são TBits, para verificar se há algum bit em comum
1278 explicit operator bool() const {
1279 for (int i = 0; i < Count(); i++)
1280 if (Data()[i] != 0ULL)
1281 return true;
1282 return false;
1283 }
1284
1285 // --- Bits individuais ---
1286 inline bool GetBit(int index) const;
1287 inline void SetBit(int index, bool value);
1288
1289 // --- Inserir / extrair inteiros pequenos ---
1290 inline void SetBits(uint64_t value, int bitIndex, int bitCount);
1291 inline uint64_t GetBits(int bitIndex, int bitCount) const;
1292};
1293
1294unsigned int TBits::Hash() const {
1295 // utilizando FNV-1 hash (http://www.isthe.com/chongo/tech/comp/fnv/)
1296 uint32_t h = 2166136261;
1297 for (uint64_t word : *this) {
1298 // processar cada octeto
1299 // quando o valor fica 0, já não interessa
1300 // já que existindo dados, são distintos de 0
1301 for (int i = 0; i < 8 && word; i++) {
1302 unsigned char octeto = word & 255;
1303 word >>= 8;
1304 h *= 16777619;
1305 h ^= octeto;
1306 }
1307 }
1308 return h;
1309}
1310
1311TBits TBits::operator&(const TBits& other) const {
1312 int n = (Count() < other.Count() ? Count() : other.Count());
1313 TBits r(n);
1314 for (int i = 0; i < n; i++)
1315 r[i] = Data()[i] & other[i];
1316 return r;
1317}
1318
1319TBits TBits::operator|(const TBits& other) const {
1320 int n = (Count() > other.Count() ? Count() : other.Count());
1321 TBits r(n);
1322 for (int i = 0; i < n; i++) {
1323 uint64_t a = (i < Count()) ? Data()[i] : 0;
1324 uint64_t b = (i < other.Count()) ? other[i] : 0;
1325 r[i] = a | b;
1326 }
1327 return r;
1328}
1329
1330TBits TBits::operator^(const TBits& other) const {
1331 int n = (Count() > other.Count() ? Count() : other.Count());
1332 TBits r(n);
1333 for (int i = 0; i < n; i++) {
1334 uint64_t a = (i < Count()) ? Data()[i] : 0;
1335 uint64_t b = (i < other.Count()) ? other[i] : 0;
1336 r[i] = a ^ b;
1337 }
1338 return r;
1339}
1340
1342 TBits r(Count());
1343 for (int i = 0; i < Count(); i++)
1344 r[i] = ~Data()[i];
1345 return r;
1346}
1347
1348bool TBits::GetBit(int index) const {
1349 int w = index >> 6;
1350 int o = index & 63;
1351 if (w >= Count()) return false;
1352 return (Data()[w] >> o) & 1ULL;
1353}
1354
1355uint64_t TBits::GetBits(int bitIndex, int bitCount) const {
1356 int w = bitIndex >> 6;
1357 int o = bitIndex & 63;
1358
1359 uint64_t v = (w < Count()) ? (Data()[w] >> o) : 0;
1360
1361 if (o + bitCount > 64 && w + 1 < Count())
1362 v |= Data()[w + 1] << (64 - o);
1363
1364 return v & (bitCount == 64 ? ~0ULL : ((1ULL << bitCount) - 1));
1365}
1366
1367
1368void TBits::SetBit(int index, bool value) {
1369 int w = index >> 6;
1370 int o = index & 63;
1371 if (w >= Count()) {
1372 int currentWords = Count();
1373 Count(w + 1);
1374 while (currentWords < Count())
1375 Data()[currentWords++] = 0ULL;
1376 }
1377
1378 uint64_t& word = (*this)[w];
1379 if (value)
1380 word |= (1ULL << o);
1381 else
1382 word &= ~(1ULL << o);
1383}
1384
1385void TBits::SetBits(uint64_t value, int bitIndex, int bitCount) {
1386 int w = bitIndex >> 6;
1387 int o = bitIndex & 63;
1388
1389 if (w + 1 >= Count()) {
1390 int currentWords = Count();
1391 Count(w + 2);
1392 while (currentWords < Count())
1393 Data()[currentWords++] = 0ULL;
1394 }
1395
1396 uint64_t mask = (bitCount == 64 ? ~0ULL : ((1ULL << bitCount) - 1)) << o;
1397 Data()[w] = (Data()[w] & ~mask) | ((value << o) & mask);
1398
1399 if (o + bitCount > 64) {
1400 int spill = (o + bitCount) - 64;
1401 uint64_t mask2 = (1ULL << spill) - 1;
1402 Data()[w + 1] = (Data()[w + 1] & ~mask2) | (value >> (64 - o));
1403 }
1404}
1405
1406
1407template<>
1408inline TVector<int>::TVector(const char* str) {
1409 TString buffer(str);
1410 char* token = buffer.Data();
1411 char* pt;
1412 if (!str || *str == '\0')
1413 return;
1414
1415 // separar por vírgulas
1416 if ((pt = strchr(token, ','))) {
1417 *pt = 0;
1418 *this = TVector(token);
1419 do {
1420 token = pt + 1;
1421 if ((pt = strchr(token, ',')))
1422 *pt = 0;
1423 *this += TVector(token);
1424 } while (pt);
1425 }
1426 else {
1427 // procurar por : (intervalo)
1428 if ((pt = strchr(token, ':'))) {
1429 char* pt2;
1430 *pt = 0;
1431 int A = atoi(token);
1432 int C = 1;
1433 if ((pt2 = strchr(pt + 1, ':'))) { // A:B:C
1434 *pt2 = 0;
1435 if ((C = atoi(pt2 + 1)) <= 0)
1436 C = 1;
1437 } // c.c. A:B
1438 int B = atoi(pt + 1);
1439 if (A > B) { // ordem não interessa
1440 int aux = A;
1441 A = B;
1442 B = aux;
1443 }
1444 for (int i = A; i <= B; i += C)
1445 *this += i;
1446 }
1447 else // inteiro apenas
1448 *this += atoi(token);
1449 }
1450 BeASet();
1451}
1452
1453template<>
1454inline TVector<int>& TVector<int>::operator+=(const char* str) {
1455 *this += TVector<int>(str);
1456 return *this;
1457}
1458
1459// permite fazer for(auto x : _TV("1:10,15:50:3,73")) printf("%d ", x);
1460inline TVector<int> _TV(const char* str) {
1461 return TVector<int>(str);
1462}
1463
Interface para geração de números aleatórios independentes do sistema operativo.
TVector< int > _TV(const char *str)
Definition TVector.h:1460
uint64_t GetBits(int bitIndex, int bitCount) const
Definition TVector.h:1355
TBits operator|(const TBits &other) const
Definition TVector.h:1319
void SetBits(uint64_t value, int bitIndex, int bitCount)
Definition TVector.h:1385
TBits operator~() const
Definition TVector.h:1341
TBits operator&(const TBits &other) const
Definition TVector.h:1311
TBits & operator^=(const TBits &other)
Definition TVector.h:1275
void SetBit(int index, bool value)
Definition TVector.h:1368
TBits & operator|=(const TBits &other)
Definition TVector.h:1274
TBits operator^(const TBits &other) const
Definition TVector.h:1330
unsigned int Hash() const
Definition TVector.h:1294
TBits(int words=0)
Definition TVector.h:1263
bool GetBit(int index) const
Definition TVector.h:1348
TBits & operator&=(const TBits &other)
Definition TVector.h:1273
TString & operator+=(const TString &other)
Definition TVector.h:1176
TVector< TString > tok(const char *delim=" \t\n\r") const
Definition TVector.h:1196
TString(int v)
Definition TVector.h:1134
TString()
Definition TVector.h:1115
TString & printf(const char *fmt,...)
Definition TVector.h:1150
const char * operator*() const noexcept
Definition TVector.h:1145
bool Empty() const
Definition TVector.h:1184
TString(const char *s)
Definition TVector.h:1121
unsigned int Hash() const
Definition TVector.h:1187
TVector< TString > readLines()
Definition TVector.h:1229
TString & writeLines(const TVector< TString > &lines, bool append=false)
Definition TVector.h:1248
friend bool operator!=(const TVector< Item > &a, const TVector< Item > &b)
Definition TVector.h:340
Item * end() noexcept
Definition TVector.h:320
Item & First()
Definition TVector.h:224
TVector< Item > & Count(int value)
Ajusta o tamanho lógico do vetor para value.
Definition TVector.h:244
TVector< Item > & BeASet()
Converte o vetor num conjunto: remove duplicados e ordena.
Definition TVector.h:845
virtual ~TVector() noexcept
Destrutor.
Definition TVector.h:439
static Item erro
Valor retornado em casos de acesso inválido.
Definition TVector.h:62
bool Equal(const TVector< Item > &v) const
Verifica se dois vetores-conjunto são iguais.
Definition TVector.h:946
friend TVector< Item > operator+(TVector< Item > a, const TVector< Item > &b)
Definition TVector.h:334
TVector & operator=(TVector &&o) noexcept
Operador de atribuição por movimentação.
Definition TVector.h:494
Item & Pop()
Definition TVector.h:193
TVector< Item > & Replace(Item const &iold, Item const &inew)
Substitui todas as ocorrências de um valor antigo por um novo.
Definition TVector.h:809
Item & operator[](int i)
Acesso por índice com auto-expansão.
Definition TVector.h:539
TVector & operator=(const TVector &o)
Operador de atribuição por cópia.
Definition TVector.h:461
const Item * begin() const noexcept
Definition TVector.h:321
TVector< Item > & Insert(TVector< Item > &v, int index=0)
Insere um vetor de itens na posição indicada.
Definition TVector.h:985
TVector< Item > & RandomOrder()
Coloca os elementos em ordem aleatória (Fisher–Yates shuffle).
Definition TVector.h:761
TVector< Item > & Difference(const TVector< Item > &v)
Diferença deste conjunto em relação a outro.
Definition TVector.h:919
TVector< Item > & Sort(TVector< int > *idxvect=nullptr)
Ordena todo o vetor, opcionalmente devolvendo índices ordenados.
Definition TVector.h:606
TVector< Item > & operator+=(const Item &x)
Definition TVector.h:328
Item & Random()
Definition TVector.h:253
TVector & operator+=(const TVector &o)
Concatena outro vetor a este.
Definition TVector.h:517
TVector< Item > & operator-=(const Item &x)
Definition TVector.h:331
friend bool operator==(const TVector< Item > &a, const TVector< Item > &b)
Definition TVector.h:337
TVector(const char *str)
Constrói um vetor de inteiros a partir de uma string no formato de lista.
Definition TVector.h:129
TVector< Item > & Remove(Item const &i)
Remove todas as ocorrências de um dado elemento.
Definition TVector.h:774
TVector & operator+=(std::initializer_list< Item > init)
Adiciona múltiplos elementos ao final do vetor.
Definition TVector.h:155
int Distance(TVector< Item > &v, int type=0)
Calcula várias métricas de “distância” entre vetores.
Definition TVector.h:1048
TVector< Item > & Intersection(const TVector< Item > &v)
Interseção deste conjunto com outro.
Definition TVector.h:893
const Item & operator[](int i) const
Acesso constante por índice sem modificação de tamanho.
Definition TVector.h:555
const Item * Data() const
Acesso direto constante.
Definition TVector.h:221
bool Contained(const TVector< Item > &v) const
Verifica se este conjunto está contido no outro.
Definition TVector.h:962
TVector< Item > & Add(Item a)
Definition TVector.h:181
Item & Last()
Definition TVector.h:227
TVector< Item > & Reset(Item const &i)
Preenche todo o vetor com um mesmo valor.
Definition TVector.h:793
TVector< Item > & Invert()
Inverte a ordem dos elementos no vetor.
Definition TVector.h:1028
TVector< Item > & Insert(Item a, int index=0)
Insere um único elemento na posição indicada.
Definition TVector.h:1010
void Sort(int start, int end=-1)
Ordena um subintervalo [start,end] do vetor.
Definition TVector.h:629
TVector< Item > & Delete(int i)
Remove o elemento na posição i deslocando os seguintes.
Definition TVector.h:826
Item * begin() noexcept
Definition TVector.h:319
int Count() const
Definition TVector.h:230
TVector< Item > & operator+=(const char *str)=delete
Acrescenta elementos a partir de uma string no formato de lista.
Item * Data()
Acesso direto.
Definition TVector.h:219
virtual bool Empty() const
Definition TVector.h:233
int Find(Item &i, bool binary=false, int left=0, int right=-1)
Procura um elemento no vetor.
Definition TVector.h:576
TVector(int size, Item const *init)
Constrói um vetor pré-carregado a partir de um array.
Definition TVector.h:421
TVector< Item > & Union(const TVector< Item > &v)
Realiza a união deste conjunto com outro.
Definition TVector.h:868
TVector(int size=0)
Construtor.
Definition TVector.h:403
const Item * end() const noexcept
Definition TVector.h:322
TVector< Item > & Push(Item a)
Definition TVector.h:190
unsigned int rand(int seq)
Retorna o próximo valor pseudo-aleatório.
Definition TRand.cpp:46