Initial commit

This commit is contained in:
user
2026-07-12 14:22:00 +04:00
commit 49ecd4784c
90 changed files with 6910 additions and 0 deletions
@@ -0,0 +1,22 @@
#include "convert.h"
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Convert)
size_t FromStdString::operator()(const std::array<char, 5> &value, size_t alphabetPower) const {
if (value.empty()) {
throw std::invalid_argument("undefined key");
}
size_t result = 0;
size_t counter = 0;
for (auto crbegin = value.crbegin(), crend = value.crend()
; crbegin != crend && *crbegin >= '!' && *crbegin <= '~'; ++crbegin, ++counter
) {
result += (*crbegin) * std::pow(alphabetPower, counter);
}
return result;
}
END_NAMESPACE // Convert
END_NAMESPACE // BusinessLogic
@@ -0,0 +1,24 @@
#ifndef CONVERT_H
#define CONVERT_H
#include "../businessLogic.h"
#include <string>
#include <stdexcept>
#include <limits>
#include <array>
#include <cmath>
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Convert)
class FromStdString
{
public:
size_t operator()(const std::array<char, 5> &, size_t) const;
};
END_NAMESPACE // Convert
END_NAMESPACE // BusinessLogic
#endif // CONVERT_H
@@ -0,0 +1,34 @@
#ifndef CREATOR_ALGHORITHM_DOUBLE_HASHING_H
#define CREATOR_ALGHORITHM_DOUBLE_HASHING_H
#include "doubleHashing.h"
#include "creatorFamily.h"
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Hash)
BEGIN_NAMESPACE(Algorithm)
BEGIN_NAMESPACE(DoubleHashing)
class Creator : public Family::Creator
{
private:
size_t m_firstHashFunction;
size_t m_secondHashFunction;
public:
Creator(size_t first, size_t second) : m_firstHashFunction(first), m_secondHashFunction(second)
{
}
public:
virtual std::unique_ptr<Abstract::Product> create() const override {
return std::unique_ptr<Abstract::Product>(new Product(m_firstHashFunction, m_secondHashFunction));
}
};
END_NAMESPACE // DoubleHashing
END_NAMESPACE // Algorithm
END_NAMESPACE // Hash
END_NAMESPACE // BusinessLogic
#endif // !CREATOR_ALGHORITHM_DOUBLE_HASHING_H
@@ -0,0 +1,24 @@
#ifndef CREATOR_ALGHORITHM_FAMILY_H
#define CREATOR_ALGHORITHM_FAMILY_H
#include "../creatorAbstract.h"
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Hash)
BEGIN_NAMESPACE(Algorithm)
BEGIN_NAMESPACE(Family)
class Creator : public Abstract::Creator
{
protected:
Creator()
{
}
};
END_NAMESPACE // Family
END_NAMESPACE // Algorithm
END_NAMESPACE // Hash
END_NAMESPACE // BusinessLogic
#endif // !CREATOR_ALGHORITHM_FAMILY_H
@@ -0,0 +1,34 @@
#ifndef CREATOR_ALGHORITHM_PSEUDORANDOM_PROBING_H
#define CREATOR_ALGHORITHM_PSEUDORANDOM_PROBING_H
#include "pseudorandomProbing.h"
#include "creatorFamily.h"
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Hash)
BEGIN_NAMESPACE(Algorithm)
BEGIN_NAMESPACE(PseudorandomProbing)
class Creator : public Family::Creator
{
private:
size_t m_hashFunctionNumber;
public:
Creator(size_t number) : m_hashFunctionNumber(number)
{
}
public:
virtual std::unique_ptr<Abstract::Product> create() const override {
return std::unique_ptr<Abstract::Product>(new Product(m_hashFunctionNumber));
}
};
END_NAMESPACE // PseudorandomProbing
END_NAMESPACE // Algorithm
END_NAMESPACE // Hash
END_NAMESPACE // BusinessLogic
#endif // !CREATOR_ALGHORITHM_PSEUDORANDOM_PROBING_H
@@ -0,0 +1,41 @@
#ifndef ALGHORITHM_DOUBLE_HASHING_H
#define ALGHORITHM_DOUBLE_HASHING_H
#include "family.h"
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Hash)
BEGIN_NAMESPACE(Algorithm)
BEGIN_NAMESPACE(DoubleHashing)
class Product final : public Family::Product
{
private:
size_t m_firstHashFunction;
size_t m_secondHashFunction;
size_t m_multiplier;
private:
friend Creator;
Product(size_t first, size_t second) : m_firstHashFunction(first), m_secondHashFunction(second)
{
if (first == second) {
throw std::invalid_argument("hash functions must be different");
}
}
protected:
virtual size_t getFirstCoefficient() override {
m_multiplier = m_hashFunction->getHash(m_convertValue, m_firstHashFunction);
return m_hashFunction->getHash(m_convertValue, m_firstHashFunction);
}
virtual size_t getSecondCoefficient(size_t counter) override {
return counter * m_multiplier;
}
};
END_NAMESPACE // DoubleHashing
END_NAMESPACE // Algorithm
END_NAMESPACE // Hash
END_NAMESPACE // BusinessLogic
#endif // !ALGHORITHM_DOUBLE_HASHING_H
@@ -0,0 +1,36 @@
#ifndef ALGHORITHM_FAMILY_H
#define ALGHORITHM_FAMILY_H
#include "../../Function/Family/family.h"
#include "../abstract.h"
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Hash)
BEGIN_NAMESPACE(Algorithm)
BEGIN_NAMESPACE(Family)
class Product : public Abstract::Product
{
public:
using function_type = Function::Family::Product;
protected:
const function_type *m_hashFunction;
protected:
Product() : m_hashFunction(nullptr)
{
}
public:
void setHashFunction(const function_type &hashFunction) {
m_hashFunction = &hashFunction;
}
};
END_NAMESPACE // Family
END_NAMESPACE // Algorithm
END_NAMESPACE // Hash
END_NAMESPACE // BusinessLogic
#endif // !ALGHORITHM_FAMILY_H
@@ -0,0 +1,44 @@
#ifndef ALGHORITHM_PSEUDORANDOM_PROBING_H
#define ALGHORITHM_PSEUDORANDOM_PROBING_H
#include "family.h"
#include <random>
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Hash)
BEGIN_NAMESPACE(Algorithm)
BEGIN_NAMESPACE(PseudorandomProbing)
class Product final : public Family::Product
{
private:
size_t m_hashFunctionNumber;
size_t m_multiplier;
private:
friend Creator;
Product(size_t number) : m_hashFunctionNumber(number)
{
}
protected:
// virtual bool isValidInput() const override {
// return isPrimeNumber(size());
// }
virtual size_t getFirstCoefficient() override {
m_multiplier = m_hashFunction->getHash(m_convertValue, m_hashFunctionNumber);
srand(m_multiplier);
return m_hashFunction->getHash(m_convertValue, m_hashFunctionNumber);
}
virtual size_t getSecondCoefficient(size_t counter) override {
return counter * rand();
}
};
END_NAMESPACE // PseudorandomProbing
END_NAMESPACE // Algorithm
END_NAMESPACE // Hash
END_NAMESPACE // BusinessLogic
#endif // !ALGHORITHM_PSEUDORANDOM_PROBING_H
@@ -0,0 +1,35 @@
#ifndef CREATOR_ALGHORITHM_LINEAR_PROBING_H
#define CREATOR_ALGHORITHM_LINEAR_PROBING_H
#include "linearProbing.h"
#include "creatorOne.h"
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Hash)
BEGIN_NAMESPACE(Algorithm)
BEGIN_NAMESPACE(LinearProbing)
class Creator : public One::Creator
{
private:
/* A number that is not mutually prime to the size will not apply */
const size_t m_coefficient;
public:
Creator(size_t coefficient = 1) : m_coefficient(coefficient)
{
}
public:
virtual std::unique_ptr<Abstract::Product> create() const override {
return std::unique_ptr<Abstract::Product>(new Product(m_coefficient));
}
};
END_NAMESPACE // LinearProbing
END_NAMESPACE // Algorithm
END_NAMESPACE // Hash
END_NAMESPACE // BusinessLogic
#endif // !CREATOR_ALGHORITHM_LINEAR_PROBING_H
@@ -0,0 +1,24 @@
#ifndef CREATOR_ALGHORITHM_ONE_H
#define CREATOR_ALGHORITHM_ONE_H
#include "../creatorAbstract.h"
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Hash)
BEGIN_NAMESPACE(Algorithm)
BEGIN_NAMESPACE(One)
class Creator : public Abstract::Creator
{
protected:
Creator()
{
}
};
END_NAMESPACE // One
END_NAMESPACE // Algorithm
END_NAMESPACE // Hash
END_NAMESPACE // BusinessLogic
#endif // !CREATOR_ALGHORITHM_ONE_H
@@ -0,0 +1,30 @@
#ifndef CREATOR_ALGHORITHM_QUADRATIC_PROBING_H
#define CREATOR_ALGHORITHM_QUADRATIC_PROBING_H
#include "quadraticProbing.h"
#include "creatorOne.h"
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Hash)
BEGIN_NAMESPACE(Algorithm)
BEGIN_NAMESPACE(QuadraticProbing)
class Creator : public One::Creator
{
public:
Creator()
{
}
public:
virtual std::unique_ptr<Abstract::Product> create() const override {
return std::unique_ptr<Abstract::Product>(new Product());
}
};
END_NAMESPACE // LinearProbing
END_NAMESPACE // Algorithm
END_NAMESPACE // Hash
END_NAMESPACE // BusinessLogic
#endif // !CREATOR_ALGHORITHM_QUADRATIC_PROBING_H
@@ -0,0 +1,41 @@
#ifndef ALGHORITHM_LINEAR_PROBING_H
#define ALGHORITHM_LINEAR_PROBING_H
#include "one.h"
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Hash)
BEGIN_NAMESPACE(Algorithm)
BEGIN_NAMESPACE(LinearProbing)
class Product final : public One::Product
{
private:
/* A number that is not mutually prime to the size will not apply */
const size_t m_coefficient;
private:
friend Creator;
Product(size_t coefficient)
: m_coefficient(coefficient == 0 ? 1 : coefficient)
{
}
protected:
// virtual bool isValidInput() const override {
// return gcd(m_coefficient, size()) == 1;
// }
virtual size_t getFirstCoefficient() override {
return m_hashFunction->getHash(m_convertValue);
}
virtual size_t getSecondCoefficient(size_t counter) override {
return counter * m_coefficient;
}
};
END_NAMESPACE // LinearProbing
END_NAMESPACE // Algorithm
END_NAMESPACE // Hash
END_NAMESPACE // BusinessLogic
#endif // !ALGHORITHM_LINEAR_PROBING_H
@@ -0,0 +1,36 @@
#ifndef ALGHORITHM_ONE_H
#define ALGHORITHM_ONE_H
#include "../../Function/One/one.h"
#include "../abstract.h"
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Hash)
BEGIN_NAMESPACE(Algorithm)
BEGIN_NAMESPACE(One)
class Product : public Abstract::Product
{
public:
using function_type = Function::One::Product;
protected:
const function_type *m_hashFunction;
protected:
Product() : m_hashFunction(nullptr)
{
}
public:
void setHashFunction(const function_type &hashFunction) {
m_hashFunction = &hashFunction;
}
};
END_NAMESPACE // One
END_NAMESPACE // Algorithm
END_NAMESPACE // Hash
END_NAMESPACE // BusinessLogic
#endif // !ALGHORITHM_ONE_H
@@ -0,0 +1,36 @@
#ifndef ALGHORITHM_QUADRATIC_PROBING_H
#define ALGHORITHM_QUADRATIC_PROBING_H
#include "one.h"
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Hash)
BEGIN_NAMESPACE(Algorithm)
BEGIN_NAMESPACE(QuadraticProbing)
class Product final : public One::Product
{
private:
friend Creator;
Product()
{
}
protected:
// virtual bool isValidInput() const override {
// return isPrimeNumber(size());
// }
virtual size_t getFirstCoefficient() override {
return m_hashFunction->getHash(m_convertValue);
}
virtual size_t getSecondCoefficient(size_t counter) override {
return std::pow(size(), counter);
}
};
END_NAMESPACE // LinearProbing
END_NAMESPACE // Algorithm
END_NAMESPACE // Hash
END_NAMESPACE // BusinessLogic
#endif // !ALGHORITHM_QUADRATIC_PROBING_H
@@ -0,0 +1,101 @@
#ifndef ALGHORITHM_ABSTRACT_H
#define ALGHORITHM_ABSTRACT_H
#include "../../Convert/convert.h"
#include <vector>
#include <cmath>
#include <stdexcept>
#include <memory>
#include <array>
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Hash)
BEGIN_NAMESPACE(Algorithm)
BEGIN_NAMESPACE(Abstract)
class Product
{
public:
using value_type = std::array<char, 5>;
private:
const std::vector<value_type> *m_table;
BusinessLogic::Convert::FromStdString m_toInteger;
protected:
size_t m_convertValue;
protected:
Product() : m_table(nullptr)
{
}
protected:
size_t gcd(size_t first, size_t second) const {
while (first > 0 && second > 0) {
first > second
? first %= second
: second %= first;
}
return first + second;
}
bool isPrimeNumber(size_t value) const {
size_t size = static_cast<size_t>(sqrt(value));
for (size_t i = 2; i <= size; i++) {
if (value % i == 0) {
return false;
}
}
return true;
}
size_t size() const {
return m_table->size();
}
protected:
virtual bool isValidInput() const {
return true;
}
virtual size_t getFirstCoefficient() = 0;
virtual size_t getSecondCoefficient(size_t counter) = 0;
public:
void setTable(decltype(m_table) table) {
m_table = table;
}
size_t getIndex(const value_type &value, size_t& numberOfCollisions, size_t alphabetPower) {
if (not isValidInput()) {
throw std::invalid_argument("the condition for using the algorithm is not met");
}
size_t size = m_table->size();
m_convertValue = m_toInteger(value, alphabetPower);
// It is necessary to use some coefficient
numberOfCollisions = 0;
decltype (m_table->cbegin()) currentIterator;
constexpr std::array<char, 5> nullValue = {'\0', '\0', '\0', '\0', '\0'};
while (numberOfCollisions <= size) {
currentIterator = {
m_table->cbegin()
+ ( getFirstCoefficient() + getSecondCoefficient(numberOfCollisions) ) % size
};
if ( *currentIterator == nullValue || *currentIterator == value ) { // Free cell or value match
return ( currentIterator - m_table->cbegin() );
}
++numberOfCollisions;
}
return std::numeric_limits<size_t>::max();
}
};
END_NAMESPACE // Abstract
END_NAMESPACE // Algorithm
END_NAMESPACE // Hash
END_NAMESPACE // BusinessLogic
#endif // !ALGHORITHM_ABSTRACT_H
@@ -0,0 +1,29 @@
#ifndef CREATOR_ALGHORITHM_ABSTRACT_H
#define CREATOR_ALGHORITHM_ABSTRACT_H
#include "../../../BusinessLogic/businessLogic.h"
#include <memory>
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Hash)
BEGIN_NAMESPACE(Algorithm)
BEGIN_NAMESPACE(Abstract)
class Creator
{
protected:
Creator()
{
}
public:
virtual std::unique_ptr<Product> create() const = 0;
};
END_NAMESPACE // Abstract
END_NAMESPACE // Algorithm
END_NAMESPACE // Hash
END_NAMESPACE // BusinessLogic
#endif // !CREATOR_ALGHORITHM_ABSTRACT_H
@@ -0,0 +1,48 @@
#ifndef FACTORY_ABSTRACT_H
#define FACTORY_ABSTRACT_H
#include "../Function/abstract.h"
#include "../Algorithm/abstract.h"
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Hash)
BEGIN_NAMESPACE(Factory)
class Abstract
{
public:
/*
* I used to use a constant link. This led to UB.
*
* https://eel.is/c++draft/class.temporary#6 (27.10.2021)
*
* The exceptions to this lifetime rule are:
* (6.9) A temporary object bound to a reference parameter in a function call ([expr.call]) persists until the completion of the full-expression containing the call.
*/
using AFC_type = std::shared_ptr<Function::Abstract::Creator>;
using AAC_type = std::shared_ptr<Algorithm::Abstract::Creator>;
protected:
AFC_type m_functionCreator;
AAC_type m_algorithmCreator;
protected:
Abstract(AFC_type functionCreator, AAC_type algorithmCreator)
: m_functionCreator(functionCreator), m_algorithmCreator(algorithmCreator)
{
}
public:
using AFP_type = Function::Abstract::Product;
using AAP_type = Algorithm::Abstract::Product;
public:
virtual const AFP_type &getFunction() const = 0;
virtual std::unique_ptr<AAP_type> getAlgorithm() const = 0;
};
END_NAMESPACE // Factory
END_NAMESPACE // Hash
END_NAMESPACE // BusinessLogic
#endif // !FACTORY_ABSTRACT_H
@@ -0,0 +1,46 @@
#ifndef FACTORY_FAMILY_H
#define FACTORY_FAMILY_H
#include "../Factory/abstract.h"
#include "../Function/Family/family.h"
#include "../Function/Family/creatorFamily.h"
#include "../Algorithm/Family/family.h"
#include "../Algorithm/Family/creatorFamily.h"
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Hash)
BEGIN_NAMESPACE(Factory)
class Family final : public Abstract
{
public:
using FFC_type = std::shared_ptr<Function::Family::Creator>;
using FAC_type = std::shared_ptr<Algorithm::Family::Creator>;
using FFP_type = Function::Family::Product;
using FAP_type = Algorithm::Family::Product;
public:
Family(const FFC_type functionCreator, const FAC_type algorithmCreator)
: Abstract(functionCreator, algorithmCreator)
{
}
public:
virtual const FFP_type &getFunction() const override {
return dynamic_cast<const FFP_type &>(m_functionCreator->create());
}
virtual std::unique_ptr<AAP_type> getAlgorithm() const override {
std::unique_ptr<AAP_type> algorithm = m_algorithmCreator->create();
dynamic_cast<FAP_type *>(algorithm.get())->setHashFunction(getFunction());
return algorithm;
}
};
END_NAMESPACE // Factory
END_NAMESPACE // Hash
END_NAMESPACE // BusinessLogic
#endif // !FACTORY_FAMILY_H
@@ -0,0 +1,46 @@
#ifndef FACTORY_ONE_H
#define FACTORY_ONE_H
#include "../Factory/abstract.h"
#include "../Function/One/one.h"
#include "../Function/One/creatorOne.h"
#include "../Algorithm/One/one.h"
#include "../Algorithm/One/creatorOne.h"
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Hash)
BEGIN_NAMESPACE(Factory)
class One final : public Abstract
{
public:
using OFC_type = std::shared_ptr<Function::One::Creator>;
using OAC_type = std::shared_ptr<Algorithm::One::Creator>;
using OFP_type = Function::One::Product;
using OAP_type = Algorithm::One::Product;
public:
One(OFC_type functionCreator, OAC_type algorithmCreator)
: Abstract(functionCreator, algorithmCreator)
{
}
public:
virtual const OFP_type &getFunction() const override {
return dynamic_cast<const OFP_type &>(m_functionCreator->create());
}
virtual std::unique_ptr<AAP_type> getAlgorithm() const override {
std::unique_ptr<AAP_type> algorithm = m_algorithmCreator->create();
dynamic_cast<OAP_type *>(algorithm.get())->setHashFunction(getFunction());
return algorithm;
}
};
END_NAMESPACE // Factory
END_NAMESPACE // Hash
END_NAMESPACE // BusinessLogic
#endif // !FACTORY_ONE_H
@@ -0,0 +1,27 @@
#ifndef CREATOR_FUNCTION_FAMILY_H
#define CREATOR_FUNCTION_FAMILY_H
#include "../creatorAbstract.h"
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Hash)
BEGIN_NAMESPACE(Function)
BEGIN_NAMESPACE(Family)
class Creator : public Abstract::Creator
{
protected:
Creator()
{
}
public:
virtual const Product &create() const = 0;
};
END_NAMESPACE // Family
END_NAMESPACE // Function
END_NAMESPACE // Hash
END_NAMESPACE // BusinessLogic
#endif // CREATOR_FUNCTION_FAMILY_H
@@ -0,0 +1,25 @@
#ifndef CREATOR_FUNCTION_FNV1a_H
#define CREATOR_FUNCTION_FNV1a_H
#include "fnv1a.h"
#include "creatorFamily.h"
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Hash)
BEGIN_NAMESPACE(Function)
BEGIN_NAMESPACE(FNV1a)
class Creator : public Family::Creator
{
public:
virtual const Product &create() const override {
return Product::getInstance();
}
};
END_NAMESPACE // FNV1a
END_NAMESPACE // Function
END_NAMESPACE // Hash
END_NAMESPACE // BusinessLogic
#endif // !CREATOR_FUNCTION_FNV1a_H
@@ -0,0 +1,39 @@
#ifndef FUNCTION_FAMILY_H
#define FUNCTION_FAMILY_H
#include "../abstract.h"
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Hash)
BEGIN_NAMESPACE(Function)
BEGIN_NAMESPACE(Family)
using function_type = std::function<size_t(size_t, size_t)>;
class Product : public Abstract::Product
{
protected:
const function_type m_function;
protected:
Product(const function_type& function) : m_function(function)
{
}
public:
const function_type &to_std() const {
return m_function;
}
size_t getHash(size_t first, size_t second) const {
// First - the value that is hashed
// Second - coefficient
return m_function(first, second);
}
};
END_NAMESPACE // Family
END_NAMESPACE // Function
END_NAMESPACE // Hash
END_NAMESPACE // BusinessLogic
#endif // FUNCTION_FAMILY_H
@@ -0,0 +1,40 @@
#ifndef FUNCTION_FNV1a_H
#define FUNCTION_FNV1a_H
#include "family.h"
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Hash)
BEGIN_NAMESPACE(Function)
BEGIN_NAMESPACE(FNV1a)
using Singleton = BusinessLogic::Pattern::Singleton<Product>;
class Product final : public Family::Product, public Singleton
{
private:
const int32_t m_p;
private:
friend const Product &Singleton::getInstance();
Product()
: Family::Product(
[this](size_t value, size_t i) -> size_t {
size_t result = (0x811C9DC5 xor i) xor static_cast<int32_t>(value);
return static_cast<int32_t>(result * m_p);
}
)
, m_p(0x01000193)
{
}
public:
using Singleton::getInstance;
};
END_NAMESPACE // FNV1a
END_NAMESPACE // Function
END_NAMESPACE // Hash
END_NAMESPACE // BusinessLogic
#endif // !FUNCTION_FNV1a_H
@@ -0,0 +1,25 @@
#ifndef CREATOR_FUNCTION_EQUIVALENT_H
#define CREATOR_FUNCTION_EQUIVALENT_H
#include "creatorOne.h"
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Hash)
BEGIN_NAMESPACE(Function)
BEGIN_NAMESPACE(Equivalent)
class Creator : public One::Creator
{
public:
virtual const Product &create() const override {
return Product::getInstance();
}
};
END_NAMESPACE // Equivalent
END_NAMESPACE // Function
END_NAMESPACE // Hash
END_NAMESPACE // BusinessLogic
#endif // !CREATOR_FUNCTION_EQUIVALENT_H
@@ -0,0 +1,27 @@
#ifndef CREATOR_FUNCTION_ONE_H
#define CREATOR_FUNCTION_ONE_H
#include "../creatorAbstract.h"
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Hash)
BEGIN_NAMESPACE(Function)
BEGIN_NAMESPACE(One)
class Creator : public Abstract::Creator
{
protected:
Creator()
{
}
public:
virtual const Product &create() const = 0;
};
END_NAMESPACE // One
END_NAMESPACE // Function
END_NAMESPACE // Hash
END_NAMESPACE // BusinessLogic
#endif // !CREATOR_FUNCTION_ONE_H
@@ -0,0 +1,24 @@
#ifndef CREATOR_FUNCTION_STANDART_H
#define CREATOR_FUNCTION_STANDART_H
#include "creatorOne.h"
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Hash)
BEGIN_NAMESPACE(Function)
BEGIN_NAMESPACE(Standart)
class Creator : public One::Creator
{
public:
virtual const Product &create() const override {
return Product::getInstance();
}
};
END_NAMESPACE // Standart
END_NAMESPACE // Function
END_NAMESPACE // Hash
END_NAMESPACE // BusinessLogic
#endif // !CREATOR_FUNCTION_FNV1a_H
@@ -0,0 +1,35 @@
#ifndef FUNCTION_EQUIVALENT_H
#define FUNCTION_EQUIVALENT_H
#include "one.h"
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Hash)
BEGIN_NAMESPACE(Function)
BEGIN_NAMESPACE(Equivalent)
using Singleton = BusinessLogic::Pattern::Singleton<Product>;
class Product final : public One::Product, public Singleton
{
private:
friend const Product &Singleton::getInstance();
Product() :
One::Product(
[](size_t value) -> size_t {
return value;
}
)
{
}
public:
using Singleton::getInstance;
};
END_NAMESPACE // Equivalent
END_NAMESPACE // Function
END_NAMESPACE // Hash
END_NAMESPACE // BusinessLogic
#endif // !FUNCTION_EQUIVALENT_H
@@ -0,0 +1,37 @@
#ifndef FUNCTION_ONE_H
#define FUNCTION_ONE_H
#include "../abstract.h"
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Hash)
BEGIN_NAMESPACE(Function)
BEGIN_NAMESPACE(One)
using function_type = std::function<size_t(size_t)>;
class Product : public Abstract::Product
{
protected:
const function_type m_function;
protected:
Product(const function_type& function) : m_function(function)
{
}
public:
const function_type& to_std() const {
return m_function;
}
size_t getHash(size_t value) const {
return m_function(value);
}
};
END_NAMESPACE // One
END_NAMESPACE // Function
END_NAMESPACE // Hash
END_NAMESPACE // BusinessLogic
#endif // !FUNCTION_ONE_H
@@ -0,0 +1,37 @@
#ifndef FUNCTION_STANDART_H
#define FUNCTION_STANDART_H
#include "one.h"
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Hash)
BEGIN_NAMESPACE(Function)
BEGIN_NAMESPACE(Standart)
using Singleton = BusinessLogic::Pattern::Singleton<Product>;
class Product final : public One::Product, public Singleton
{
private:
std::hash<size_t> m_standartHashFunction;
private:
friend const Product &Singleton::getInstance();
Product()
: One::Product(
std::bind(&std::hash<size_t>::operator(), &m_standartHashFunction, std::placeholders::_1)
)
, m_standartHashFunction()
{
}
public:
using Singleton::getInstance;
};
END_NAMESPACE // Standart
END_NAMESPACE // Function
END_NAMESPACE // Hash
END_NAMESPACE // BusinessLogic
#endif // !FUNCTION_FNV1a_H
@@ -0,0 +1,36 @@
#ifndef CREATOR_ADAPTER_FAMILY_TO_ONE_H
#define CREATOR_ADAPTER_FAMILY_TO_ONE_H
#include "familyToOne.h"
#include "../One/creatorOne.h"
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Hash)
BEGIN_NAMESPACE(Function)
BEGIN_NAMESPACE(Pattern)
BEGIN_NAMESPACE(FamilyToOne)
class Creator final : public One::Creator
{
private:
Product m_product; // To support the interface
public:
Creator(std::shared_ptr<Family::Creator> adaptee, size_t coefficient)
: m_product(adaptee->create(), coefficient)
{
}
public:
virtual const Product &create() const override {
return m_product;
}
};
END_NAMESPACE // FamilyToOne
END_NAMESPACE // Pattern
END_NAMESPACE // Function
END_NAMESPACE // Hash
END_NAMESPACE // BusinessLogic
#endif // !CREATOR_ADAPTER_FAMILY_TO_ONE_H
@@ -0,0 +1,30 @@
#ifndef ADAPTER_FAMILY_TO_ONE_H
#define ADAPTER_FAMILY_TO_ONE_H
#include "../Family/family.h"
#include "../One/one.h"
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Hash)
BEGIN_NAMESPACE(Function)
BEGIN_NAMESPACE(Pattern)
BEGIN_NAMESPACE(FamilyToOne)
class Product final : public One::Product
{
public:
Product(const Family::Product &adaptee, size_t coefficient)
: One::Product(
std::bind(adaptee.to_std(), std::placeholders::_1, coefficient)
)
{
}
};
END_NAMESPACE // FamilyToOne
END_NAMESPACE // Pattern
END_NAMESPACE // Function
END_NAMESPACE // Hash
END_NAMESPACE // BusinessLogic
#endif // !ADAPTER_FAMILY_TO_ONE_H
@@ -0,0 +1,30 @@
#ifndef FUNCTION_ABSTRACT_H
#define FUNCTION_ABSTRACT_H
#include "../../businessLogic.h"
#include "../../Pattern/singleton.h"
#include <memory>
#include <functional>
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Hash)
BEGIN_NAMESPACE(Function)
BEGIN_NAMESPACE(Abstract)
class Product
{
protected:
Product()
{
}
/* With the virtual destructor, the compiler considers this class to be polymorphic */
virtual ~Product() = default;
};
END_NAMESPACE // Abstract
END_NAMESPACE // Function
END_NAMESPACE // Hash
END_NAMESPACE // BusinessLogic
#endif // !FUNCTION_ABSTRACT_H
@@ -0,0 +1,27 @@
#ifndef CREATOR_FUNCTION_ABSTRACT_H
#define CREATOR_FUNCTION_ABSTRACT_H
#include "../../businessLogic.h"
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Hash)
BEGIN_NAMESPACE(Function)
BEGIN_NAMESPACE(Abstract)
class Creator
{
protected:
Creator()
{
}
public:
virtual const Product &create() const = 0;
};
END_NAMESPACE // Abstract
END_NAMESPACE // Function
END_NAMESPACE // Hash
END_NAMESPACE // BusinessLogic
#endif // !CREATOR_FUNCTION_ABSTRACT_H
@@ -0,0 +1,58 @@
#ifndef SUBSCRIBER_H
#define SUBSCRIBER_H
#include "../../../businessLogic.h"
#include <vector>
#include <string>
#include <algorithm>
#include <array>
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Hash)
BEGIN_NAMESPACE(Table)
BEGIN_NAMESPACE(Pattern)
class InterfaceSubscriber
{
public:
virtual void successfulInsertion(const Table::Abstract *, const std::array<char, 5> &, std::pair<size_t, size_t>, size_t) = 0;
virtual void unsuccessfulInsertion(const Table::Abstract *, const std::array<char, 5> &) = 0;
};
class Publisher
{
private:
std::vector<InterfaceSubscriber *> m_subscribers;
public:
virtual void signTheObject(InterfaceSubscriber *subscriber) {
if (subscriber not_eq nullptr) {
m_subscribers.push_back(subscriber);
}
}
virtual void unsubscribe(InterfaceSubscriber *subscriber) {
if (subscriber not_eq nullptr) {
m_subscribers.erase(std::find(m_subscribers.begin(), m_subscribers.end(), subscriber));
}
}
protected:
virtual void sendSuccessfulInsertion(const Table::Abstract *sender, const std::array<char, 5> &value, std::pair<size_t, size_t> index, size_t numberOfCollisions) const {
for (decltype(auto) currentSubscriber : m_subscribers) {
currentSubscriber->successfulInsertion(sender, value, index, numberOfCollisions);
}
}
virtual void sendUnseccessInsertion(const Table::Abstract *sender, const std::array<char, 5> &value) const {
for (decltype(auto) currentSubscriber : m_subscribers) {
currentSubscriber->unsuccessfulInsertion(sender, value);
}
}
};
END_NAMESPACE // Pattern
END_NAMESPACE // Table
END_NAMESPACE // Hash
END_NAMESPACE // BusinessLogic
#endif // SUBSCRIBER_H
@@ -0,0 +1,60 @@
#ifndef ABSTRACT_HASH_TABLE_H
#define ABSTRACT_HASH_TABLE_H
#include "../../businessLogic.h"
#include "../../Statistics/dispersion.h"
#include "Pattern/subscriber.h"
#include <vector>
#include <list>
#include <memory>
#include <functional>
#include <string>
#include <stdexcept>
#include <typeinfo>
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Hash)
BEGIN_NAMESPACE(Table)
class Abstract : public Pattern::Publisher
{
public:
using value_type = std::array<char, 5>;
using collision_container = BusinessLogic::Statistics::Dispersion::container_type;
protected: // Members
size_t m_numberOfBuckets;
size_t m_alphabetPower;
BusinessLogic::Statistics::Dispersion m_dispersion;
protected:
Abstract(size_t alphabetPower)
: m_numberOfBuckets(0)
, m_alphabetPower(alphabetPower)
{
}
Abstract(Abstract &&) = default;
Abstract &operator=(Abstract &&) = default;
Abstract(const Abstract &) = delete;
Abstract &operator=(const Abstract &) = delete;
public:
virtual bool isExist(const value_type &) const = 0;
virtual size_t size() const = 0;
virtual bool insert(const value_type &value) = 0;
virtual double simpleUniformHashingCoefficient() const = 0;
size_t alphabetPower() const {
return m_alphabetPower;
}
size_t numberOfBuckets() const {
return m_numberOfBuckets;
}
};
END_NAMESPACE // Table
END_NAMESPACE // Hash
END_NAMESPACE // BusinessLogic
#endif // ABSTRACT_HASH_TABLE_H
@@ -0,0 +1,93 @@
#ifndef CHAINS_HASH_TABLE_H
#define CHAINS_HASH_TABLE_H
#include "abstract.h"
#include "../../Convert/convert.h"
#include "../Function/One/one.h"
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Hash)
BEGIN_NAMESPACE(Table)
class Chains final : public Abstract
{
public: // Types
using container_type = std::vector<std::list<value_type>>;
using OFP_type = Function::One::Product;
using OFC_type = Function::One::Creator;
private:
BusinessLogic::Convert::FromStdString m_toInteger;
public:
container_type m_container;
const OFP_type &m_function;
Chains(size_t size, const OFC_type &function, size_t alphabetPower = std::numeric_limits<char>::max())
: Abstract(alphabetPower)
, m_function(function.create())
{
if (size == 0) {
size = 1;
}
/* The use of 'this' is mandatory */
this->m_container.resize(size);
}
private:
bool isExist(const value_type &value, size_t index) const {
const std::list<value_type> &currentList = m_container[index];
return std::find(currentList.cbegin(), currentList.cend(), value) not_eq currentList.cend();
}
public:
virtual bool isExist(const value_type &value) const override {
size_t size = this->size();
size_t index = m_function.getHash(m_toInteger(value, m_alphabetPower)) % size;
return isExist(value, index);
}
auto row(size_t index) const {
return m_container[index];
}
virtual size_t size() const override {
return m_container.size();
}
virtual bool insert(const value_type &value) override {
using namespace BusinessLogic::Statistics;
size_t index = m_function.getHash(m_toInteger(value, m_alphabetPower)) % this->size();
if( isExist(value, index) ) {
sendUnseccessInsertion(this, value);
return false;
}
try {
// List does not need a reserve
m_container[index].push_back(value);
}
catch (const std::bad_alloc &) {
sendUnseccessInsertion(this, value);
return false;
}
++m_numberOfBuckets;
size_t listLength = m_container[index].size();
sendSuccessfulInsertion(this, value, std::make_pair(index, listLength - 1), listLength - 1);
return true;
}
virtual double simpleUniformHashingCoefficient() const override {
size_t size = this->size();
collision_container container(size);
for(size_t i = 0; i < size; ++i) {
container[i] = m_container[i].size();
}
return m_dispersion(container, size);
}
};
END_NAMESPACE // Table
END_NAMESPACE // Hash
END_NAMESPACE // BusinessLogic
#endif // CHAINS_HASH_TABLE_H
@@ -0,0 +1,82 @@
#ifndef DIRECT_ADRESS_HASH_TABLE_H
#define DIRECT_ADRESS_HASH_TABLE_H
#include "../Factory/abstract.h"
#include "abstract.h"
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Hash)
BEGIN_NAMESPACE(Table)
class OpenAddressing final : public Abstract
{
public: // Types
using container_type = std::vector<value_type>;
using factory_type = Factory::Abstract;
private:
using sample_type = BusinessLogic::Statistics::Dispersion::container_type;
private:
friend factory_type::AAP_type;
container_type m_container;
collision_container m_numberOfCollision;
std::unique_ptr<Algorithm::Abstract::Product> m_algorithm;
public:
OpenAddressing(size_t size, const factory_type &factory, size_t alphabetPower = std::numeric_limits<char>::max())
: Abstract(alphabetPower)
, m_numberOfCollision(size, std::numeric_limits<size_t>::max())
, m_algorithm(factory.getAlgorithm())
{
constexpr std::array<char, 5> nullValue = {'\0', '\0', '\0', '\0', '\0'};
m_container.resize(size, nullValue);
m_algorithm->setTable(&m_container);
}
public:
virtual bool isExist(const value_type &value) const override {
size_t numberOfCollisions = 0;
size_t index = (*m_algorithm).getIndex(value, numberOfCollisions, m_alphabetPower);
return ( index != std::numeric_limits<size_t>::max() )
|| ( (m_container.begin() + index).operator*() == value );
}
virtual size_t size() const override {
return m_container.size();
}
virtual bool insert(const value_type &value) override {
using namespace BusinessLogic::Statistics;
size_t size = m_container.size();
if ( m_numberOfBuckets == size) {
sendUnseccessInsertion(this, value);
return false;
}
size_t numberOfCollisions = 0;
size_t index = (*m_algorithm).getIndex(value, numberOfCollisions, m_alphabetPower);
if (index == std::numeric_limits<size_t>::max()
|| (m_container.begin() + index).operator*() == value
) {
sendUnseccessInsertion(this, value);
return false;
}
m_container[index] = value;
m_numberOfCollision[m_numberOfBuckets] = numberOfCollisions;
++m_numberOfBuckets;
sendSuccessfulInsertion(this, value, std::make_pair(index, 0), numberOfCollisions);
return true;
}
virtual double simpleUniformHashingCoefficient() const override {
return m_dispersion(m_numberOfCollision, m_numberOfBuckets);
}
};
END_NAMESPACE // Table
END_NAMESPACE // Hash
END_NAMESPACE // BusinessLogic
#endif // DIRECT_ADRESS_HASH_TABLE_H
@@ -0,0 +1,37 @@
#ifndef SINGLETON_H
#define SINGLETON_H
#include "../businessLogic.h"
#include <memory>
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Pattern)
template <typename T>
class Singleton {
private:
static std::unique_ptr<T> m_singleton;
public:
static const T &getInstance() {
if (m_singleton == nullptr) {
m_singleton = std::unique_ptr<T>(new T);
}
return m_singleton.operator*();
}
Singleton() = default;
Singleton(const Singleton &) = delete;
Singleton(Singleton &&) = delete;
Singleton &operator=(const Singleton &) = delete;
Singleton &operator=(Singleton &&) = delete;
};
template<typename T>
std::unique_ptr<T> Singleton<T>::m_singleton = nullptr;
END_NAMESPACE // Pattern
END_NAMESPACE // BusinessLogic
#endif // SINGLETON_H
@@ -0,0 +1,18 @@
#include "dispersion.h"
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Statistics)
long double Dispersion::operator()(const container_type &container, size_t size) const {
long double average = 0;
long double averageOfSquares = 0;
for(size_t i = 0; i < size; ++i) {
average += ( container[i] ) / static_cast<long double>(size);
averageOfSquares += ( container[i] ) * ( container[i] ) / static_cast<long double>(size);
}
return averageOfSquares - average * average;
}
END_NAMESPACE // Statistics
END_NAMESPACE // BusinessLogic
@@ -0,0 +1,25 @@
#ifndef DISPERSION_H
#define DISPERSION_H
#include "../businessLogic.h"
#include <vector>
#include <algorithm>
#include <functional>
BEGIN_NAMESPACE(BusinessLogic)
BEGIN_NAMESPACE(Statistics)
class Dispersion {
public: // Types
using value_type = size_t;
using container_type = std::vector<value_type>;
public:
long double operator()(const container_type &container, size_t size) const;
};
END_NAMESPACE // Statistics
END_NAMESPACE // BusinessLogic
#endif // DISPERSION_H
+102
View File
@@ -0,0 +1,102 @@
#ifndef BUSINESS_LOGIC_H
#define BUSINESS_LOGIC_H
/* Opening bracket */
#define OPEN {
/* Closing bracket */
#define CLOSE }
/* Begin of namespace */
#define BEGIN_NAMESPACE(name) \
namespace name OPEN
/* Begin of namespace */
#define END_NAMESPACE \
CLOSE
/* Declaring classes of factory method */
#define DFM_TYPES \
class Product; \
class Creator;
/* Factory method namespace declaration */
#define DFM_NAMESPACE(name) \
BEGIN_NAMESPACE(name) \
DFM_TYPES \
END_NAMESPACE
/* Factory method base cod declaration */
#define DFM_BASE \
DFM_NAMESPACE(Abstract) \
DFM_NAMESPACE(One) \
DFM_NAMESPACE(Family)
namespace BusinessLogic
{
namespace Hash
{
namespace Function
{
DFM_BASE
DFM_NAMESPACE(FNV1a)
DFM_NAMESPACE(Standart)
DFM_NAMESPACE(Equivalent)
namespace Pattern
{
DFM_NAMESPACE(FamilyToOne)
}
}
namespace Algorithm
{
DFM_BASE
DFM_NAMESPACE(LinearProbing)
DFM_NAMESPACE(QuadraticProbing)
DFM_NAMESPACE(PseudorandomProbing)
DFM_NAMESPACE(DoubleHashing)
}
namespace Factory
{
class Abstract;
class One;
class Family;
}
namespace Table /* Only string data */
{
class Abstract;
class OpenAddressing; // Direct address hash function
class Chains; // Hash function implemented by the chain method
namespace Pattern
{
class InterfaceSubscriber;
class Publisher;
}
}
}
namespace Pattern // Can be used for different classes
{
template<typename T>
class Singleton;
}
namespace Convert
{
class FromStdString;
}
namespace Statistics
{
class Dispersion;
}
}
#endif // BUSINESS_LOGIC_H
+197
View File
@@ -0,0 +1,197 @@
#include "hashHeaderFiles.h"
#include <iostream>
#include <string>
#include <ctime>
#include <initializer_list>
#include <tuple>
#include <array>
#include "Convert/convert.h"
using namespace BusinessLogic::Hash;
using namespace Function::Pattern;
using namespace Table::Pattern;
using factory_ptr = std::shared_ptr<const Factory::Abstract>;
class Subscriber : public InterfaceSubscriber {
private:
clock_t m_time;
size_t m_maxCollision;
size_t m_numberOfSuccesses;
size_t m_numberOfFailures;
size_t m_target;
long double m_lastCoefficients;
public:
Subscriber(size_t target)
: m_maxCollision(0)
, m_numberOfSuccesses(0)
, m_numberOfFailures(0)
, m_target(target)
, m_lastCoefficients(0)
{
}
void startTime() {
m_time = clock();
}
void endTime() {
m_time = clock() - m_time;
}
double lastCoefficient() const {
return m_lastCoefficients;
}
double workingTime() const {
return m_time / static_cast<double>(CLOCKS_PER_SEC);
}
size_t maxCollision() const {
return m_maxCollision;
}
auto numberOfSuccesses() const {
return m_numberOfSuccesses;
}
auto numberOfFailures() const {
return m_numberOfFailures;
}
virtual void successfulInsertion(const Table::Abstract *table, const std::array<char, 5> &, std::pair<size_t, size_t>, size_t numberOfCollisions) override {
m_maxCollision = {
numberOfCollisions > m_maxCollision
? numberOfCollisions
: m_maxCollision
};
++m_numberOfSuccesses;
if(m_numberOfSuccesses + m_numberOfFailures >= m_target) {
m_lastCoefficients = table->simpleUniformHashingCoefficient();
}
}
virtual void unsuccessfulInsertion(const Table::Abstract *, const std::array<char, 5> &) override {
++m_numberOfFailures;
}
virtual void filledInPart(const Table::Abstract *) override {
m_lastCoefficients = 0;
}
};
void runTable(std::unique_ptr<Table::Abstract> table, size_t target) {
/* 26 letters */
constexpr char firstChar = ' ';
constexpr char endChar = '~';
size_t progress = 0;
std::array<char, 5> currentString = { ' ', ' ', ' ', ' ', ' ' };
bool continueFlag = true;
while (continueFlag) {
if (++progress > target || not table->insert(currentString)) {
continueFlag = false;
}
currentString[4] < endChar ? ++currentString[4]
: (currentString[4] = firstChar, currentString[3] < endChar) ? ++currentString[3]
: (currentString[3] = firstChar, currentString[2] < endChar) ? ++currentString[2]
: (currentString[2] = firstChar, currentString[1] < endChar) ? ++currentString[1]
: (currentString[1] = firstChar, currentString[0] < endChar) ? ++currentString[0]
: (continueFlag = false);
}
}
int main(int /*argc*/, char **/*argv*/)
{
auto fnv1a = std::make_shared<Function::FNV1a::Creator>();
auto equivalent = std::make_shared<Function::Equivalent::Creator>();
auto standart = std::make_shared<Function::Standart::Creator>();
auto doubleHashing = std::make_shared<Algorithm::DoubleHashing::Creator>(0, 1);
auto pseudorandomProbing = std::make_shared<Algorithm::PseudorandomProbing::Creator>(0);
auto linearProbing = std::make_shared<Algorithm::LinearProbing::Creator>();
auto quadraticProbing = std::make_shared<Algorithm::QuadraticProbing::Creator>();
/* First Hash Function has a number 0, second - 1 */
const Factory::Abstract &fac1 { Factory::Family(fnv1a, doubleHashing) };
const Factory::Abstract &fac2 { Factory::Family(fnv1a, pseudorandomProbing) };
const Factory::Abstract &fac3 { Factory::One(equivalent, linearProbing) };
const Factory::Abstract &fac4 { Factory::One(equivalent, quadraticProbing) };
const Factory::Abstract &fac5 { Factory::One(standart, linearProbing) };
const Factory::Abstract &fac6 { Factory::One(standart, quadraticProbing) };
auto simpleFNV1a = std::make_shared<FamilyToOne::Creator>(fnv1a, 0);
const Factory::Abstract &fac7 { Factory::One(simpleFNV1a, linearProbing) };
const Factory::Abstract &fac8 { Factory::One(simpleFNV1a, quadraticProbing) };
/* 0x5 == 0b0101 */
auto complicatedFNV1a = std::make_shared<FamilyToOne::Creator>(fnv1a, 0x55555555);
const Factory::Abstract &fac9 { Factory::One(complicatedFNV1a, linearProbing) };
const Factory::Abstract &fac10 { Factory::One(complicatedFNV1a, quadraticProbing) };
/*
* Constants
*/
constexpr size_t numberOfInserts = (
//11
//101
//5'003
//50'021
//230'003
//456'959
//1'000'003
//5'000'011
//10'000'019
10'000'019
); // Must be simple - max is 10'371'957'246
constexpr size_t quantityOfTables = 14;
constexpr size_t numberOfBins = numberOfInserts / 10;
constexpr size_t alphabetPower = '~' - ' ' + 1;
constexpr double alpha = 0.9;
std::array<std::shared_ptr<Subscriber>, quantityOfTables> results;
for(std::shared_ptr<Subscriber> &current : results) {
current = std::make_shared<Subscriber>(static_cast<size_t>(numberOfInserts * alpha));
}
/*
* Constants
*/
std::array<std::unique_ptr<Table::Abstract>, quantityOfTables> tables {
std::unique_ptr<Table::Abstract>( new Table::OpenAddressing(numberOfInserts, fac1, alphabetPower) ),
std::unique_ptr<Table::Abstract>( new Table::OpenAddressing(numberOfInserts, fac2, alphabetPower) ),
std::unique_ptr<Table::Abstract>( new Table::OpenAddressing(numberOfInserts, fac3, alphabetPower) ),
std::unique_ptr<Table::Abstract>( new Table::OpenAddressing(numberOfInserts, fac4, alphabetPower) ),
std::unique_ptr<Table::Abstract>( new Table::OpenAddressing(numberOfInserts, fac5, alphabetPower) ),
std::unique_ptr<Table::Abstract>( new Table::OpenAddressing(numberOfInserts, fac6, alphabetPower) ),
std::unique_ptr<Table::Abstract>( new Table::OpenAddressing(numberOfInserts, fac7, alphabetPower) ),
std::unique_ptr<Table::Abstract>( new Table::OpenAddressing(numberOfInserts, fac8, alphabetPower) ),
std::unique_ptr<Table::Abstract>( new Table::OpenAddressing(numberOfInserts, fac9, alphabetPower) ),
std::unique_ptr<Table::Abstract>( new Table::OpenAddressing(numberOfInserts, fac10, alphabetPower) ),
std::unique_ptr<Table::Abstract>( new Table::Chains (numberOfBins, *equivalent, alphabetPower) ),
std::unique_ptr<Table::Abstract>( new Table::Chains (numberOfBins, *standart, alphabetPower) ),
std::unique_ptr<Table::Abstract>( new Table::Chains (numberOfBins, *simpleFNV1a, alphabetPower) ),
std::unique_ptr<Table::Abstract>( new Table::Chains (numberOfBins, *complicatedFNV1a, alphabetPower) )
};
std::cout << std::fixed;
std::cout.precision(10);
std::cout << "START!" << std::endl;
for(size_t i = 0; i < quantityOfTables; ++i) {
tables[i]->signTheObject( &results[i].operator*() );
results[i]->startTime();
runTable(std::move(tables[i]), numberOfInserts * alpha);
results[i]->endTime();
std::cout
<< results[i]->maxCollision() << ' '
<< std::sqrt(results[i]->lastCoefficient()) << ' '
<< results[i]->numberOfSuccesses() << '/'
<< alpha << '/'
<< numberOfInserts << ' '
<< results[i]->workingTime() << std::endl;
}
std::cout << "END!" << std::endl;
}
@@ -0,0 +1,32 @@
#ifndef HASH_HEADER_FILES_H
#define HASH_HEADER_FILES_H
#include "Statistics/dispersion.h"
#include "Hash/Algorithm/One/linearProbing.h"
#include "Hash/Algorithm/One/quadraticProbing.h"
#include "Hash/Algorithm/Family/pseudorandomProbing.h"
#include "Hash/Algorithm/Family/doubleHashing.h"
#include "Hash/Function/Family/fnv1a.h"
#include "Hash/Function/One/standart.h"
#include "Hash/Function/One/equivalent.h"
#include "Hash/Function/Pattern/familyToOne.h"
#include "Hash/Algorithm/One/creatorLinearProbing.h"
#include "Hash/Algorithm/One/creatorQuadraticProbing.h"
#include "Hash/Algorithm/Family/creatorPseudorandomProbing.h"
#include "Hash/Algorithm/Family/creatorDoubleHashing.h"
#include "Hash/Function/Family/creatorFnv1a.h"
#include "Hash/Function/One/creatorStandart.h"
#include "Hash/Function/One/creatorEquivalent.h"
#include "Hash/Function/Pattern/creatorFamilyToOne.h"
#include "Hash/Factory/one.h"
#include "Hash/Factory/family.h"
#include "Hash/Table/chains.h"
#include "Hash/Table/openAddress.h"
#endif // HASH_HEADER_FILES_H
Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

@@ -0,0 +1,84 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Demonstration</title>
</head>
<body>
<h2 style="text-align: center">Руководство пользователя</h2>
<h3 style="text-align: center">Система демонстрации</h3>
<p style="text-align: justify">
Данный раздел - описание существующих возможностей взаимодействия с
системой демонстрации изученного материала.<br />
На рисунке 3.1 виден весь основной интерфейс пользователя, необходимый для
полноценного комфортного взаимодействия с данной системой.
</p>
<div style="text-align: center">
<img src="demonstration.png" />
<p style="text-align: center">
Рисунок 2.1 - система демонстрации вставки элемента в хеш-таблицу
</p>
</div>
<p style="text-align: justify">
Каждая цифра указывает на определённый интерфейс пользователя, где даётся
его описание:
</p>
<ol>
<li style="text-align: justify">
Табличное представление модели, которое&nbsp;заполняется ранее
вставленными в хеш-таблицу элементами в порядке их хранения в самой
хей-таблице.
</li>
<li style="text-align: justify">
График, показывающий тенденцию изменения коэффициента простого
равномерного хеширования на протяжении процесса вставки элементов в
хеш-таблицу.
</li>
<li style="text-align: justify">
График, показывающий тенденцию изменения количества коллизий&nbsp;на
протяжении процесса вставки элементов в хеш-таблицу.
</li>
<li style="text-align: justify">
Группирующий блок, позволяющий изменять способ решения проблем
коллизий&nbsp;хеш-таблицы.
</li>
<li style="text-align: justify">
Группирующий блок, позволяющий изменять применяемую в процессе вставки
элемента хеш-функцию.
</li>
<li style="text-align: justify">
Группирующий блок, позволяющий изменять применяемую в процессе вставки
элемента&nbsp;алгоритм, применяемый в попытке решения колизии на основе
таблицы с открытой адрессацией.
</li>
<li style="text-align: justify">
Сгруппированный интерфейс, позволяющий создать новую хеш-таблицу с
указанием размера первоначального контейнера, сбросить действительную
хеш-таблицу, запросить последнюю статистику по операциям вставки
элементов
</li>
<li style="text-align: justify">
Сгруппированный интерфейс, позволяющий создавать инструкции по вставке
новых элементов в хеш таблицу несколькими способами: n-ое количество
элементов разных элементов и один единственный, где задаётся первый
элемент. Так же существует возможность поиска первого несуществующего
элемента хеш-таблице, остановки процесса вставки элементов в
хеш-таблцицу, фокусирования графиков для полного отображения информации.
Каждая функция соответствует своей кнопке данного сгруппированного
интерфейса.
</li>
<li style="text-align: justify">
Вывод информации о действиях пользователя и результатах хеширования
элементов.
</li>
<li style="text-align: justify">
Масштабирование всех видов, вплоть до освобождения места для
определённого вида с целью его более детального рассмотрения.
Существвует возможность полного масштабирования одного вида, взамен
скрытия всех остальных.
</li>
</ol>
</body>
</html>
+33
View File
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Main</title>
</head>
<body>
<h2 style="text-align: center">Руководство пользователя</h2>
<h3 style="text-align: center">
Предоставление помощи пользователю<br />
в использовании демонстрационной программы:<br />
&quot;Алгоритм вставки в хеш-таблицу&quot;
</h3>
<p style="text-align: justify;">
Данное руководство предназначено пользователю для лучшего понимания работы
программы и взаимодействия с ней.
</p>
<p>Оглавление:</p>
<ol>
<li>
<a href="theoryPage.html">Раздел теории</a>
<ul>
<li><a href="theory.html">Теория</a></li>
<li><a href="demonstration.html">Демонстрация</a></li>
</ul>
</li>
<li><a href="testingPage.html">Раздел тестирования</a></li>
<li><a href="menubar.html">Полоса или строка меню</a></li>
</ol>
</body>
</html>
+57
View File
@@ -0,0 +1,57 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Menubar</title>
</head>
<body>
<h2 style="text-align: center">Руководство пользователя</h2>
<h3 style="text-align: center">Полоска или строка меню</h3>
<p style="text-align: justify">
Данный раздел - описание существующих возможностей взаимодействия с
посолкой или строкой меню данной программы.<br />
На рисунке 5.1 и 5.2 отображены подменю, каждое из которых группирует
определённые действия.
</p>
<div style="text-align: center">
<img src="menubarFirst.png" />
<p style="text-align: center">
Рисунок 5.1 - подменю выбора текущего раздела
</p>
<p style="text-align: center">
<img src="menubarSecond.png" />
</p>
<p>Рисунок 5.2 - подменю предоставления помощи</p>
</div>
<p style="text-align: justify">
<span style="text-align: center"
>Первое подменю (см. рис. 5.1) необходимо для переключения разделов -
раздел теории, который включает две системы (система теории и система
демонстрации) и раздел тестирования.</span
>
</p>
<p style="text-align: justify">
Каждая цифра указывает на определённый интерфейс пользователя, где даётся
его описание:
</p>
<ol>
<li style="text-align: justify">
Действие подменю, необходимое для переключения вида на раздел теории.
</li>
<li style="text-align: justify">
Действие подменю, необходимое для переключения вида на раздел практики.
</li>
<li style="text-align: justify">
Действие подменю, необходимое для открытия модального диалогового окна -
руководства пользователя.
</li>
<li style="text-align: justify">
Действие подменю, необходимое для открытия модального диалогового окна,
которое содержит информацию об использующимся&nbsp;программой фреймворке
Qt.
</li>
</ol>
</body>
</html>
@@ -0,0 +1,67 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>PracticPage</title>
</head>
<body>
<h2 style="text-align: center">Руководство пользователя</h2>
<h3 style="text-align: center">Система тестирования</h3>
<p style="text-align: justify">
Данный раздел - описание существующих возможностей взаимодействия с
системой тестирования.<br />
На рисунке 4.1 виден весь основной интерфейс пользователя, необходимый для
полноценного комфортного взаимодействия с данной системой.
</p>
<div style="text-align: center">
<img src="testingPage.html" />
<p style="text-align: center">Рисунок 4.1 - система тестирования</p>
</div>
<p style="text-align: justify">
Каждая цифра указывает на определённый интерфейс пользователя, где даётся
его описание:
</p>
<ol>
<li style="text-align: justify">
Отображаемый текст, как текущий вопрос с описанием ввода правильного
ответа и самого тестового задания.
</li>
<li style="text-align: justify">
Панель ввода правильного ответа. Может представлять
определённое&nbsp;количество&nbsp;флагов для указания множественного
ответа из множества альтернатив (от 5-и до 9-и),&nbsp;поле ввода целого
числа или&nbsp;числа с плавающей точкой.
</li>
<li style="text-align: justify">
Нажимная кнопка для подтверждения ответа и проверки его на корректность.
</li>
<li style="text-align: justify">
Выходная информация, как способ идентификации успешного / безуспешного
начала тестирования с указанием конкретной ошибки, завершения
тестирования и успешного / безуспешного ответа на предыдущий вопрос.
</li>
<li style="text-align: justify">
Нажимная кнопка, реализующая начало тестирования.
</li>
<li style="text-align: justify">
Нажимная кнопка, реализующая предварительное завершение тестирования.
</li>
<li style="text-align: justify">
Группирующий интерфейс необходимый для выбора типа предоставляемых
вопросов в процессе тестирования.
</li>
<li style="text-align: justify">
Группирующий интерфейс&nbsp;необходимый для выбора сложности
предоставляемых вопросов в процессе тестирования.
</li>
</ol>
<p style="text-align: justify">
Стоит отметить, что результат тестирования сохраняется в бинарном файле
(формат записи смотри в технической документации), когда тестирование
завершается после окончания подходящих под критерии вопросов или решения
пользователя, при нажатии соответствующей кнопки.
</p>
</body>
</html>
+63
View File
@@ -0,0 +1,63 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Theory</title>
</head>
<body>
<h2 style="text-align: center">Руководство пользователя</h2>
<h3 style="text-align: center">Система теории</h3>
<p style="text-align: justify">
Данный раздел - описание существующих возможностей взаимодействия с
системой изучения теоретического материала.<br />
На рисунке 2.1 виден весь основной интерфейс пользователя, необходимый для
полноценного комфортного взаимодействия с данной системой.
</p>
<div style="text-align: center">
<img src="theory.png" />
<p style="text-align: center">
Рисунок 2.1 - система изучения теоретического материала
</p>
</div>
<p style="text-align: justify">
Каждая цифра указывает на определённый интерфейс пользователя, где даётся
его описание:
</p>
<ol>
<li style="text-align: justify">
Нажимная кнопка, при нажатии которой пользователь переходит на следующую
страницу теоретического материала. Доступна, если отображается не
главная и не последняя страницы.
</li>
<li style="text-align: justify">
Нажимная кнопка, при нажатии которой пользователь переходит на главную
страницу теоретического материала. Доступна, если не отображается
главная страница.
</li>
<li style="text-align: justify">
Нажимная кнопка, при нажатии которой пользователь переходит на
предыдущую страницу теоретического материала. Доступна, если
отображается не главная и не первая страницы.
</li>
<li style="text-align: justify">
Нажимная кнопка, позволяющая&nbsp;отобразить предыдущую небольшую
доступную часть отображаемой страницы.
</li>
<li style="text-align: justify">
Ползунок, при перемещении которого можно перейти к любой части
отображаемой страницы.
</li>
<li style="text-align: justify">
Нажимная кнопка, позволяющая отобразить следующую&nbsp;небольшую
доступную&nbsp;часть отображаемой страницы.
</li>
<li style="text-align: justify">
Гиперссылка оглавления, при нажатии на которую пользователь может
перейти к любой интересующей его теме, которая описывается в отдельной
страцице.
</li>
</ol>
</body>
</html>
@@ -0,0 +1,50 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>TheoryPage</title>
</head>
<body>
<h2 style="text-align: center">Руководство пользователя</h2>
<h3 style="text-align: center">Раздел теории</h3>
<p style="text-align: justify">
Данный раздел - первое, что видит пользователь, при первом запуске
программы.<br />
На рисунке 1.1 виден весь основной интерфейс пользователя, необходимый для
перехода в ту или иную систему.
</p>
<div style="text-align: center">
<img src="theoryPage.png"/>
<p style="text-align: center">Рисунок 1.1 - раздел теории и практики</p>
</div>
<p>Всего существует три системы:</p>
<ul>
<li style="text-align: justify">Теории.</li>
<li style="text-align: justify">Демонстрации.</li>
<li style="text-align: justify">Тестирования.</li>
</ul>
<p style="text-align: justify">
Основой графического интерфейса пользователя являются нажимаемые кнопки,
переключающие между собой вкладки, флажки множественного или одиночного
выборов, и другие элементы, которые будут обсуждаться по мере описания
данного руководства. Каждая цифра указывает на определённый интерфейс
пользователя, где даётся его описание:
</p>
<ol>
<li style="text-align: justify">
Раздел изучения теоретического материала, необходимый для понимания темы
&quot;Алгоритм вставки элемента в хеш-таблицу&quot;.
</li>
<li style="text-align: justify">
Раздел демонстрации вставки элемента в хеш-таблицу.&nbsp;
</li>
<li style="text-align: justify">
Полоса или строка меню, как единственный способ переключения фокуса
между системами теории, которая&nbsp;подразумевает включение системы
демонстрации, и тестирования.
</li>
</ol>
</body>
</html>
+13
View File
@@ -0,0 +1,13 @@
<?xml version="1.0"?>
<info>
<directory>:/ManualHTML/Pages</directory>
<directory>:/ManualHTML/Images</directory>
<order>
<page>main.html</page>
<page>theoryPage.html</page>
<page>theory.html</page>
<page>demonstration.html</page>
<page>testingPage.html</page>
<page>menubar.html</page>
</order>
</info>
@@ -0,0 +1,21 @@
#ifndef LATIN_VALIDATOR_H
#define LATIN_VALIDATOR_H
#include <QValidator>
class LatinValidator : public QValidator {
public:
LatinValidator(QObject *parent) : QValidator(parent)
{
}
virtual State validate(QString& str, int&) const override {
QRegExp rxp = QRegExp("[!-~]*");
if (str.contains(rxp)) {
return Acceptable;
}
return Invalid;
}
};
#endif // LATIN_VALIDATOR_H
@@ -0,0 +1,564 @@
#include "demonstrationWidget.h"
inline void DemonstrationWidget::TableInformation::clear() {
for (size_t *value :
{&m_maxCollision, &m_numberOfSuccesses, &m_numberOfFailures}) {
*value = 0;
}
for (double *value : {&m_lastCoefficient, &m_maxCoefficient}) {
*value = 0;
}
for (auto *series : {m_pSeriesNumberOfCollisions}) {
series->removePoints(0, series->count());
}
m_pSeriesNumberOfCollisions->append(0, 0);
m_lastCoord = {0, 0};
m_lastValue = {'\0', '\0', '\0', '\0', '\0'};
m_lastInsertion = false;
}
DemonstrationWidget::DemonstrationWidget(QWidget *pWidget)
: QWidget(pWidget),
m_pChartCollisionsView(new QChartView(new QChart, this)),
m_pStandardModel(nullptr), m_stop(false), m_pFunction(nullptr),
m_complicatedFunction(nullptr), m_pAlgorithm(nullptr),
m_alphabetPower(endChar - firstChar + 1), m_pTable(nullptr),
m_tableInformation(new QLineSeries(m_pChartCollisionsView->chart())) {
setupUi(dynamic_cast<QWidget *>(this));
m_tableView->horizontalHeader()->setSectionResizeMode(
QHeaderView::ResizeToContents);
QGridLayout *gridLayout = new QGridLayout;
/*
* Сhart
*/
auto *axisX = new QValueAxis();
auto *axisY = new QValueAxis();
axisX->setTickCount(20);
axisY->setTickCount(10);
axisX->setRange(1, 2);
axisY->setRange(0, 1);
QChart *chartCollision = m_pChartCollisionsView->chart();
chartCollision->setTitle("Graph of collision changes");
chartCollision->legend()->hide();
chartCollision->addAxis(axisX, Qt::AlignBottom);
chartCollision->addAxis(axisY, Qt::AlignLeft);
chartCollision->addSeries(m_tableInformation.m_pSeriesNumberOfCollisions);
m_tableInformation.m_pSeriesNumberOfCollisions->attachAxis(axisX);
m_tableInformation.m_pSeriesNumberOfCollisions->attachAxis(axisY);
/*
* View(-s)
*/
m_pChartCollisionsView->installEventFilter(this);
m_pChartCollisionsView->setRubberBand(QChartView::RectangleRubberBand);
m_pChartCollisionsView->setRenderHint(QPainter::Antialiasing);
m_pChartCollisionsView->setMinimumHeight(m_tableView->minimumHeight());
m_pChartCollisionsView->setMinimumWidth(m_tableView->minimumWidth());
/*
* Splitter
*/
QSplitter *splitter = new QSplitter(Qt::Vertical);
splitter->addWidget(m_tableView);
splitter->addWidget(m_pChartCollisionsView);
gridLayout->addWidget(splitter, 0, 0, 1, 1);
gridLayout->addWidget(m_rightScrollArea, 0, 1, 1, 1);
gridLayout->addWidget(m_frmProgressBar, 1, 0, 1, 2);
setLayout(gridLayout);
/*
* Validator and HTML theory
*/
m_leFrom->setValidator(new LatinValidator(m_leFrom));
m_leInsert->setValidator(new LatinValidator(m_leInsert));
/*
* Signal & slots
*/
connect(m_pbReset, &QPushButton::clicked, this,
&DemonstrationWidget::slotClickedReset);
connect(m_pbApply, &QPushButton::clicked, this,
&DemonstrationWidget::slotClickedApply);
connect(m_pbStatistics, &QPushButton::clicked, this,
&DemonstrationWidget::slotClickedStatistics);
connect(m_pbMakeItems, &QPushButton::clicked, this,
&DemonstrationWidget::slotClickedMakeItems);
connect(m_pbInsert, &QPushButton::clicked, this,
&DemonstrationWidget::slotClickedInsert);
connect(m_pbFindFree, &QPushButton::clicked, this,
&DemonstrationWidget::slotClickedFindFree);
connect(m_pbStop, &QPushButton::clicked, this,
&DemonstrationWidget::slotClickedStop);
connect(m_pbFocus, &QPushButton::clicked, this,
&DemonstrationWidget::slotClickedFocus);
connect(m_rbFNV1a32bit, &QRadioButton::toggled, this,
&DemonstrationWidget::slotUpdateAdditionalInputData);
connect(m_rbPseudorandomProbing, &QRadioButton::toggled, this,
&DemonstrationWidget::slotUpdateAdditionalInputData);
connect(m_rbDoubleHashing, &QRadioButton::toggled, this,
&DemonstrationWidget::slotUpdateAdditionalInputData);
connect(m_rbChains, &QRadioButton::toggled, this,
&DemonstrationWidget::slotUpdateAdditionalInputData);
/*
* GUI
*/
m_frmProgressBar->hide();
m_frmFirstInputData->hide();
m_frmSecondInputData->hide();
m_gbInputData->hide();
}
/*
* Inserting elements
*/
void DemonstrationWidget::successfulInsertion(const table_type *,
const value_type &value,
std::pair<size_t, size_t> index,
size_t numberOfCollisions) {
m_tableInformation.m_lastCoord = index;
m_tableInformation.m_lastValue = value;
m_tableInformation.m_lastInsertion = true;
++m_tableInformation.m_numberOfSuccesses;
m_tableInformation.m_lastCollision = numberOfCollisions;
m_tableInformation.m_maxCollision = {numberOfCollisions >
m_tableInformation.m_maxCollision
? numberOfCollisions
: m_tableInformation.m_maxCollision};
m_tableInformation.m_lastCollision = numberOfCollisions;
if (numberOfCollisions > m_tableInformation.m_maxCollision) {
m_tableInformation.m_maxCollision = numberOfCollisions;
}
m_tableInformation.m_pSeriesNumberOfCollisions->append(
m_tableInformation.m_numberOfSuccesses, numberOfCollisions);
QModelIndex modelIndex = m_pStandardModel->index(index.first, index.second);
if (getCurrentTableType() == TableType::Chain) {
updateColumns(index.first);
} else {
m_pStandardModel->setData(modelIndex, QVariant(toQString(value)));
}
}
void DemonstrationWidget::unsuccessfulInsertion(const table_type *,
const value_type &value) {
m_tableInformation.m_lastValue = value;
m_tableInformation.m_lastInsertion = false;
++m_tableInformation.m_numberOfFailures;
}
inline void DemonstrationWidget::updateColumns(size_t rowIndex) {
using namespace BusinessLogic::Hash::Table;
auto tableRow =
dynamic_cast<BusinessLogic::Hash::Table::Chains *>(m_pTable.get())
->row(rowIndex);
size_t modelColumnCount = m_pStandardModel->columnCount();
size_t tableColumnCount = tableRow.size();
if (modelColumnCount < tableColumnCount) {
m_pStandardModel->insertColumns(
modelColumnCount,
std::max(tableColumnCount - modelColumnCount,
static_cast<size_t>(std::ceil(
std::sqrt(m_tableInformation.m_lastCoefficient)))));
}
QModelIndex modelIndex;
auto iterator = tableRow.begin();
for (size_t i = 0, size = tableRow.size(); i < size; ++i, ++iterator) {
modelIndex = m_pStandardModel->index(rowIndex, i);
m_pStandardModel->setData(modelIndex, QVariant(toQString(*iterator)));
}
}
inline void DemonstrationWidget::updateCharts() {
m_pChartCollisionsView->chart()
->axes(Qt::Horizontal)
.front()
->setRange(1, m_tableInformation.m_numberOfSuccesses);
m_pChartCollisionsView->chart()
->axes(Qt::Vertical)
.front()
->setRange(0, m_tableInformation.m_maxCollision);
m_pChartCollisionsView->chart()->resetMatrix();
}
inline void DemonstrationWidget::updateTableView() {
m_tableView->scrollTo(
m_pStandardModel->index(m_tableInformation.m_lastCoord.first,
m_tableInformation.m_lastCoord.second),
QAbstractItemView::PositionAtCenter);
m_tableView->repaint();
}
inline DemonstrationWidget::value_type &
DemonstrationWidget::next(value_type &value) const {
auto rbegin = value.rbegin();
auto rend = value.rend();
for (; rbegin != rend; ++rbegin) {
if (*rbegin >= firstChar && *rbegin < endChar) {
++(*rbegin);
return value;
} else if (*rbegin == '\0') {
*rbegin = firstChar;
return value;
} else {
*rbegin = firstChar;
}
}
value = toStdArray(std::string(4, '\0') + firstChar);
return value;
}
inline bool DemonstrationWidget::checkBeforeInsertion(bool tableTypeIsChain) {
size_t quantityOfInserts = m_sbQuantity->value();
if (tableTypeIsChain &&
(m_pTable->numberOfBuckets() + quantityOfInserts) / m_pTable->size() >
10) {
outputMessage(
"Prohibit insertion when allocating more than 10 elements per chain",
"red");
return false;
}
return true;
}
inline void DemonstrationWidget::slotClickedMakeItems() {
using namespace BusinessLogic::Convert;
bool tableTypeIsChain = getCurrentTableType() == TableType::Chain;
if (not checkBeforeInsertion(tableTypeIsChain)) {
return;
}
/*
* Preparing
*/
if (tableTypeIsChain && m_pStandardModel->columnCount() == 0) {
m_pStandardModel->insertColumns(0, m_sbQuantity->value() /
m_sbBucketQuantity->value());
}
m_frmProgressBar->setVisible(true);
m_progressBar->setValue(0);
/*
* For other thread
*/
setEnabledInsertingProcess(false);
m_frmProgressBar->setVisible(true);
auto differenceNumberOfSuccesses = m_tableInformation.m_numberOfSuccesses;
auto differenceNumberOfFailures = m_tableInformation.m_numberOfFailures;
int value;
value_type currentString = toStdArray(m_leFrom->text().toStdString());
for (size_t progress = 0, target = m_sbQuantity->value(); progress < target;
++progress) {
m_pTable->insert(currentString);
next(currentString);
if (m_stop) {
m_stop = false;
break;
}
value = static_cast<int>(
progress * static_cast<double>(m_progressBar->maximum()) / target);
if (value > m_progressBar->value()) {
m_progressBar->setValue(value);
}
QApplication::processEvents();
}
updateCharts();
updateTableView();
m_frmProgressBar->setVisible(false);
setEnabledInsertingProcess(true);
/*
* Output message
*/
differenceNumberOfSuccesses =
m_tableInformation.m_numberOfSuccesses - differenceNumberOfSuccesses;
differenceNumberOfFailures =
m_tableInformation.m_numberOfFailures - differenceNumberOfFailures;
m_lblOutputMessages->setText(
getColorTextHTML(
QString("Successful inserts: %1").arg(differenceNumberOfSuccesses),
"green") +
"<br>" +
getColorTextHTML(QString("Failed inserts&nbsp;&nbsp;&nbsp;&nbsp;: %1")
.arg(differenceNumberOfFailures),
"red"));
}
inline void DemonstrationWidget::slotClickedInsert() {
bool tableTypeIsChain = getCurrentTableType() == TableType::Chain;
if (not checkBeforeInsertion(tableTypeIsChain)) {
return;
}
m_pTable->insert(toStdArray(m_leInsert->text().toStdString()));
outputMessage(m_tableInformation.m_lastInsertion ? "Inserting is successful"
: "The insertion has failed",
m_tableInformation.m_lastInsertion ? "green" : "red");
}
/*
* Other logic
*/
inline auto DemonstrationWidget::getCurrentFactory() const {
using namespace BusinessLogic::Hash;
std::unique_ptr<const Factory::Abstract> factory;
bool functionTypeIsFamily =
getCurrentFunctionType() == RelationshipType::Family;
if (getCurrentAlgorythmType() == RelationshipType::One) {
factory = std::make_unique<Factory::One>(
functionTypeIsFamily
? m_complicatedFunction // The complicated function must be prepared
: std::dynamic_pointer_cast<Function::One::Creator>(m_pFunction),
std::dynamic_pointer_cast<Algorithm::One::Creator>(m_pAlgorithm));
} else if (functionTypeIsFamily) {
factory = std::make_unique<Factory::Family>(
std::dynamic_pointer_cast<Function::Family::Creator>(m_pFunction),
std::dynamic_pointer_cast<Algorithm::Family::Creator>(m_pAlgorithm));
} else {
std::invalid_argument("function type not defined");
}
return factory;
}
inline void DemonstrationWidget::updateFunctionCreator() {
using namespace BusinessLogic::Hash::Function;
if (m_rbEquivalent->isChecked()) {
m_pFunction = std::make_shared<Equivalent::Creator>();
} else if (m_rbStandart->isChecked()) {
m_pFunction = std::make_shared<Standart::Creator>();
} else { // m_rbFNV1a32bit->isChecked()
m_pFunction = std::make_shared<FNV1a::Creator>();
}
}
inline void DemonstrationWidget::updateAlgorithmCreator() {
using namespace BusinessLogic::Hash::Algorithm;
if (m_rbLinearProbing->isChecked()) {
m_pAlgorithm = std::make_shared<LinearProbing::Creator>();
} else if (m_rbQuadraticProbing->isChecked()) {
m_pAlgorithm = std::make_shared<QuadraticProbing::Creator>();
} else if (m_rbPseudorandomProbing->isChecked()) {
m_pAlgorithm = std::make_shared<PseudorandomProbing::Creator>(
m_sbFirstInputData->value());
} else { // m_rbDoubleHashing->isChecked()
m_pAlgorithm = std::make_shared<DoubleHashing::Creator>(
m_sbFirstInputData->value(), m_sbSecondInputData->value());
}
}
inline void DemonstrationWidget::deleteModel() {
auto stringListModel = m_tableView->selectionModel();
m_tableView->setModel(nullptr);
if (stringListModel not_eq nullptr) {
delete stringListModel;
}
}
/*
* Table GUI
*/
inline void DemonstrationWidget::slotUpdateAdditionalInputData() {
bool predicate = {getCurrentFunctionType() == RelationshipType::Family};
m_gbInputData->setVisible(predicate);
m_frmFirstInputData->setVisible(predicate);
if (getCurrentTableType() == TableType::Chain) {
m_rbStandart->setEnabled(true);
m_rbEquivalent->setEnabled(true);
m_frmSecondInputData->setVisible(false);
} else {
bool algorythmIsFamily =
getCurrentAlgorythmType() == RelationshipType::Family;
m_rbEquivalent->setDisabled(algorythmIsFamily);
m_rbStandart->setDisabled(algorythmIsFamily);
m_frmSecondInputData->setVisible(algorythmIsFamily);
if (algorythmIsFamily) {
m_rbFNV1a32bit->setChecked(true);
repaint();
m_frmSecondInputData->setVisible(m_rbDoubleHashing->isChecked());
}
}
}
inline void DemonstrationWidget::slotClickedApply() {
using namespace BusinessLogic::Hash;
using namespace BusinessLogic::Hash::Function::Pattern;
if (m_rbDoubleHashing->isChecked() &&
m_sbFirstInputData->value() == m_sbSecondInputData->value()) {
outputMessage("Hash function coefficients should not match", "red");
return;
}
updateFunctionCreator();
updateAlgorithmCreator();
bool tableTypeIsChain = getCurrentTableType() == TableType::Chain;
bool functionTypeIsFamily =
getCurrentFunctionType() == RelationshipType::Family;
if (functionTypeIsFamily && (tableTypeIsChain || getCurrentAlgorythmType() ==
RelationshipType::One)) {
m_complicatedFunction = std::make_shared<FamilyToOne::Creator>(
std::dynamic_pointer_cast<Function::Family::Creator>(m_pFunction),
m_sbFirstInputData->value());
}
size_t bucketQuantity = m_sbBucketQuantity->value();
try {
if (tableTypeIsChain) {
m_pTable = std::make_unique<Table::Chains>(
bucketQuantity,
functionTypeIsFamily
? *m_complicatedFunction
: *std::dynamic_pointer_cast<Function::One::Creator>(m_pFunction),
m_alphabetPower);
} else {
auto factory = getCurrentFactory();
m_pTable = std::make_unique<Table::OpenAddressing>(
bucketQuantity, *factory, m_alphabetPower);
}
} catch (const std::bad_alloc &err) {
outputMessage("Not enough RAM", "red");
return;
}
setEnabledCreateHashTable(false);
m_pbFocus->setEnabled(true);
m_pTable->signTheObject(this);
/*
* A descendant will notify an ancestor of his own destruction when using
* delete
*/
deleteModel();
m_pStandardModel =
new QStandardItemModel(bucketQuantity, (tableTypeIsChain ? 0 : 1), this);
m_tableView->setModel(m_pStandardModel);
m_lblOutputMessages->setText(
getColorTextHTML("The model was created", "green"));
}
inline void DemonstrationWidget::slotClickedStatistics() {
m_tableInformation.m_lastCoefficient =
m_pTable->simpleUniformHashingCoefficient();
QMessageBox::information(
nullptr, "Statistics",
QString("Maximum number of collisions:\t%1\n")
.arg(m_tableInformation.m_maxCollision) +
QString("Number of successful inserts:\t\t%1\n")
.arg(m_tableInformation.m_numberOfSuccesses) +
QString("Number of failed inserts:\t\t%1\n")
.arg(m_tableInformation.m_numberOfFailures) +
QString("Simple uniform hashing coefficient:\t%1\n")
.arg(m_tableInformation.m_lastCoefficient));
}
inline void DemonstrationWidget::slotClickedFindFree() {
QString result;
if (m_pTable->numberOfBuckets() == 0) {
result = firstChar;
} else {
value_type currentString = m_tableInformation.m_lastValue;
while (m_pTable->isExist(next(currentString)))
continue;
result = toQString(currentString);
}
m_leFrom->setText(result);
m_leInsert->setText(result);
}
inline void DemonstrationWidget::slotClickedStop() {
m_stop = true;
setEnabledInsertingProcess(true);
}
inline void DemonstrationWidget::slotClickedFocus() { updateCharts(); }
/*
* Base GUI
*/
inline void DemonstrationWidget::slotClickedReset() {
setEnabledCreateHashTable(true);
m_pbFocus->setDisabled(true);
m_complicatedFunction.reset();
m_pTable.release();
m_tableInformation.clear();
resetAxes();
deleteModel();
outputMessage("The model has been deleted", "green");
}
inline QString
DemonstrationWidget::getColorTextHTML(const QString &text,
const char *const color) const {
return QString(m_fontBeginColorHTML).arg(color) + text + m_fontEndHTML;
}
inline void DemonstrationWidget::outputMessage(const QString &text,
const char *const color) {
m_lblOutputMessages->setText(getColorTextHTML(text, color));
}
inline void DemonstrationWidget::setEnabledCreateHashTable(bool flag) {
for (QWidget *widget : std::initializer_list<QWidget *>{
m_pbApply, m_sbBucketQuantity, m_gbResolutionOfCollisions,
m_gbFunction, m_gbInputData}) {
widget->setEnabled(flag);
}
if (getCurrentTableType() not_eq TableType::Chain) {
m_gbAlgorithm->setEnabled(flag);
}
m_gbLoadTable->setDisabled(flag);
m_pbStatistics->setDisabled(flag);
}
inline void DemonstrationWidget::setEnabledInsertingProcess(bool flag) {
for (QWidget *widget : std::initializer_list<QWidget *>{
m_leFrom, m_sbQuantity, m_pbMakeItems, m_leInsert, m_pbInsert,
m_pbReset, m_pbStatistics, m_pbFindFree}) {
widget->setEnabled(flag);
}
m_pbStop->setDisabled(flag);
}
@@ -0,0 +1,233 @@
#ifndef DEMONSTRATION_WIDGET_H
#define DEMONSTRATION_WIDGET_H
#include "../../Validator/validator.h"
#include "SourceCode/BusinessLogic/businessLogic.h"
#include "SourceCode/BusinessLogic/hashHeaderFiles.h"
#include "hashTable.h"
#include "ui_demonstrationWidget.h"
#include <algorithm>
#include <array>
#include <memory>
#include <thread>
#include <QChartView>
#include <QLineSeries>
#include <QStringListModel>
#include <QtCharts>
class DemonstrationWidget
: public QWidget,
protected Ui::DemonstrationWidget,
public BusinessLogic::Hash::Table::Pattern::InterfaceSubscriber {
public:
using value_type = BusinessLogic::Hash::Table::Abstract::value_type;
using table_type = BusinessLogic::Hash::Table::Abstract;
private:
struct TableInformation {
public:
/* Qt containers */
QLineSeries *m_pSeriesNumberOfCollisions;
/* If successful */
std::pair<size_t, size_t> m_lastCoord;
size_t m_numberOfSuccesses;
size_t m_lastCollision;
size_t m_maxCollision;
double m_lastCoefficient;
double m_maxCoefficient;
/* If unsuccessful */
size_t m_numberOfFailures;
/* In any case */
value_type m_lastValue;
bool m_lastInsertion;
public:
TableInformation(const TableInformation &) = delete;
TableInformation(TableInformation &&) = delete;
TableInformation(QLineSeries *maxCollision)
: m_pSeriesNumberOfCollisions(maxCollision) {
clear();
};
public:
void clear();
};
private: // Event filter
virtual bool eventFilter(QObject *target, QEvent *event) override {
if (target == m_pChartCollisionsView) {
QChartView *view = dynamic_cast<QChartView *>(target);
QChart *chart = view->chart();
switch (event->type()) {
case QEvent::Wheel: {
QWheelEvent *currentEvent = dynamic_cast<QWheelEvent *>(event);
qreal factor = currentEvent->angleDelta().y() > 0 ? 0.9 : 1.1;
QRectF rect = QRectF(chart->plotArea().left(), chart->plotArea().top(),
chart->plotArea().width() * factor,
chart->plotArea().height() * factor);
QPointF mousePos = view->mapFromGlobal(QCursor::pos());
rect.moveCenter(mousePos);
chart->zoomIn(rect);
QPointF delta = chart->plotArea().center() - mousePos;
chart->scroll(delta.x(), -delta.y());
return true;
} break;
default: {
return false;
} break;
}
}
return false;
}
public:
enum class TableType : short { Chain, OpenAdressing, Indefined };
enum class RelationshipType : short { One, Family, Indefined };
private:
/*
* Constants
*/
static constexpr char firstChar = '!';
static constexpr char endChar = '~';
QChartView *m_pChartCollisionsView;
QStandardItemModel *m_pStandardModel;
bool m_stop;
/*
* Business logic
*/
std::shared_ptr<BusinessLogic::Hash::Function::Abstract::Creator> m_pFunction;
std::shared_ptr<BusinessLogic::Hash::Function::One::Creator>
m_complicatedFunction;
std::shared_ptr<BusinessLogic::Hash::Algorithm::Abstract::Creator>
m_pAlgorithm;
size_t m_alphabetPower;
std::unique_ptr<BusinessLogic::Hash::Table::Abstract> m_pTable;
TableInformation m_tableInformation;
/*
* HTML tags
*/
static constexpr auto m_fontBeginColorHTML = R"(<font color="%1">)";
static constexpr auto m_fontEndHTML = R"(</font>)";
public:
DemonstrationWidget(QWidget *pWidget = nullptr);
public: // Custom slots
virtual void successfulInsertion(const table_type *, const value_type &,
std::pair<size_t, size_t>, size_t) override;
virtual void unsuccessfulInsertion(const table_type *,
const value_type &) override;
private:
/*
* Business logic
*/
TableType getCurrentTableType() const {
TableType result;
result = {m_rbChains->isChecked() ? TableType::Chain
: m_rbOpenAdressing->isChecked() ? TableType::OpenAdressing
: TableType::Indefined};
if (result == TableType::Indefined) {
throw std::invalid_argument("table not defined");
}
return result;
}
RelationshipType getCurrentFunctionType() const {
RelationshipType result;
result = {m_rbEquivalent->isChecked() ? RelationshipType::One
: m_rbStandart->isChecked() ? RelationshipType::One
: m_rbFNV1a32bit->isChecked() ? RelationshipType::Family
: RelationshipType::Indefined};
if (result == RelationshipType::Indefined) {
throw std::invalid_argument("function not defined");
}
return result;
}
RelationshipType getCurrentAlgorythmType() const {
RelationshipType result;
result = {m_rbLinearProbing->isChecked() ? RelationshipType::One
: m_rbQuadraticProbing->isChecked() ? RelationshipType::One
: m_rbPseudorandomProbing->isChecked() ? RelationshipType::Family
: m_rbDoubleHashing->isChecked() ? RelationshipType::Family
: RelationshipType::Indefined};
if (result == RelationshipType::Indefined) {
throw std::invalid_argument("algorythm not defined");
}
return result;
}
auto getCurrentFactory() const;
void updateFunctionCreator();
void updateAlgorithmCreator();
void deleteModel();
void resetAxes() {
m_pChartCollisionsView->chart()
->axes(Qt::Horizontal)
.front()
->setRange(1, 2);
m_pChartCollisionsView->chart()->axes(Qt::Vertical).front()->setRange(0, 1);
}
QString toQString(const value_type &value) {
auto convert = value;
unsigned size =
std::remove(convert.begin(), convert.end(), '\0') - convert.begin();
return QString::fromLatin1(convert.data(), size);
}
value_type toStdArray(std::string &&value) const {
value_type result = {'\0', '\0', '\0', '\0', firstChar};
std::copy(value.rbegin(), value.rend(), result.rbegin());
return result;
}
value_type &next(value_type &value) const;
bool checkBeforeInsertion(bool);
/*
* GUI and displaying
*/
QString getColorTextHTML(const QString &text, const char *const color) const;
void outputMessage(const QString &text, const char *const color);
void updateColumns(size_t rowIndex);
void updateCharts();
void updateTableView();
void setEnabledCreateHashTable(bool flag);
void setEnabledInsertingProcess(bool flag);
public slots:
void slotTabSwitched(int index) {
if (index == 1) {
QSplitter *splitter = findChild<QSplitter *>("");
auto children = splitter->children();
QList<int> sizes{dynamic_cast<QWidget *>(children[0])->minimumHeight(),
dynamic_cast<QWidget *>(children[1])->minimumHeight()};
splitter->setSizes(sizes);
}
}
private slots:
void slotUpdateAdditionalInputData();
void slotClickedReset();
void slotClickedApply();
void slotClickedMakeItems();
void slotClickedInsert();
void slotClickedStatistics();
void slotClickedFindFree();
void slotClickedStop();
void slotClickedFocus();
};
#endif // DEMONSTRATION_WIDGET_H
@@ -0,0 +1,284 @@
#include "testingWidget.h"
TestingWidget::TestingWidget(QWidget *pWidget)
: QWidget(pWidget), m_currentComplexityName("everything"),
m_currentTopicName("everything"), m_file("./QuestionsXML/questions.xml") {
setupUi(dynamic_cast<QWidget *>(this));
connect(m_pbConfirm, &QPushButton::clicked, this,
&TestingWidget::slotClickedConfirm);
connect(m_pbStart, &QPushButton::clicked, this,
&TestingWidget::slotClickedStart);
connect(m_pbStop, &QPushButton::clicked, this,
&TestingWidget::slotResetTesting);
connect(m_rbAllDifficulties, &QRadioButton::clicked, this,
&TestingWidget::slotSwitchedComplexity);
connect(m_rbEasy, &QRadioButton::clicked, this,
&TestingWidget::slotSwitchedComplexity);
connect(m_rbMedium, &QRadioButton::clicked, this,
&TestingWidget::slotSwitchedComplexity);
connect(m_rbHard, &QRadioButton::clicked, this,
&TestingWidget::slotSwitchedComplexity);
connect(m_rbAllTopics, &QRadioButton::clicked, this,
&TestingWidget::slotSwitchedTopics);
connect(m_rbDiscreteMathematics, &QRadioButton::clicked, this,
&TestingWidget::slotSwitchedTopics);
connect(m_rbHashFunction, &QRadioButton::clicked, this,
&TestingWidget::slotSwitchedTopics);
connect(m_rbHashTable, &QRadioButton::clicked, this,
&TestingWidget::slotSwitchedTopics);
connect(m_rbAlgorithm, &QRadioButton::clicked, this,
&TestingWidget::slotSwitchedTopics);
m_frmConfirm->hide();
}
inline void TestingWidget::hideCheckBoxes() {
QCheckBox *currentCheckBox;
for (unsigned i = 0; i < 9; ++i) {
currentCheckBox = findChild<QCheckBox *>(QString("m_cbIndex%1").arg(i));
currentCheckBox->hide();
}
}
inline void TestingWidget::showCheckBoxes() {
QCheckBox *currentCheckBox;
for (unsigned i = 0, size = m_answers.size(); i < size; ++i) {
currentCheckBox = findChild<QCheckBox *>(QString("m_cbIndex%1").arg(i));
currentCheckBox->show();
currentCheckBox->setText(m_answers[i].first);
}
}
inline QString TestingWidget::getHTMLQuestion(QDomElement element) {
QString currentQuestion;
element = element.firstChildElement();
do {
switch (getTagsEnumFromQString(element.tagName())) {
case TagXML::Caption: {
currentQuestion.append(QString("<h3>%1</h3>").arg(element.text()));
} break;
case TagXML::Text: {
currentQuestion.append(QString(R"(
<p align="justify">
<var>
<font face="Times New Roman, Times, serif">
%2
</font>
</var>
</p>
)")
.arg(element.text()));
} break;
case TagXML::Answer: {
m_answers.append(std::make_pair(
element.text(), element.hasAttribute("type")
? (element.attribute("type") == "correct")
: false));
} break;
case TagXML::Question: {
throw std::invalid_argument(
"the question cannot be nested within the question");
} break;
case TagXML::Undefined: {
throw std::invalid_argument("tag undefined");
} break;
}
element = element.nextSiblingElement();
} while (not element.isNull());
return currentQuestion;
}
inline void TestingWidget::configureInput(const QString &value) {
hideCheckBoxes();
resetInput();
if (value == "choice") {
m_swInputData->setCurrentIndex(0);
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
std::shuffle(m_answers.begin(), m_answers.end(),
std::default_random_engine(seed));
showCheckBoxes();
} else if (value == "integer") {
m_swInputData->setCurrentIndex(1);
} else if (value == "floatingPoint") {
m_swInputData->setCurrentIndex(2);
} else {
throw std::invalid_argument("the type of the input option is undefined");
}
}
inline bool TestingWidget::showNextQuestion() {
bool continueFlag = true;
auto checkType = [](const QString &value) -> bool {
return bool{value == "choice" || value == "integer" ||
value == "floatingPoint"};
};
while (not m_currentQuestion.isNull() && continueFlag) {
m_currentTypeName = m_currentQuestion.attribute("type");
if ((m_currentTopicName == "everything" ||
m_currentQuestion.attribute("category")
.split('|')
.contains(m_currentTopicName)) &&
(m_currentComplexityName == "everything" ||
m_currentComplexityName ==
m_currentQuestion.attribute("complexity")) &&
checkType(m_currentTypeName)) {
m_answers.clear();
m_testingTextBrowser->setHtml(getHTMLQuestion(m_currentQuestion));
configureInput(m_currentTypeName);
continueFlag = false;
}
m_currentQuestion = m_currentQuestion.nextSiblingElement("question");
}
return (not continueFlag);
}
inline void TestingWidget::setEnabledGUIStartTesting(bool flag) {
m_gbTopics->setEnabled(flag);
m_gbDifficulty->setEnabled(flag);
m_pbStart->setEnabled(flag);
m_pbStop->setDisabled(flag);
m_frmConfirm->setVisible(not flag);
}
inline TestingWidget::TagXML
TestingWidget::getTagsEnumFromQString(const QString &value) {
TagXML result = {value == "question" ? TagXML::Question
: value == "caption" ? TagXML::Caption
: value == "text" ? TagXML::Text
: value == "answer" ? TagXML::Answer
: TagXML::Undefined};
return result;
}
/*
* Slots
*/
inline void TestingWidget::slotSwitchedTopics() {
QString result = {m_rbAllTopics->isChecked() ? QString("everything")
: m_rbDiscreteMathematics->isChecked()
? QString("discreteMathematics")
: m_rbHashFunction->isChecked() ? QString("hashFunction")
: m_rbHashTable->isChecked() ? QString("hashTable")
: m_rbAlgorithm->isChecked() ? QString("algorithm")
: QString()};
if (result.isNull()) {
throw std::invalid_argument("topic undefined");
}
m_currentTopicName = result;
}
inline void TestingWidget::slotSwitchedComplexity() {
QString result = {m_rbAllDifficulties->isChecked() ? QString("everything")
: m_rbEasy->isChecked() ? QString("easy")
: m_rbMedium->isChecked() ? QString("medium")
: m_rbHard->isChecked() ? QString("hard")
: QString()};
if (result.isNull()) {
throw std::invalid_argument("complexity undefined");
}
m_currentComplexityName = result;
}
inline bool TestingWidget::checkAnswer(const QString &value) {
if (m_answers.size() <= 0) {
return false;
}
bool result = true;
if (value == "choice") {
QCheckBox *currentCheckBox;
for (unsigned i = 0, size = m_answers.size(); i < size; ++i) {
currentCheckBox = findChild<QCheckBox *>(QString("m_cbIndex%1").arg(i));
if (m_answers[i].second) {
result &= currentCheckBox->isChecked();
} else {
result &= not currentCheckBox->isChecked();
}
}
} else if (value == "integer" || value == "floatingPoint") {
QString answer = {value == "integer" ? m_sbInteger->text()
: m_sbDouble->text()};
auto iter =
std::find_if(m_answers.begin(), m_answers.end(),
[answer](const std::pair<QString, bool> &value) -> bool {
return (value.second == true && value.first == answer);
});
return (iter not_eq m_answers.end());
} else {
throw std::invalid_argument("input not defined");
}
return result;
}
inline void TestingWidget::slotClickedConfirm() {
bool result = checkAnswer(m_currentTypeName);
emit signalReplyGiven(result);
if (not showNextQuestion()) {
setEnabledGUIStartTesting(true);
slotResetTesting();
}
}
inline void TestingWidget::slotClickedStart() {
bool isOpened = m_file.open(QIODevice::ReadOnly);
emit signalFileOpened(isOpened);
if (isOpened) {
bool isSet = m_document.setContent(&m_file);
m_file.close();
emit signalContentIsSet(isSet);
if (isSet) {
QDomNode questions =
m_document.firstChild().nextSiblingElement("questions");
if (questions.isNull()) {
return;
}
QDomNode firstQuestion =
questions.firstChild().nextSiblingElement("question");
if (firstQuestion.isNull()) {
return;
}
m_currentQuestion = firstQuestion.toElement();
if (showNextQuestion()) {
setEnabledGUIStartTesting(false);
emit signalStartOfTesting();
}
}
}
return;
}
inline void TestingWidget::resetInput() {
QCheckBox *currentCheckBox;
for (unsigned i = 0; i < 9; ++i) {
currentCheckBox = findChild<QCheckBox *>(QString("m_cbIndex%1").arg(i));
currentCheckBox->setChecked(false);
}
m_sbInteger->clear();
m_sbDouble->clear();
}
inline void TestingWidget::slotResetTesting() {
m_testingTextBrowser->clear();
setEnabledGUIStartTesting(true);
resetInput();
emit signalEndOfTesting();
}
@@ -0,0 +1,71 @@
#ifndef TESTING_WIDGET_H
#define TESTING_WIDGET_H
#include "ui_testingWidget.h"
#include <random>
#include <QWidget>
#include <QtXml>
#include <QMessageBox>
class TestingWidget : public QWidget
, protected Ui::TestingWidget
{
Q_OBJECT
private:
QDomDocument m_document;
QDomElement m_currentQuestion;
QString m_currentComplexityName;
QString m_currentTopicName;
QString m_currentTypeName;
QFile m_file;
QVector<std::pair<QString, bool>> m_answers;
private:
enum class Topic : short {
Everything, DiscreteMathematics, HashFunction, HashTable, Algorithm, Undefined
};
enum class Complexity : short {
Everything, Easy, Medium, Hard, Undefined
};
enum class TagXML : short {
Question, Caption, Text, Answer, Undefined
};
public:
TestingWidget(QWidget *pWidget = nullptr);
~TestingWidget() {
if(m_file.isOpen()) {
m_file.close();
}
}
private:
void hideCheckBoxes();
void showCheckBoxes();
QString getHTMLQuestion(QDomElement domNode);
void configureInput(const QString &);
bool showNextQuestion();
void setEnabledGUIStartTesting(bool flag);
TagXML getTagsEnumFromQString(const QString&);
bool checkAnswer(const QString&);
void resetInput();
private slots:
void slotSwitchedTopics();
void slotSwitchedComplexity();
void slotClickedConfirm();
void slotClickedStart();
void slotResetTesting();
signals:
void signalFileOpened(bool /*isOpen*/);
void signalContentIsSet(bool /*isSet*/);
void signalReplyGiven(bool /*isCorrect*/);
void signalStartOfTesting();
void signalEndOfTesting();
};
#endif // TESTING_WIDGET_H
@@ -0,0 +1,112 @@
#include "textBrowserWidget.h"
TextBrowserWidget::TextBrowserWidget(const QString &xmlFile, QWidget *pWidget)
: QWidget(pWidget)
{
setupUi(dynamic_cast<QWidget *>(this));
connect( m_main, &QPushButton::clicked, this, &TextBrowserWidget::slotClickedMain );
connect( m_next, &QPushButton::clicked, this, &TextBrowserWidget::slotClickedNext );
connect( m_previous, &QPushButton::clicked, this, &TextBrowserWidget::slotClickedPrev );
connect( m_textBrowser, &QTextBrowser::sourceChanged, this, &TextBrowserWidget::slotPageChanged );
m_textBrowser->setOpenExternalLinks(true);
unpack(xmlFile);
}
/*
* HTML theory
*/
inline void TextBrowserWidget::slotPageChanged(const QUrl &url) {
QString value = url.toString().section('/', -1);
auto iterator = std::find_if(m_htmlPages.cbegin(), m_htmlPages.cend()
, [value](const QString &other)->bool {
return ( other.section('/', -1) == value );
});
if(iterator == m_htmlPages.cend()) {
m_textBrowser->clear();
return;
}
m_currentIndexPage = iterator - m_htmlPages.cbegin();
bool isMainPage = (m_currentIndexPage == 0);
m_main->setDisabled(isMainPage);
m_previous->setEnabled( isMainPage ? false : m_currentIndexPage not_eq 1 );
m_next->setEnabled( isMainPage ? false : m_currentIndexPage not_eq (m_htmlPages.size() - 1) );
}
inline bool TextBrowserWidget::unpack(const QString &xmlFileName) {
QDomDocument xmlDocument;
QFile xmlFile(xmlFileName);
if(not xmlFile.open(QIODevice::ReadOnly)) {
return false;
}
bool isSet = xmlDocument.setContent(&xmlFile);
xmlFile.close();
if(not isSet) {
return false;
}
QDomElement infoNode = xmlDocument.firstChild().nextSiblingElement("info");
QDomElement currentDirectoryElement = infoNode.firstChildElement("directory");
QStringList searchPaths;
while (not currentDirectoryElement.isNull()) {
searchPaths.append(currentDirectoryElement.text());
currentDirectoryElement = currentDirectoryElement.nextSiblingElement("directory");
}
QDomElement currentPage = infoNode.firstChildElement("order").firstChildElement("page");
if(currentPage.isNull()) {
return false;
}
QStringList result;
QString currentTagName;
bool isExists;
while(not currentPage.isNull()) {
currentTagName = currentPage.text();
isExists = false;
for(const QString &name : searchPaths) {
if(QDir(name).exists(currentTagName)) {
isExists = true;
break;
}
}
if(not isExists) {
return false;
}
result.push_back(currentTagName);
currentPage = currentPage.nextSiblingElement("page");
}
m_textBrowser->setSearchPaths(searchPaths);
m_htmlPages = result;
return setSourceMainPage();
}
inline void TextBrowserWidget::slotClickedMain() {
if(m_currentIndexPage not_eq 0) {
m_textBrowser->setSource(m_htmlPages.front());
}
}
inline void TextBrowserWidget::slotClickedPrev() {
if(m_currentIndexPage not_eq 1) {
m_textBrowser->setSource(m_htmlPages[--m_currentIndexPage]);
}
}
inline void TextBrowserWidget::slotClickedNext() {
if(m_currentIndexPage not_eq (m_htmlPages.size() - 1)) {
m_textBrowser->setSource(m_htmlPages[++m_currentIndexPage]);
}
}
@@ -0,0 +1,50 @@
#ifndef THEORY_WIDGET_H
#define THEORY_WIDGET_H
#include "ui_textBrowserWidget.h"
#include <QWidget>
#include <QFile>
#include <QtXml>
class TextBrowserWidget : public QWidget
, protected Ui::TextBrowserWidget
{
private:
/*
* HTML
*/
QStringList m_htmlPages;
int m_currentIndexPage;
public:
TextBrowserWidget(const QString &xmlFile = {}
, QWidget *pWidget = nullptr);
public:
bool unpack(const QString &xmlFile);
void setFontPointSize(int size) {
QFont font = m_textBrowser->font();
font.setPointSize(size);
m_textBrowser->setFont(font);
}
private:
/*
* Business logic
*/
bool setSourceMainPage() {
if(not m_htmlPages.isEmpty()) {
m_textBrowser->setSource( QUrl( m_htmlPages.front() ) );
return true;
}
return false;
}
private slots:
void slotPageChanged(const QUrl &url);
void slotClickedMain();
void slotClickedPrev();
void slotClickedNext();
};
#endif // THEORY_WIDGET_H
@@ -0,0 +1,154 @@
#include "mainWindow.h"
inline void MainWindow::appendStatusbarText(const QString &value) {
m_timer->stop();
QString newData;
if(m_lblStatusbarText->text().size() + value.size() < 150) {
newData.append(m_lblStatusbarText->text());
}
newData.append(value + "; ");
m_lblStatusbarText->setText(newData);
m_timer->start();
}
inline void MainWindow::saveResult() {
QDate currentTime = QDate::currentDate();
short day = currentTime.day();
short month = currentTime.month();
short year = currentTime.year() % 1000;
constexpr short sizeDay = 5;
constexpr short sizeMonth = 4;
constexpr short sizeYear = 10;
constexpr short sizeCorrect = 8;
constexpr short sizeTotal = 8;
//constexpr short sizeSubject = 3;
//constexpr short sizeComplexity = 2;
constexpr short size = {
sizeDay + sizeMonth + sizeYear
+ sizeCorrect + sizeTotal
// + sizeSubject + sizeComplexity
};
std::bitset<size> newData;
for(const auto &value : std::initializer_list<std::pair<short, short>>{
{day, sizeDay}, {month, sizeMonth}, {year, sizeYear}
, {m_numerOfCorrect, sizeCorrect}, {m_numberOfAll, sizeTotal}
}) {
newData <<= value.second;
newData |= value.first;
}
QByteArray byteArray;
while(newData.any()) {
byteArray.push_front( static_cast<char>( newData.to_ullong()) );
newData >>= CHAR_BIT;
}
QFile file("save.dat");
file.open(QIODevice::Append);
file.write(byteArray);
file.close();
}
MainWindow::MainWindow(QWidget *pWidget)
: QMainWindow ( pWidget )
, m_timer( new QTimer(this) )
, m_lblStatusbarText(new QLabel)
{
setupUi(dynamic_cast<QMainWindow *>(this));
/*
* Size
*/
QSize screen = QApplication::desktop()->screenGeometry().size();
move(screen.width() / 30, screen.height() / 20);
/*
* Signals and slots
*/
connect( m_tabWidget, &QTabWidget::tabBarClicked, m_demonstrationTab, &DemonstrationWidget::slotTabSwitched);
connect( m_actionTheory, &QAction::triggered, this, [this]() {
m_stackedWidget->setCurrentIndex(0);
});
connect( m_actionPractice, &QAction::triggered, this, [this]() {
m_stackedWidget->setCurrentIndex(1);
});
connect( m_actionAbout, &QAction::triggered, this, [](){
QMessageBox::aboutQt(nullptr);
});
/*
* Theory
*/
m_theoryTab->unpack("./TheoryHTML/info.xml");
/*
* Testing page
*/
m_lblStatusbarText->setParent(m_statusbar);
QFont font = m_lblStatusbarText->font();
font.setPointSize(12);
m_lblStatusbarText->setFont(font);
m_statusbar->addWidget(m_lblStatusbarText);
m_timer->setParent(this);
m_timer->setInterval(1000 * 5);
m_timer->callOnTimeout(m_lblStatusbarText, &QLabel::clear);
connect( m_secondPage, &TestingWidget::signalStartOfTesting, this, [this]() {
m_numerOfCorrect = 0;
m_numberOfAll = 0;
appendStatusbarText("Testing has begun");
});
connect( m_secondPage, &TestingWidget::signalEndOfTesting, this, [this]() {
saveResult();
appendStatusbarText("Test ended, results saved");
});
connect( m_secondPage, &TestingWidget::signalReplyGiven, this, [this](bool result) {
++m_numberOfAll;
if(result) {
++m_numerOfCorrect;
appendStatusbarText("Correct answer");
}
else {
appendStatusbarText("False answer");
}
});
connect( m_secondPage, &TestingWidget::signalFileOpened, this, [this](bool flag) {
appendStatusbarText(flag ? "File successfully opened" : "File cannot be opened");
});
connect( m_secondPage, &TestingWidget::signalContentIsSet, this, [this](bool flag) {
appendStatusbarText(flag ? "Content of file successfully set" : "Failure to set content of file");
});
/*
* Manual window
*/
connect( m_actionManual, &QAction::triggered, this, [this]() {
auto *manualWindow = new QDialog(this, Qt::Dialog);
manualWindow->setModal(true);
auto *centralLayout = new QVBoxLayout;
auto *textBrowser = new TextBrowserWidget(":/ManualHTML/info.xml");
textBrowser->setFontPointSize(12);
centralLayout->addWidget(textBrowser);
auto *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close);
connect(buttonBox, &QDialogButtonBox::clicked, manualWindow, &QDialog::close);
centralLayout->addWidget(buttonBox);
manualWindow->setLayout(centralLayout);
manualWindow->setMinimumSize({ 800, 600 });
manualWindow->setWindowFlags(manualWindow->windowFlags() & ~Qt::WindowContextHelpButtonHint);
manualWindow->setWindowTitle("Manual");
manualWindow->show();
});
}
@@ -0,0 +1,29 @@
#ifndef MAIN_WINDOW_H
#define MAIN_WINDOW_H
#include "ui_mainWindow.h"
#include <bitset>
#include <QDateTime>
#include <QFile>
#include <QArrayData>
class MainWindow : public QMainWindow
, protected Ui::MainWindow
{
private:
QTimer *m_timer;
QLabel *m_lblStatusbarText;
size_t m_numerOfCorrect;
size_t m_numberOfAll;
private:
void appendStatusbarText(const QString &value);
void saveResult();
public:
MainWindow(QWidget *pWidget = nullptr);
};
#endif // MAIN_WINDOW_H
@@ -0,0 +1,972 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DemonstrationWidget</class>
<widget class="QWidget" name="DemonstrationWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>805</width>
<height>460</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<widget class="QFrame" name="m_frmProgressBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>0</width>
<height>0</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="lineWidth">
<number>1</number>
</property>
<layout class="QVBoxLayout" name="verticalLayout_13">
<item>
<widget class="QLabel" name="m_lblProgressBar">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Progress of inserting elements:</string>
</property>
</widget>
</item>
<item>
<widget class="QProgressBar" name="m_progressBar">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>50</weight>
<italic>false</italic>
<bold>false</bold>
<underline>false</underline>
<strikeout>false</strikeout>
<kerning>true</kerning>
</font>
</property>
<property name="maximum">
<number>100000</number>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QScrollArea" name="m_rightScrollArea">
<property name="geometry">
<rect>
<x>501</x>
<y>0</y>
<width>250</width>
<height>250</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>250</width>
<height>0</height>
</size>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOn</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustIgnored</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>234</width>
<height>1020</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="scrollAreaWidgetContentsLayout">
<item>
<widget class="QGroupBox" name="m_gbResolutionOfCollisions">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Resolution of collisions</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="QRadioButton" name="m_rbChains">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Chains</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="m_rbOpenAdressing">
<property name="text">
<string>Open addressing</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="m_gbFunction">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Function</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_9">
<item>
<widget class="QRadioButton" name="m_rbEquivalent">
<property name="text">
<string>Equivalent</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="m_rbStandart">
<property name="text">
<string>Standart</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="m_rbFNV1a32bit">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>FNV1a 32 bit</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="m_gbAlgorithm">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Algorithm</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<widget class="QRadioButton" name="m_rbLinearProbing">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Linear probing</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="m_rbPseudorandomProbing">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Pseudorandom probing</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="m_rbQuadraticProbing">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Quadratic probing</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="m_rbDoubleHashing">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Double hashing</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="m_gbInputData">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Additional input data</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_10">
<item>
<widget class="QFrame" name="m_frmFirstInputData">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_14">
<item>
<widget class="QLabel" name="lblFirstInputData">
<property name="text">
<string>Coefficient of the first family function:</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="buddy">
<cstring>m_sbFirstInputData</cstring>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="m_sbFirstInputData">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximum">
<number>100000000</number>
</property>
<property name="singleStep">
<number>1</number>
</property>
<property name="stepType">
<enum>QAbstractSpinBox::DefaultStepType</enum>
</property>
<property name="value">
<number>0</number>
</property>
<property name="displayIntegerBase">
<number>16</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="m_frmSecondInputData">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_15">
<item>
<widget class="QLabel" name="m_lblSecondInputData">
<property name="text">
<string>Coefficient of the second family function:</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="buddy">
<cstring>m_sbSecondInputData</cstring>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="m_sbSecondInputData">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximum">
<number>100000000</number>
</property>
<property name="singleStep">
<number>1</number>
</property>
<property name="stepType">
<enum>QAbstractSpinBox::DefaultStepType</enum>
</property>
<property name="value">
<number>1</number>
</property>
<property name="displayIntegerBase">
<number>16</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="gbHashTable">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Hash table</string>
</property>
<layout class="QFormLayout" name="formLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="lblNumberOfElements">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Bucket quantity:</string>
</property>
<property name="buddy">
<cstring>m_sbBucketQuantity</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="m_sbBucketQuantity">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>10000</number>
</property>
<property name="value">
<number>1</number>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="m_pbReset">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Reset</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="m_pbApply">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Apply</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QPushButton" name="m_pbStatistics">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Statistics</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="m_gbLoadTable">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Load table</string>
</property>
<layout class="QVBoxLayout" name="loadTableLayout">
<item>
<layout class="QFormLayout" name="makeItemsLayout">
<item row="0" column="0">
<widget class="QLabel" name="lblFrom">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>From:</string>
</property>
<property name="buddy">
<cstring>m_leFrom</cstring>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="lblQuantity">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Quantity:</string>
</property>
<property name="buddy">
<cstring>m_sbQuantity</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="m_sbQuantity">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>10000</number>
</property>
<property name="value">
<number>1</number>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="m_leFrom">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>150</width>
<height>16777215</height>
</size>
</property>
<property name="inputMethodHints">
<set>Qt::ImhNone</set>
</property>
<property name="maxLength">
<number>4</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QPushButton" name="m_pbMakeItems">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Make items</string>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QFormLayout" name="insertLayout">
<item row="0" column="0">
<widget class="QLabel" name="m_lblInsert">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Value:</string>
</property>
<property name="buddy">
<cstring>m_leInsert</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="m_leInsert">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maxLength">
<number>4</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QPushButton" name="m_pbInsert">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Insert</string>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="m_pbFindFree">
<property name="text">
<string>Find free</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="m_pbStop">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Stop</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QPushButton" name="m_pbFocus">
<property name="text">
<string>Focus</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="spacerOverOutputMessages">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QFrame" name="frmOutputMessages">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="lineWidth">
<number>1</number>
</property>
<property name="midLineWidth">
<number>0</number>
</property>
<layout class="QVBoxLayout" name="verticalLayout_12">
<item>
<widget class="QLabel" name="lblOutputMessages">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Output messages:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="m_lblOutputMessages">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<family>Consolas</family>
<pointsize>10</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="contextMenuPolicy">
<enum>Qt::DefaultContextMenu</enum>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="inputMethodHints">
<set>Qt::ImhNone</set>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="lineWidth">
<number>1</number>
</property>
<property name="midLineWidth">
<number>0</number>
</property>
<property name="text">
<string notr="true"/>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="margin">
<number>0</number>
</property>
<property name="textInteractionFlags">
<set>Qt::NoTextInteraction</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QTableView" name="m_tableView">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>500</width>
<height>250</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>300</width>
<height>200</height>
</size>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="tabKeyNavigation">
<bool>false</bool>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="dragDropOverwriteMode">
<bool>false</bool>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="horizontalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="gridStyle">
<enum>Qt::SolidLine</enum>
</property>
<attribute name="horizontalHeaderHighlightSections">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderHighlightSections">
<bool>false</bool>
</attribute>
</widget>
</widget>
<tabstops>
<tabstop>m_tableView</tabstop>
<tabstop>m_rightScrollArea</tabstop>
<tabstop>m_rbChains</tabstop>
<tabstop>m_rbOpenAdressing</tabstop>
<tabstop>m_rbEquivalent</tabstop>
<tabstop>m_rbStandart</tabstop>
<tabstop>m_rbFNV1a32bit</tabstop>
<tabstop>m_rbLinearProbing</tabstop>
<tabstop>m_rbPseudorandomProbing</tabstop>
<tabstop>m_rbQuadraticProbing</tabstop>
<tabstop>m_rbDoubleHashing</tabstop>
<tabstop>m_sbFirstInputData</tabstop>
<tabstop>m_sbSecondInputData</tabstop>
<tabstop>m_sbBucketQuantity</tabstop>
<tabstop>m_pbReset</tabstop>
<tabstop>m_pbApply</tabstop>
<tabstop>m_pbStatistics</tabstop>
<tabstop>m_leFrom</tabstop>
<tabstop>m_sbQuantity</tabstop>
<tabstop>m_pbMakeItems</tabstop>
<tabstop>m_leInsert</tabstop>
<tabstop>m_pbInsert</tabstop>
<tabstop>m_pbFindFree</tabstop>
<tabstop>m_pbStop</tabstop>
<tabstop>m_pbFocus</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>m_rbChains</sender>
<signal>clicked(bool)</signal>
<receiver>m_gbAlgorithm</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>861</x>
<y>45</y>
</hint>
<hint type="destinationlabel">
<x>858</x>
<y>225</y>
</hint>
</hints>
</connection>
<connection>
<sender>m_rbOpenAdressing</sender>
<signal>clicked(bool)</signal>
<receiver>m_gbAlgorithm</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>887</x>
<y>78</y>
</hint>
<hint type="destinationlabel">
<x>892</x>
<y>219</y>
</hint>
</hints>
</connection>
</connections>
</ui>
@@ -0,0 +1,261 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1093</width>
<height>548</height>
</rect>
</property>
<property name="windowTitle">
<string>Hash tables</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QStackedWidget" name="m_stackedWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="lineWidth">
<number>1</number>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="m_firstPage">
<layout class="QVBoxLayout" name="firstPageLayout">
<item>
<widget class="QTabWidget" name="m_tabWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="TextBrowserWidget" name="m_theoryTab">
<attribute name="title">
<string>Theory</string>
</attribute>
</widget>
<widget class="DemonstrationWidget" name="m_demonstrationTab">
<attribute name="title">
<string>Demonstration</string>
</attribute>
</widget>
</widget>
</item>
</layout>
</widget>
<widget class="TestingWidget" name="m_secondPage">
<property name="enabled">
<bool>true</bool>
</property>
</widget>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="bottomLayout">
<item>
<spacer name="bottomSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="m_exitButton">
<property name="text">
<string>&amp;Exit</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="m_menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1093</width>
<height>20</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<widget class="QMenu" name="menuHelp">
<property name="title">
<string>&amp;Help</string>
</property>
<addaction name="m_actionManual"/>
<addaction name="separator"/>
<addaction name="m_actionAbout"/>
</widget>
<widget class="QMenu" name="menuView">
<property name="title">
<string>&amp;View</string>
</property>
<addaction name="m_actionTheory"/>
<addaction name="m_actionPractice"/>
</widget>
<addaction name="menuView"/>
<addaction name="menuHelp"/>
</widget>
<widget class="QStatusBar" name="m_statusbar"/>
<action name="m_actionNewUserSession">
<property name="text">
<string>&amp;User session</string>
</property>
<property name="toolTip">
<string>User session</string>
</property>
<property name="shortcut">
<string>Ctrl+N</string>
</property>
</action>
<action name="m_actionOpen">
<property name="text">
<string>&amp;Open...</string>
</property>
<property name="shortcut">
<string>Ctrl+O</string>
</property>
</action>
<action name="m_actionSave">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;Save</string>
</property>
<property name="shortcut">
<string>Ctrl+S</string>
</property>
</action>
<action name="m_actionSaveAs">
<property name="text">
<string>Save &amp;As...</string>
</property>
</action>
<action name="m_actionOptions">
<property name="text">
<string>&amp;Options...</string>
</property>
</action>
<action name="m_actionManual">
<property name="text">
<string>&amp;Manual</string>
</property>
<property name="shortcut">
<string>Ctrl+H</string>
</property>
</action>
<action name="m_actionAbout">
<property name="text">
<string>About this &amp;program</string>
</property>
<property name="shortcut">
<string>Ctrl+A</string>
</property>
</action>
<action name="m_actionTheory">
<property name="text">
<string>&amp;Theory</string>
</property>
<property name="shortcut">
<string>Ctrl+T</string>
</property>
</action>
<action name="m_actionPractice">
<property name="text">
<string>&amp;Practice</string>
</property>
<property name="shortcut">
<string>Ctrl+P</string>
</property>
</action>
<action name="m_actionAllSessions">
<property name="text">
<string>&amp;General</string>
</property>
</action>
<action name="m_actionCurrentSessions">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>&amp;Current</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
<class>TestingWidget</class>
<extends>QWidget</extends>
<header>SourceCode/UserInterface/ClassesUI/Widgets/Testing/testingWidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>DemonstrationWidget</class>
<extends>QWidget</extends>
<header>SourceCode/UserInterface/ClassesUI/Widgets/Demonstration/demonstrationWidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>TextBrowserWidget</class>
<extends>QWidget</extends>
<header>SourceCode/UserInterface/ClassesUI/Widgets/TextBrowser/textBrowserWidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>m_tabWidget</tabstop>
<tabstop>m_exitButton</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>m_exitButton</sender>
<signal>clicked()</signal>
<receiver>MainWindow</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel">
<x>1044</x>
<y>503</y>
</hint>
<hint type="destinationlabel">
<x>935</x>
<y>524</y>
</hint>
</hints>
</connection>
</connections>
</ui>
@@ -0,0 +1,381 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TestingWidget</class>
<widget class="QWidget" name="TestingWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>716</width>
<height>545</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<layout class="QVBoxLayout" name="leftLayout">
<item>
<widget class="QLabel" name="lblTestingWindow">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Testing window:&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="buddy">
<cstring>m_testingTextBrowser</cstring>
</property>
</widget>
</item>
<item>
<widget class="QTextBrowser" name="m_testingTextBrowser">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>16</pointsize>
</font>
</property>
</widget>
</item>
<item>
<widget class="QFrame" name="m_frmConfirm">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QStackedWidget" name="m_swInputData">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="lineWidth">
<number>1</number>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="m_wChoice">
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QLabel" name="lblChoice">
<property name="text">
<string>Choose your answer:</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="m_cbIndex0">
<property name="text">
<string>CheckBox</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="m_cbIndex1">
<property name="text">
<string>CheckBox</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="m_cbIndex2">
<property name="text">
<string>CheckBox</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="m_cbIndex3">
<property name="text">
<string>CheckBox</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="m_cbIndex4">
<property name="text">
<string>CheckBox</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="m_cbIndex5">
<property name="text">
<string>CheckBox</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="m_cbIndex6">
<property name="text">
<string>CheckBox</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="m_cbIndex7">
<property name="text">
<string>CheckBox</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="m_cbIndex8">
<property name="text">
<string>CheckBox</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="m_wIntegerInput">
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="lblInteger">
<property name="text">
<string>Enter an integer number:</string>
</property>
<property name="buddy">
<cstring>m_sbInteger</cstring>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="m_sbInteger"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="m_wDoubleInput">
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLabel" name="lblDouble">
<property name="text">
<string>Enter a fractional number:</string>
</property>
<property name="buddy">
<cstring>m_sbInteger</cstring>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="m_sbDouble"/>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="confirmLayout">
<item>
<widget class="QPushButton" name="m_pbConfirm">
<property name="text">
<string>Confirm answer</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="rightLayout">
<property name="spacing">
<number>7</number>
</property>
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="m_gbTopics">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="title">
<string>Choosing a topic</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QRadioButton" name="m_rbAllTopics">
<property name="text">
<string>Everything</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="m_rbDiscreteMathematics">
<property name="text">
<string>Discrete mathematics</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="m_rbHashFunction">
<property name="text">
<string>Hash function</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="m_rbHashTable">
<property name="text">
<string>Hash table</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="m_rbAlgorithm">
<property name="text">
<string>Algorithm</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="m_gbDifficulty">
<property name="title">
<string>Choice of difficulty</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QRadioButton" name="m_rbAllDifficulties">
<property name="text">
<string>Everything</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="m_rbEasy">
<property name="text">
<string>Easy</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="m_rbMedium">
<property name="text">
<string>Medium</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="m_rbHard">
<property name="text">
<string>Hard</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="m_pbStart">
<property name="text">
<string>Start testing</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="m_pbStop">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Save &amp;&amp; Stop testing</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<tabstops>
<tabstop>m_testingTextBrowser</tabstop>
<tabstop>m_pbStart</tabstop>
<tabstop>m_pbStop</tabstop>
<tabstop>m_sbInteger</tabstop>
<tabstop>m_pbConfirm</tabstop>
<tabstop>m_rbAllTopics</tabstop>
<tabstop>m_rbDiscreteMathematics</tabstop>
<tabstop>m_rbHashFunction</tabstop>
<tabstop>m_rbHashTable</tabstop>
<tabstop>m_rbAlgorithm</tabstop>
<tabstop>m_rbAllDifficulties</tabstop>
<tabstop>m_rbEasy</tabstop>
<tabstop>m_rbMedium</tabstop>
<tabstop>m_rbHard</tabstop>
<tabstop>m_sbDouble</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>
@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TextBrowserWidget</class>
<widget class="QWidget" name="TextBrowserWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="textBrowserButtonsLayout">
<item>
<spacer name="leftSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="m_previous">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Previous</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="m_main">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Main</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="m_next">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Next</string>
</property>
</widget>
</item>
<item>
<spacer name="rightSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QTextBrowser" name="m_textBrowser">
<property name="font">
<font>
<family>Times New Roman</family>
<pointsize>16</pointsize>
</font>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
+11
View File
@@ -0,0 +1,11 @@
#include "../SourceCode/UserInterface/ClassesUI/Windows/MainWindow/mainWindow.h"
int main(int argc, char **argv)
{
QApplication app(argc, argv);
MainWindow mainWindow;
mainWindow.show();
return app.exec();
}
+17
View File
@@ -0,0 +1,17 @@
<RCC>
<qresource prefix="/">
<file>ManualHTML/info.xml</file>
<file>ManualHTML/Pages/demonstration.html</file>
<file>ManualHTML/Pages/main.html</file>
<file>ManualHTML/Pages/menubar.html</file>
<file>ManualHTML/Pages/theory.html</file>
<file>ManualHTML/Pages/theoryPage.html</file>
<file>ManualHTML/Pages/testingPage.html</file>
<file>ManualHTML/Images/demonstration.png</file>
<file>ManualHTML/Images/menubarFirst.png</file>
<file>ManualHTML/Images/menubarSecond.png</file>
<file>ManualHTML/Images/testingPage.png</file>
<file>ManualHTML/Images/theory.png</file>
<file>ManualHTML/Images/theoryPage.png</file>
</qresource>
</RCC>