#include "UserTable.h" #include #include const User UserTable::user_not_found = User{-1, "Not Found"}; UserTable::UserTable() : users{new User[capacity]} {} UserTable::UserTable(const std::string &fname) : UserTable{} { std::ifstream ufile(fname); if (ufile.is_open()) { while (ufile) { int cn; if (ufile >> cn) { ufile.ignore(); // skip space char n[80]; ufile.getline(n, 80); addUser(User(cn, n)); } } } else { std::cout << "Could not open " << fname << std::endl; } } void UserTable::addUser(const User &u) { // gör tabellen större vid behov ensureCapacity(n + 1); // 1. Hitta rätt plats int pos{0}; while ((pos < n) && (users[pos].getCardNbr() < u.getCardNbr())) { ++pos; } // 2. skapa lucka i vektorn for (int i = n; i > pos; --i) { users[i] = users[i - 1]; } // 3. stoppa in den nya användaren i luckan users[pos] = u; ++n; } User UserTable::find(int c) const { // binärsökning (baserad på Holm, 2007) int low = 0; int high = n - 1; int mid = -1; bool found = false; while (low < high && !found) { mid = (low + high) / 2; // const int midnbr = users[mid].getCardNbr(); if (c == midnbr) { found = true; } else if (users[mid].getCardNbr() < c) { low = mid + 1; } else { high = mid - 1; } } return found ? users[mid] : user_not_found; } User UserTable::find(std::string name) const { auto it = std::find_if(users, users + n, [&name](const User &u) { return u.getName() == name; }); // If it is at the 'end' of users, the result is not found return (it != users+n) ? *it : user_not_found; } void UserTable::ensureCapacity(int s) { if (s > capacity) { while (s > capacity) { capacity *= 4; } auto tmp = new User[capacity]; std::copy(users, users + n, tmp); delete[] users; users = tmp; } } void UserTable::print(std::ostream &os) const { os << "-------------" << std::endl; for (int i = 0; i != getNbrUsers(); ++i) { const auto &u = users[i]; os << "(" << u.getCardNbr() << ") " << u.getName() << std::endl; } os << "=============" << std::endl; } /** * Testmetod för binärsökningen: * går igenom alla användare och kollar att deras kortnummer kan sökas upp. * Om något kortnummer inte kunde sökas upp returneras detta. Annars, om * alla sökningar lyckades, returneras 0. */ int testFindNbr(const UserTable ut) { for (int i = 0; i < ut.n; i++) { int nbr = ut.users[i].getCardNbr(); User found = ut.find(nbr); if (found != ut.users[i]) { return nbr; } } return 0; }