2021-10-27 15:15:47 +02:00
|
|
|
#include "UserTable.h"
|
|
|
|
#include <algorithm>
|
2024-11-27 17:25:14 +01:00
|
|
|
#include <fstream>
|
2021-10-27 15:15:47 +02:00
|
|
|
|
2024-11-27 17:25:14 +01:00
|
|
|
const User UserTable::user_not_found = User{-1, "Not Found"};
|
2021-10-27 15:15:47 +02:00
|
|
|
|
2024-11-27 17:25:14 +01:00
|
|
|
UserTable::UserTable() : users{new User[capacity]} {}
|
2021-10-27 15:15:47 +02:00
|
|
|
|
2024-11-27 17:25:14 +01:00
|
|
|
UserTable::UserTable(const std::string &fname) : UserTable{} {
|
2021-10-27 15:15:47 +02:00
|
|
|
std::ifstream ufile(fname);
|
|
|
|
|
2024-11-27 17:25:14 +01:00
|
|
|
if (ufile.is_open()) {
|
|
|
|
while (ufile) {
|
2021-10-27 15:15:47 +02:00
|
|
|
int cn;
|
2024-11-27 17:25:14 +01:00
|
|
|
if (ufile >> cn) {
|
2021-10-27 15:15:47 +02:00
|
|
|
ufile.ignore(); // skip space
|
|
|
|
char n[80];
|
2024-11-27 17:25:14 +01:00
|
|
|
ufile.getline(n, 80);
|
|
|
|
addUser(User(cn, n));
|
2021-10-27 15:15:47 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
std::cout << "Could not open " << fname << std::endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-11-27 17:25:14 +01:00
|
|
|
void UserTable::addUser(const User &u) {
|
2021-10-27 15:15:47 +02:00
|
|
|
// gör tabellen större vid behov
|
2024-11-27 17:25:14 +01:00
|
|
|
ensureCapacity(n + 1);
|
2024-12-05 12:02:17 +01:00
|
|
|
|
2021-10-27 15:15:47 +02:00
|
|
|
// 1. Hitta rätt plats
|
|
|
|
int pos{0};
|
2024-11-27 17:25:14 +01:00
|
|
|
while ((pos < n) && (users[pos].getCardNbr() < u.getCardNbr())) {
|
2021-10-27 15:15:47 +02:00
|
|
|
++pos;
|
|
|
|
}
|
|
|
|
|
2024-11-27 17:25:14 +01:00
|
|
|
// 2. skapa lucka i vektorn
|
|
|
|
for (int i = n; i > pos; --i) {
|
|
|
|
users[i] = users[i - 1];
|
2021-10-27 15:15:47 +02:00
|
|
|
}
|
|
|
|
|
2024-11-27 17:25:14 +01:00
|
|
|
// 3. stoppa in den nya användaren i luckan
|
2021-10-27 15:15:47 +02:00
|
|
|
users[pos] = u;
|
2024-12-05 12:02:17 +01:00
|
|
|
|
|
|
|
++n;
|
2021-10-27 15:15:47 +02:00
|
|
|
}
|
|
|
|
|
2024-11-27 17:25:14 +01:00
|
|
|
User UserTable::find(int c) const {
|
2021-10-27 15:15:47 +02:00
|
|
|
// binärsökning (baserad på Holm, 2007)
|
|
|
|
|
|
|
|
int low = 0;
|
|
|
|
int high = n - 1;
|
|
|
|
int mid = -1;
|
|
|
|
bool found = false;
|
2024-11-27 17:25:14 +01:00
|
|
|
while (low < high && !found) {
|
2021-10-27 15:15:47 +02:00
|
|
|
mid = (low + high) / 2;
|
|
|
|
//
|
2024-11-27 17:14:10 +01:00
|
|
|
const int midnbr = users[mid].getCardNbr();
|
|
|
|
if (c == midnbr) {
|
2021-10-27 15:15:47 +02:00
|
|
|
found = true;
|
|
|
|
} else if (users[mid].getCardNbr() < c) {
|
|
|
|
low = mid + 1;
|
|
|
|
} else {
|
|
|
|
high = mid - 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return found ? users[mid] : user_not_found;
|
|
|
|
}
|
2024-11-27 17:25:14 +01:00
|
|
|
User UserTable::find(std::string name) const {
|
2024-12-05 12:32:27 +01:00
|
|
|
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;
|
2021-10-27 15:15:47 +02:00
|
|
|
}
|
|
|
|
|
2024-11-27 17:25:14 +01:00
|
|
|
void UserTable::ensureCapacity(int s) {
|
|
|
|
if (s > capacity) {
|
|
|
|
while (s > capacity) {
|
|
|
|
capacity *= 4;
|
2021-10-27 15:15:47 +02:00
|
|
|
}
|
|
|
|
auto tmp = new User[capacity];
|
2024-11-27 17:25:14 +01:00
|
|
|
std::copy(users, users + n, tmp);
|
2021-10-27 15:15:47 +02:00
|
|
|
delete[] users;
|
2024-11-27 17:25:14 +01:00
|
|
|
users = tmp;
|
2021-10-27 15:15:47 +02:00
|
|
|
}
|
|
|
|
}
|
2024-11-27 17:25:14 +01:00
|
|
|
void UserTable::print(std::ostream &os) const {
|
2021-10-27 15:15:47 +02:00
|
|
|
os << "-------------" << std::endl;
|
2024-11-27 17:25:14 +01:00
|
|
|
for (int i = 0; i != getNbrUsers(); ++i) {
|
|
|
|
const auto &u = users[i];
|
|
|
|
os << "(" << u.getCardNbr() << ") " << u.getName() << std::endl;
|
2021-10-27 15:15:47 +02:00
|
|
|
}
|
|
|
|
os << "=============" << std::endl;
|
|
|
|
}
|
|
|
|
/**
|
2024-11-27 17:25:14 +01:00
|
|
|
* 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) {
|
2021-10-27 15:15:47 +02:00
|
|
|
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;
|
|
|
|
}
|