#define _CRT_SECURE_NO_WARNINGS
#include "LRU_Cache.h"
#include <iostream>
#include <string>
static int failures = 0;
void esaytest() {
LRUCache cache(2);
cache.put(1, 1);
cache.put(2, 2);
std::cout << cache.get(1) << "\n";
cache.put(3, 3);
std::cout << cache.get(2) << "\n";
cache.put(4, 4);
std::cout << cache.get(1) << "\n";
std::cout << cache.get(3) << "\n";
std::cout << cache.get(4) << "\n";
}
bool expectEqual(int got, int want, const std::string& caseDesc) {
if (got == want) {
std::cout << "PASS: " << caseDesc << "\n";
return true;
} else {
std::cout << "FAIL: " << caseDesc << " -> got " << got << ", expected " << want << "\n";
++failures;
return false;
}
}
void test_leetcode_example() {
std::cout << "--- test_leetcode_example ---\n";
LRUCache cache(2);
cache.put(1, 1);
cache.put(2, 2);
expectEqual(cache.get(1), 1, "get(1) == 1");
cache.put(3, 3);
expectEqual(cache.get(2), -1, "get(2) == -1");
cache.put(4, 4);
expectEqual(cache.get(1), -1, "get(1) == -1 after eviction");
expectEqual(cache.get(3), 3, "get(3) == 3");
expectEqual(cache.get(4), 4, "get(4) == 4");
}
void test_update_existing_key() {
std::cout << "--- test_update_existing_key ---\n";
LRUCache cache(2);
cache.put(1, 1);
cache.put(2, 2);
cache.put(1, 10);
expectEqual(cache.get(1), 10, "updated get(1) == 10");
cache.put(3, 3);
expectEqual(cache.get(2), -1, "key 2 evicted after inserting key 3");
}
void test_capacity_one() {
std::cout << "--- test_capacity_one ---\n";
LRUCache cache(1);
cache.put(1, 1);
expectEqual(cache.get(1), 1, "capacity1 get(1) == 1");
cache.put(2, 2);
expectEqual(cache.get(1), -1, "capacity1 key1 evicted");
expectEqual(cache.get(2), 2, "capacity1 get(2) == 2");
}
void test_capacity_zero() {
std::cout << "--- test_capacity_zero ---\n";
LRUCache cache(0);
cache.put(1, 1);
expectEqual(cache.get(1), -1, "capacity0 get(1) == -1");
}
void test_access_ordering() {
std::cout << "--- test_access_ordering ---\n";
LRUCache cache(3);
cache.put(1, 1);
cache.put(2, 2);
cache.put(3, 3);
expectEqual(cache.get(1), 1, "access: get(1) moves 1 to MRU");
expectEqual(cache.get(2), 2, "access: get(2) moves 2 to MRU");
cache.put(4, 4);
expectEqual(cache.get(3), -1, "key 3 evicted after inserting key 4");
expectEqual(cache.get(1), 1, "get(1) still present");
expectEqual(cache.get(2), 2, "get(2) still present");
expectEqual(cache.get(4), 4, "get(4) == 4");
}
int main() {
esaytest();
test_leetcode_example();
test_update_existing_key();
test_capacity_one();
test_capacity_zero();
test_access_ordering();
if (failures == 0) {
std::cout << "\nAll tests passed.\n";
return 0;
} else {
std::cout << "\nTests failed: " << failures << "\n";
return 1;
}
}
#include <list>
#include <unordered_map>
#include <utility>
using namespace std;
class LRUCache {
private:
using NodeList = list<pair<int, int>>;
using Iterator = NodeList::iterator;
unordered_map<int, Iterator> _hashMap;
NodeList _LRUList;
size_t _capacity;
public:
LRUCache(int capacity) : _capacity(capacity) {}
int get(int key) {
auto ret = _hashMap.find(key);
if (ret != _hashMap.end()) {
Iterator it = ret->second;
_LRUList.splice(_LRUList.begin(), _LRUList, it);
return it->second;
} else {
return -1;
}
}
void put(int key, int value) {
auto ret = _hashMap.find(key);
if (ret != _hashMap.end()) {
Iterator it = ret->second;
it->second = value;
_LRUList.splice(_LRUList.begin(), _LRUList, it);
} else {
if (_hashMap.size() >= _capacity) {
int keyToRemove = _LRUList.back().first;
_hashMap.erase(keyToRemove);
_LRUList.pop_back();
}
_LRUList.push_front(make_pair(key, value));
_hashMap[key] = _LRUList.begin();
}
}
};