Advertisement
Guest User

Untitled

a guest
Jun 18th, 2019
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.42 KB | None | 0 0
  1. #include <cstdlib>
  2. #include <iostream>
  3.  
  4. #include "Colectie.h"
  5.  
  6. using std::cout;
  7.  
  8. Colectie::Colectie() {
  9. elements = NULL;
  10. nextElements = NULL;
  11. total = 0;
  12. capacity = 0;
  13. firstFree = 0;
  14.  
  15. expand(SIZE_FACTOR);
  16. }
  17.  
  18. void Colectie::expand(int newCapacity) {
  19. // keep a pointer to the old vectors
  20. TElem* oldElements = elements;
  21. int* oldNextElements = nextElements;
  22. int oldCapacity = capacity;
  23.  
  24. // alocate new vectors
  25. TElem* newElements = static_cast<TElem*>(malloc(sizeof(TElem) * (newCapacity)));
  26. int* newNextElements = static_cast<int*>(malloc(sizeof(int) * (newCapacity)));
  27.  
  28. // initialize the whole new vectors
  29. for (int i = 0; i < newCapacity; i++) {
  30. newElements[i] = MISSING_VALUE;
  31. newNextElements[i] = MISSING_POSITION;
  32. }
  33.  
  34. // assign the new vectors to use the innerAdd function we already have
  35. elements = newElements;
  36. nextElements = newNextElements;
  37. capacity = newCapacity;
  38.  
  39. // re-add each element in the old vector
  40. for (int i = 0; i < oldCapacity; i++) {
  41. TElem element = oldElements[i];
  42. innerAdd(element);
  43. }
  44.  
  45. // if capacity is 0, this is the initial expand
  46. // so don't do anything to the contents of the old vectors
  47. if (oldCapacity != 0) {
  48. free(oldElements);
  49. free(oldNextElements);
  50. }
  51. }
  52.  
  53. int Colectie::findFirstFree() {
  54. int position = 0;
  55. while (true) {
  56. if (position == capacity) {
  57. // we filled the list, there are no left positions
  58. // set the next free position to the old capacity
  59. // the list will be exanded on the next add
  60. position = capacity;
  61. break;
  62. }
  63.  
  64. // we found the firs tposition without value
  65. if (elements[position] == MISSING_VALUE) {
  66. break;
  67. }
  68.  
  69. position++;
  70. }
  71.  
  72. return position;
  73. }
  74.  
  75. int Colectie::hash(TElem element) const {
  76. return abs(element % capacity);
  77. }
  78.  
  79. void Colectie::print() const {
  80. cout << "START PRINT\n";
  81. for (int i = 0; i < capacity; i++) {
  82. if (elements[i] != MISSING_VALUE)
  83. cout << i << "\t";
  84. }
  85. cout << "\n";
  86.  
  87. for (int i = 0; i < capacity; i++) {
  88. if (elements[i] != MISSING_VALUE)
  89. cout << elements[i] << "\t";
  90. }
  91. cout << "\n";
  92.  
  93. for (int i = 0; i < capacity; i++) {
  94. if (elements[i] != MISSING_VALUE)
  95. cout << nextElements[i] << "\t";
  96. }
  97. cout << "\n";
  98. cout << "END PRINT\n";
  99. }
  100.  
  101. void Colectie::innerAdd(TElem element) {
  102. // we want to put our element at the position of our hash
  103. int targetPosition = hash(element);
  104.  
  105. if (elements[targetPosition] != MISSING_VALUE) {
  106. // the position of our hash is not empty
  107. // find the last position of elements sitting at our hash
  108. // since we need to make it point to our target position
  109. // which is the first free position
  110. int previousPosition = targetPosition;
  111.  
  112. while (true) {
  113. // we found the last element in the chain
  114. if (nextElements[previousPosition] == MISSING_POSITION) {
  115. break;
  116. }
  117.  
  118. // advance a position
  119. previousPosition = nextElements[previousPosition];
  120. }
  121.  
  122. // make sure the last element in the chain points at
  123. // the target position
  124. targetPosition = firstFree;
  125. nextElements[previousPosition] = firstFree;
  126. }
  127.  
  128. elements[targetPosition] = element;
  129.  
  130. // our target position might have been the first free position
  131. // find it again
  132. if (targetPosition == firstFree) {
  133. firstFree = findFirstFree();
  134. }
  135. }
  136.  
  137. void Colectie::add(TElem element) {
  138. if (total == capacity) {
  139. expand(capacity * SIZE_FACTOR);
  140. }
  141.  
  142. innerAdd(element);
  143. total += 1;
  144. }
  145.  
  146. bool Colectie::elementExists(TElem element) const {
  147. int targetPosition = hash(element);
  148.  
  149. while (true) {
  150. if (elements[targetPosition] == element) {
  151. // we found our element in the chain
  152. return true;
  153. }
  154.  
  155. if (nextElements[targetPosition] == MISSING_POSITION) {
  156. // we reached the end of the chain
  157. return false;
  158. }
  159.  
  160. targetPosition = nextElements[targetPosition];
  161. }
  162. }
  163.  
  164. int Colectie::getElementPosition(TElem element) const {
  165. int targetPosition = hash(element);
  166.  
  167. while (true) {
  168. if (elements[targetPosition] == element) {
  169. break;
  170. }
  171.  
  172. targetPosition = nextElements[targetPosition];
  173. }
  174.  
  175. return targetPosition;
  176. }
  177.  
  178. int Colectie::getPositionBefore(int position) const {
  179. int previousPosition = MISSING_POSITION;
  180.  
  181. for (int i = 0; i < capacity; i++) {
  182. if (nextElements[i] == position) {
  183. previousPosition = i;
  184. break;
  185. }
  186. }
  187.  
  188. return previousPosition;
  189. }
  190.  
  191. int Colectie::getPositionAfter(int position) const {
  192. int nextPosition = nextElements[position];
  193. return nextPosition;
  194. }
  195.  
  196. void Colectie::pullNextElementsBack(int position) {
  197. int nextPosition = nextElements[position];
  198.  
  199. while (true) {
  200. elements[position] = elements[nextPosition];
  201.  
  202. if (nextElements[nextPosition] == MISSING_POSITION) {
  203. // the next element is the end of the chain
  204. // and we already pulled it's value
  205. // we can skip to clearing the value
  206. // and making the previous element not point to anything
  207. break;
  208. }
  209.  
  210. // advance a position
  211. position = nextPosition;
  212. nextPosition = nextElements[nextPosition];
  213. }
  214.  
  215. elements[nextPosition] = MISSING_VALUE;
  216. nextElements[position] = MISSING_POSITION;
  217. }
  218.  
  219. bool Colectie::remove(TElem element) {
  220. if (!elementExists(element)) {
  221. // element is not in the chain
  222. return false;
  223. }
  224.  
  225. int targetPosition = getElementPosition(element);
  226. int previousPosition = getPositionBefore(targetPosition);
  227. int nextPosition = getPositionAfter(targetPosition);
  228.  
  229. if (nextPosition == MISSING_POSITION && previousPosition == MISSING_POSITION) {
  230. // element is the only one in the chain
  231. elements[targetPosition] = MISSING_VALUE;
  232. } else if (nextPosition == MISSING_POSITION) {
  233. // element is the last one in the chain
  234. elements[targetPosition] = MISSING_VALUE;
  235. nextElements[previousPosition] = MISSING_POSITION;
  236. } else {
  237. // element can be the first in the chain
  238. // and cannot be the last one in the chain
  239. // so we can pull the next value back
  240. pullNextElementsBack(targetPosition);
  241. }
  242.  
  243. total -= 1;
  244. return true;
  245. }
  246.  
  247. int Colectie::occurances(TElem element) const {
  248. int targetPosition = hash(element);
  249. int n = 0;
  250.  
  251. while (true) {
  252. if (elements[targetPosition] == element) {
  253. n++;
  254. }
  255.  
  256. if (nextElements[targetPosition] == MISSING_POSITION) {
  257. break;
  258. }
  259.  
  260. targetPosition = nextElements[targetPosition];
  261. }
  262.  
  263. return n;
  264. }
  265.  
  266. int Colectie::size() const {
  267. return total;
  268. }
  269.  
  270. void Colectie::adauga(TElem element) {
  271. add(element);
  272. }
  273.  
  274. bool Colectie::sterge(TElem element) {
  275. return remove(element);
  276. }
  277.  
  278. int Colectie::nrAparitii(TElem element) const {
  279. return occurances(element);
  280. }
  281.  
  282. bool Colectie::cauta(TElem element) const {
  283. return elementExists(element);
  284. }
  285.  
  286. int Colectie::dim() const {
  287. return size();
  288. }
  289.  
  290. bool Colectie::vida() const {
  291. return size() == 0;
  292. }
  293.  
  294. Colectie::~Colectie() {
  295. free(elements);
  296. free(nextElements);
  297. }
  298.  
  299. IteratorColectie Colectie::iterator() {
  300. return IteratorColectie(this);
  301. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement