├── BTree ├── BTree.hpp ├── data │ ├── class-bint.hpp │ ├── class-integer.hpp │ ├── class-matrix.hpp │ ├── one │ │ ├── BTree.cpp │ │ ├── BTree.hpp │ │ ├── InsertionTest.cpp │ │ ├── data_make.cpp │ │ ├── data_make_query.cpp │ │ ├── exception.hpp │ │ ├── runTest.py │ │ ├── sql_checker.cpp │ │ └── utility.hpp │ ├── three │ │ ├── BTree.cpp │ │ ├── BTree.hpp │ │ ├── InsertionTest.cpp │ │ ├── data_make.cpp │ │ ├── data_make_erase.cpp │ │ ├── data_make_query.cpp │ │ ├── exception.hpp │ │ ├── runTest.py │ │ ├── sql_checker.cpp │ │ └── utility.hpp │ └── two │ │ ├── BTree.cpp │ │ ├── BTree.hpp │ │ ├── InsertionTest.cpp │ │ ├── data_make.cpp │ │ ├── data_make_query.cpp │ │ ├── exception.hpp │ │ ├── runTest.py │ │ ├── sql_checker.cpp │ │ └── utility.hpp ├── exception.hpp └── utility.hpp ├── LICENSE ├── README.md └── deque ├── data ├── class-bint.hpp ├── class-integer.hpp ├── class-matrix.hpp ├── five │ ├── answer.txt │ └── code.cpp ├── four.memcheck │ ├── answer.txt │ └── code.cpp ├── four │ ├── answer.txt │ └── code.cpp ├── one.memcheck │ ├── answer.txt │ └── code.cpp ├── one │ ├── answer.txt │ └── code.cpp ├── six │ ├── answer.txt │ └── code.cpp ├── three.memcheck │ ├── answer.txt │ └── code.cpp ├── three │ ├── answer.txt │ └── code.cpp ├── two.memcheck │ ├── answer.txt │ └── code.cpp └── two │ ├── answer.txt │ └── code.cpp ├── deque.hpp ├── exceptions.hpp └── utility.hpp /BTree/BTree.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 郑文鑫 on 2019-03-09. 3 | // 4 | 5 | #include "utility.hpp" 6 | #include 7 | #include 8 | #include "exception.hpp" 9 | #include 10 | namespace sjtu { 11 | template > 12 | class BTree { 13 | private: 14 | // Your private members go here 15 | public: 16 | typedef pair value_type; 17 | 18 | 19 | class const_iterator; 20 | class iterator { 21 | private: 22 | // Your private members go here 23 | public: 24 | bool modify(const Value& value){ 25 | 26 | } 27 | iterator() { 28 | // TODO Default Constructor 29 | } 30 | iterator(const iterator& other) { 31 | // TODO Copy Constructor 32 | } 33 | // Return a new iterator which points to the n-next elements 34 | iterator operator++(int) { 35 | // Todo iterator++ 36 | } 37 | iterator& operator++() { 38 | // Todo ++iterator 39 | } 40 | iterator operator--(int) { 41 | // Todo iterator-- 42 | } 43 | iterator& operator--() { 44 | // Todo --iterator 45 | } 46 | // Overloaded of operator '==' and '!=' 47 | // Check whether the iterators are same 48 | bool operator==(const iterator& rhs) const { 49 | // Todo operator == 50 | } 51 | bool operator==(const const_iterator& rhs) const { 52 | // Todo operator == 53 | } 54 | bool operator!=(const iterator& rhs) const { 55 | // Todo operator != 56 | } 57 | bool operator!=(const const_iterator& rhs) const { 58 | // Todo operator != 59 | } 60 | }; 61 | class const_iterator { 62 | // it should has similar member method as iterator. 63 | // and it should be able to construct from an iterator. 64 | private: 65 | // Your private members go here 66 | public: 67 | const_iterator() { 68 | // TODO 69 | } 70 | const_iterator(const const_iterator& other) { 71 | // TODO 72 | } 73 | const_iterator(const iterator& other) { 74 | // TODO 75 | } 76 | // And other methods in iterator, please fill by yourself. 77 | }; 78 | // Default Constructor and Copy Constructor 79 | BTree() { 80 | // Todo Default 81 | } 82 | BTree(const BTree& other) { 83 | // Todo Copy 84 | } 85 | BTree& operator=(const BTree& other) { 86 | // Todo Assignment 87 | } 88 | ~BTree() { 89 | // Todo Destructor 90 | } 91 | // Insert: Insert certain Key-Value into the database 92 | // Return a pair, the first of the pair is the iterator point to the new 93 | // element, the second of the pair is Success if it is successfully inserted 94 | pair insert(const Key& key, const Value& value) { 95 | 96 | } 97 | // Erase: Erase the Key-Value 98 | // Return Success if it is successfully erased 99 | // Return Fail if the key doesn't exist in the database 100 | OperationResult erase(const Key& key) { 101 | // TODO erase function 102 | return Fail; // If you can't finish erase part, just remaining here. 103 | } 104 | // Return a iterator to the beginning 105 | iterator begin() {} 106 | const_iterator cbegin() const {} 107 | // Return a iterator to the end(the next element after the last) 108 | iterator end() {} 109 | const_iterator cend() const {} 110 | // Check whether this BTree is empty 111 | bool empty() const {} 112 | // Return the number of pairs 113 | size_t size() const {} 114 | // Clear the BTree 115 | void clear() {} 116 | // Return the value refer to the Key(key) 117 | Value at(const Key& key){ 118 | } 119 | /** 120 | * Returns the number of elements with key 121 | * that compares equivalent to the specified argument, 122 | * The default method of check the equivalence is !(a < b || b > a) 123 | */ 124 | size_t count(const Key& key) const {} 125 | /** 126 | * Finds an element with key equivalent to key. 127 | * key value of the element to search for. 128 | * Iterator to an element with key equivalent to key. 129 | * If no such element is found, past-the-end (see end()) iterator is 130 | * returned. 131 | */ 132 | iterator find(const Key& key) {} 133 | const_iterator find(const Key& key) const {} 134 | }; 135 | } // namespace sjtu 136 | 137 | -------------------------------------------------------------------------------- /BTree/data/class-bint.hpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace Util { 9 | 10 | const size_t MIN_CAPACITY = 2048; 11 | 12 | class Bint { 13 | class NewSpaceFailed : public std::runtime_error { 14 | public: 15 | NewSpaceFailed(); 16 | }; 17 | class BadCast : public std::invalid_argument { 18 | public: 19 | BadCast(); 20 | }; 21 | bool isMinus = false; 22 | size_t length; 23 | int *data = nullptr; 24 | size_t capacity = MIN_CAPACITY; 25 | void _DoubleSpace(); 26 | void _SafeNewSpace(int *&p, const size_t &len); 27 | explicit Bint(const size_t &capa); 28 | public: 29 | Bint(); 30 | Bint(int x); 31 | Bint(long long x); 32 | Bint(std::string x); 33 | Bint(const Bint &b); 34 | Bint(Bint &&b) noexcept; 35 | 36 | Bint &operator=(int rhs); 37 | Bint &operator=(long long rhs); 38 | Bint &operator=(const Bint &rhs); 39 | Bint &operator=(Bint &&rhs) noexcept; 40 | 41 | friend Bint abs(const Bint &x); 42 | friend Bint abs(Bint &&x); 43 | 44 | friend bool operator==(const Bint &lhs, const Bint &rhs); 45 | friend bool operator!=(const Bint &lhs, const Bint &rhs); 46 | friend bool operator<(const Bint &lhs, const Bint &rhs); 47 | friend bool operator>(const Bint &lhs, const Bint &rhs); 48 | friend bool operator<=(const Bint &lhs, const Bint &rhs); 49 | friend bool operator>=(const Bint &lhs, const Bint &rhs); 50 | 51 | friend Bint operator+(const Bint &lhs, const Bint &rhs); 52 | friend Bint operator-(const Bint &b); 53 | friend Bint operator-(Bint &&b); 54 | friend Bint operator-(const Bint &lhs, const Bint &rhs); 55 | friend Bint operator*(const Bint &lhs, const Bint &rhs); 56 | 57 | friend std::istream &operator>>(std::istream &is, Bint &b); 58 | friend std::ostream &operator<<(std::ostream &os, const Bint &b); 59 | 60 | ~Bint(); 61 | }; 62 | } 63 | 64 | #include 65 | #include 66 | 67 | namespace Util { 68 | 69 | Bint::NewSpaceFailed::NewSpaceFailed() : std::runtime_error("No Enough Memory Space.") {} 70 | Bint::BadCast::BadCast() : std::invalid_argument("Cannot convert to a Bint object") {} 71 | 72 | void Bint::_SafeNewSpace(int *&p, const size_t &len) 73 | { 74 | if (p != nullptr) { 75 | delete[] p; 76 | p = nullptr; 77 | } 78 | p = new int[len]; 79 | if (p == nullptr) { 80 | throw NewSpaceFailed(); 81 | } 82 | memset(p, 0, len * sizeof(unsigned int)); 83 | } 84 | 85 | void Bint::_DoubleSpace() 86 | { 87 | int *newMem = nullptr; 88 | _SafeNewSpace(newMem, capacity << 1); 89 | memcpy(newMem, data, capacity * sizeof(int)); 90 | delete[] data; 91 | data = newMem; 92 | capacity <<= 1; 93 | } 94 | 95 | Bint::Bint() 96 | : length(1) 97 | { 98 | _SafeNewSpace(data, capacity); 99 | } 100 | 101 | Bint::Bint(int x) 102 | : length(0) 103 | { 104 | _SafeNewSpace(data, capacity); 105 | if (x < 0) { 106 | isMinus = true; 107 | x = -x; 108 | } 109 | while (x) { 110 | data[length++] = x % 10000; 111 | x /= 10000; 112 | } 113 | if (!length) { 114 | length = 1; 115 | } 116 | } 117 | 118 | Bint::Bint(long long x) 119 | : length(0) 120 | { 121 | _SafeNewSpace(data, capacity); 122 | if (x < 0) { 123 | isMinus = true; 124 | x = -x; 125 | } 126 | while (x) { 127 | data[length++] = static_cast(x % 10000); 128 | x /= 10000; 129 | } 130 | if (!length) { 131 | length = 1; 132 | } 133 | } 134 | 135 | Bint::Bint(const size_t &capa) 136 | : length(1) 137 | { 138 | while (capacity < capa) { 139 | capacity <<= 1; 140 | } 141 | _SafeNewSpace(data, capacity); 142 | } 143 | 144 | Bint::Bint(std::string x) 145 | { 146 | while (x[0] == '-') { 147 | isMinus = !isMinus; 148 | x.erase(0, 1); 149 | } 150 | while ((capacity << 2) <= x.length()) { 151 | capacity <<= 1; 152 | } 153 | 154 | _SafeNewSpace(data, capacity); 155 | 156 | size_t mid = x.length() >> 1; 157 | for (size_t i = 0; i < mid; ++i) { 158 | std::swap(x[i], x[x.length() - 1 - i]); 159 | } 160 | 161 | const static unsigned int pow10[4] = {1, 10, 100, 1000}; 162 | for (size_t i = 0; i < capacity; ++i) { 163 | if ((i << 2) >= x.length()) { 164 | length = i; 165 | break; 166 | } 167 | for (size_t j = 0; j < 4; ++j) { 168 | if ((i << 2) + j >= x.length()) { 169 | break; 170 | } 171 | if (x[(i << 2) + j] > '9' || x[(i << 2) + j] < '0') { 172 | throw BadCast(); 173 | } 174 | data[i] = data[i] + (x[(i << 2) + j] - '0') * pow10[j]; 175 | } 176 | } 177 | } 178 | 179 | Bint::Bint(const Bint &b) 180 | : isMinus(b.isMinus), length(b.length), capacity(b.capacity) 181 | { 182 | _SafeNewSpace(data, capacity); 183 | memcpy(data, b.data, sizeof(unsigned int) * capacity); 184 | } 185 | 186 | Bint::Bint(Bint &&b) noexcept 187 | : isMinus(b.isMinus), length(b.length), capacity(b.capacity) 188 | { 189 | data = b.data; 190 | b.data = nullptr; 191 | } 192 | 193 | Bint &Bint::operator=(int x) 194 | { 195 | memset(data, 0, sizeof(unsigned int) * capacity); 196 | length = 0; 197 | if (x < 0) { 198 | isMinus = true; 199 | x = -x; 200 | } 201 | while (x) { 202 | data[length++] = x % 10000; 203 | x /= 10000; 204 | } 205 | if (!length) { 206 | length = 1; 207 | } 208 | return *this; 209 | } 210 | 211 | Bint &Bint::operator=(long long x) 212 | { 213 | memset(data, 0, sizeof(unsigned int) * capacity); 214 | length = 0; 215 | if (x < 0) { 216 | isMinus = true; 217 | x = -x; 218 | } 219 | while (x) { 220 | data[length++] = static_cast(x % 10000); 221 | x /= 10000; 222 | } 223 | if (!length) { 224 | length = 1; 225 | } 226 | return *this; 227 | } 228 | 229 | Bint &Bint::operator=(const Bint &rhs) 230 | { 231 | if (this == &rhs) { 232 | return *this; 233 | } 234 | if (rhs.capacity > capacity) { 235 | capacity = rhs.capacity; 236 | _SafeNewSpace(data, capacity); 237 | } 238 | memcpy(data, rhs.data, sizeof(unsigned int) * rhs.capacity); 239 | length = rhs.length; 240 | isMinus = rhs.isMinus; 241 | return *this; 242 | } 243 | 244 | Bint &Bint::operator=(Bint &&rhs) noexcept 245 | { 246 | if (this == &rhs) { 247 | return *this; 248 | } 249 | capacity = rhs.capacity; 250 | length = rhs.length; 251 | isMinus = rhs.isMinus; 252 | data = rhs.data; 253 | rhs.data = nullptr; 254 | return *this; 255 | } 256 | 257 | std::istream &operator>>(std::istream &is, Bint &b) 258 | { 259 | std::string s; 260 | is >> s; 261 | b = Bint(s); 262 | return is; 263 | } 264 | 265 | std::ostream &operator<<(std::ostream &os, const Bint &b) 266 | { 267 | if (b.data == nullptr) { 268 | return os; 269 | } 270 | if (b.isMinus && (b.length > 1 || b.data[0] != 0)) { 271 | os << "-"; 272 | } 273 | os << b.data[b.length - 1]; 274 | for (long long i = b.length - 2LL; i >= 0; --i) { 275 | os << std::setw(4) << std::setfill('0') << b.data[i]; 276 | } 277 | return os; 278 | } 279 | 280 | Bint abs(const Bint &b) 281 | { 282 | Bint result(b); 283 | result.isMinus = false; 284 | return result; 285 | } 286 | 287 | Bint abs(Bint &&b) 288 | { 289 | b.isMinus = false; 290 | return b; 291 | } 292 | 293 | bool operator==(const Bint &lhs, const Bint &rhs) 294 | { 295 | if (lhs.isMinus != rhs.isMinus) { 296 | return false; 297 | } 298 | if (lhs.length != rhs.length) { 299 | return false; 300 | } 301 | for (size_t i = 0; i < lhs.length; ++i) { 302 | if (lhs.data[i] != rhs.data[i]) { 303 | return false; 304 | } 305 | } 306 | return true; 307 | } 308 | 309 | bool operator!=(const Bint &lhs, const Bint &rhs) 310 | { 311 | if (lhs.isMinus != rhs.isMinus) { 312 | return true; 313 | } 314 | if (lhs.length != rhs.length) { 315 | return true; 316 | } 317 | for (size_t i = 0; i < lhs.length; ++i) { 318 | if (lhs.data[i] != rhs.data[i]) { 319 | return true; 320 | } 321 | } 322 | return false; 323 | } 324 | 325 | bool operator<(const Bint &lhs, const Bint &rhs) 326 | { 327 | if (lhs.isMinus != rhs.isMinus) { 328 | return !lhs.isMinus; 329 | } 330 | if (lhs.isMinus) { 331 | if (lhs.length != rhs.length) { 332 | return lhs.length > rhs.length; 333 | } 334 | for (long long i = lhs.length - 1; i >= 0; --i) { 335 | if (lhs.data[i] != rhs.data[i]) { 336 | return lhs.data[i] > rhs.data[i]; 337 | } 338 | } 339 | return false; 340 | } else { 341 | if (lhs.length != rhs.length) { 342 | return lhs.length < rhs.length; 343 | } 344 | for (long long i = lhs.length - 1; i >= 0; --i) { 345 | if (lhs.data[i] != rhs.data[i]) { 346 | return lhs.data[i] < rhs.data[i]; 347 | } 348 | } 349 | return false; 350 | } 351 | } 352 | 353 | bool operator>(const Bint &lhs, const Bint &rhs) 354 | { 355 | return rhs < lhs; 356 | } 357 | 358 | bool operator<=(const Bint &lhs, const Bint &rhs) 359 | { 360 | if (lhs.isMinus != rhs.isMinus) { 361 | return !lhs.isMinus; 362 | } 363 | if (lhs.isMinus) { 364 | if (lhs.length != rhs.length) { 365 | return lhs.length > rhs.length; 366 | } 367 | for (long long i = lhs.length - 1; i >= 0; --i) { 368 | if (lhs.data[i] != rhs.data[i]) { 369 | return lhs.data[i] > rhs.data[i]; 370 | } 371 | } 372 | return true; 373 | } else { 374 | if (lhs.length != rhs.length) { 375 | return lhs.length < rhs.length; 376 | } 377 | for (long long i = lhs.length - 1; i >= 0; --i) { 378 | if (lhs.data[i] != rhs.data[i]) { 379 | return lhs.data[i] < rhs.data[i]; 380 | } 381 | } 382 | return true; 383 | } 384 | } 385 | 386 | bool operator>=(const Bint &lhs, const Bint &rhs) 387 | { 388 | if (lhs.isMinus != rhs.isMinus) { 389 | return lhs.isMinus; 390 | } 391 | if (lhs.isMinus) { 392 | if (lhs.length != rhs.length) { 393 | return lhs.length < rhs.length; 394 | } 395 | for (long long i = lhs.length - 1; i >= 0; --i) { 396 | if (lhs.data[i] != rhs.data[i]) { 397 | return lhs.data[i] < rhs.data[i]; 398 | } 399 | } 400 | return true; 401 | } else { 402 | if (lhs.length != rhs.length) { 403 | return lhs.length > rhs.length; 404 | } 405 | for (long long i = lhs.length - 1; i >= 0; --i) { 406 | if (lhs.data[i] != rhs.data[i]) { 407 | return lhs.data[i] > rhs.data[i]; 408 | } 409 | } 410 | return true; 411 | } 412 | } 413 | 414 | 415 | Bint operator+(const Bint &lhs, const Bint &rhs) 416 | { 417 | if (lhs.isMinus == rhs.isMinus) { 418 | size_t maxLen = std::max(lhs.length, rhs.length); 419 | size_t expectLen = maxLen + 1; 420 | Bint result(expectLen); // special constructor 421 | for (size_t i = 0; i < maxLen; ++i) { 422 | result.data[i] = lhs.data[i] + rhs.data[i]; 423 | } 424 | for (size_t i = 0; i < maxLen; ++i) { 425 | if (result.data[i] > 10000) { 426 | result.data[i] -= 10000; 427 | ++result.data[i + 1]; 428 | } 429 | } 430 | result.length = result.data[maxLen] > 0 ? maxLen + 1 : maxLen; 431 | result.isMinus = lhs.isMinus; 432 | return result; 433 | } else { 434 | if (lhs.isMinus) { 435 | return rhs - abs(lhs); 436 | } else { 437 | return lhs - abs(rhs); 438 | } 439 | } 440 | } 441 | 442 | Bint operator-(const Bint &b) 443 | { 444 | Bint result(b); 445 | result.isMinus = !result.isMinus; 446 | return result; 447 | } 448 | 449 | Bint operator-(Bint &&b) 450 | { 451 | b.isMinus = !b.isMinus; 452 | return b; 453 | } 454 | 455 | Bint operator-(const Bint &lhs, const Bint &rhs) 456 | { 457 | if (lhs.isMinus == rhs.isMinus) { 458 | if (lhs.isMinus) { 459 | return -(abs(lhs) - abs(rhs)); 460 | } else { 461 | if (lhs < rhs) { 462 | return -(rhs - lhs); 463 | } 464 | Bint result(std::max(lhs.length, rhs.length)); 465 | for (size_t i = 0; i < lhs.length; ++i) { 466 | result.data[i] = lhs.data[i] - rhs.data[i]; 467 | } 468 | for (size_t i = 0; i < lhs.length; ++i) { 469 | if (result.data[i] < 0) { 470 | result.data[i] += 10000; 471 | ++result.data[i + 1]; 472 | } 473 | } 474 | while (result.length > 1 && result.data[result.length - 1] == 0) { 475 | --result.length; 476 | } 477 | return result; 478 | } 479 | } else { 480 | return lhs + (-rhs); 481 | } 482 | } 483 | 484 | Bint operator*(const Bint &lhs, const Bint &rhs) 485 | { 486 | size_t expectLen = lhs.length + rhs.length + 2; 487 | Bint result(expectLen); 488 | for (size_t i = 0; i < lhs.length; ++i) { 489 | for (size_t j = 0; j < rhs.length; ++j) { 490 | long long tmp = result.data[i + j] + static_cast(lhs.data[i]) * rhs.data[j]; 491 | if (tmp >= 10000) { 492 | result.data[i + j] = tmp % 10000; 493 | result.data[i + j + 1] += static_cast(tmp / 10000); 494 | } else { 495 | result.data[i + j] = tmp; 496 | } 497 | } 498 | } 499 | result.length = lhs.length + rhs.length -1; 500 | while (result.data[result.length] > 0) { 501 | ++result.length; 502 | } 503 | while (result.length > 1 && result.data[result.length - 1] == 0) { 504 | --result.length; 505 | } 506 | return result; 507 | } 508 | 509 | Bint::~Bint() 510 | { 511 | if (data != nullptr) { 512 | delete[] data; 513 | data = nullptr; 514 | } 515 | } 516 | } 517 | -------------------------------------------------------------------------------- /BTree/data/class-integer.hpp: -------------------------------------------------------------------------------- 1 | class Integer { 2 | private: 3 | int data; 4 | public: 5 | Integer(const int &value) : data(value) {} 6 | Integer(const Integer &other) : data(other.data) {} 7 | bool operator==(const Integer &t) 8 | { 9 | return data == t.data; 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /BTree/data/class-matrix.hpp: -------------------------------------------------------------------------------- 1 | #ifndef DIAMOND_MATRIX_HPP 2 | #define DIAMOND_MATRIX_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace Diamond { 10 | 11 | template 12 | class Matrix { 13 | protected: 14 | size_t n_rows = 0; 15 | size_t n_cols = 0; 16 | std::vector> data; 17 | class RowProxy { 18 | std::vector<_Td> &row; 19 | public: 20 | RowProxy(std::vector<_Td> & _row) : row(_row) {} 21 | _Td & operator[](const size_t &pos) 22 | { 23 | return row[pos]; 24 | } 25 | }; 26 | class ConstRowProxy { 27 | const std::vector<_Td> &row; 28 | public: 29 | ConstRowProxy(const std::vector<_Td> &_row) : row(_row) {} 30 | const _Td & operator[](const size_t &pos) const 31 | { 32 | return row[pos]; 33 | } 34 | }; 35 | public: 36 | Matrix() {}; 37 | Matrix(const size_t &_n_rows, const size_t &_n_cols) 38 | : n_rows(_n_rows), n_cols(_n_cols), data(std::vector>(n_rows, std::vector<_Td>(n_cols))) {} 39 | Matrix(const size_t &_n_rows, const size_t &_n_cols, const _Td &fillValue) 40 | : n_rows(_n_rows), n_cols(_n_cols), data(std::vector>(n_rows, std::vector<_Td>(n_cols, fillValue))) {} 41 | Matrix(const Matrix<_Td> &mat) 42 | : n_rows(mat.n_rows), n_cols(mat.n_cols), data(mat.data) {} 43 | Matrix(Matrix<_Td> &&mat) noexcept 44 | : n_rows(mat.n_rows), n_cols(mat.n_cols), data(mat.data) {} 45 | Matrix<_Td> & operator=(const Matrix<_Td> &rhs) 46 | { 47 | this->n_rows = rhs.n_rows; 48 | this->n_cols = rhs.n_cols; 49 | this->data = rhs.data; 50 | return *this; 51 | } 52 | Matrix<_Td> & operator=(Matrix<_Td> &&rhs) 53 | { 54 | this->n_rows = rhs.n_rows; 55 | this->n_cols = rhs.n_cols; 56 | this->data = rhs.data; 57 | return *this; 58 | } 59 | inline const size_t & RowSize() const 60 | { 61 | return n_rows; 62 | } 63 | inline const size_t & ColSize() const 64 | { 65 | return n_cols; 66 | } 67 | RowProxy operator[](const size_t &Kth) 68 | { 69 | return RowProxy(this->data[Kth]); 70 | } 71 | const ConstRowProxy operator[](const size_t &Kth) const 72 | { 73 | return ConstRowProxy(this->data[Kth]); 74 | } 75 | ~Matrix() = default; 76 | }; 77 | 78 | /** 79 | * Sum of two matrics. 80 | */ 81 | template 82 | Matrix<_Td> operator+(const Matrix<_Td> &a, const Matrix<_Td> &b) 83 | { 84 | if (a.RowSize() != b.RowSize() || a.ColSize() != b.ColSize()) { 85 | throw std::invalid_argument("different matrics\'s sizes"); 86 | } 87 | Matrix<_Td> c(a.RowSize(), a.ColSize()); 88 | for (size_t i = 0; i < a.RowSize(); ++i) { 89 | for (size_t j = 0; j < a.ColSize(); ++j) { 90 | c[i][j] = a[i][j] + b[i][j]; 91 | } 92 | } 93 | return c; 94 | } 95 | 96 | template 97 | Matrix<_Td> operator-(const Matrix<_Td> &a, const Matrix<_Td> &b) 98 | { 99 | if (a.RowSize() != b.RowSize() || a.ColSize() != b.ColSize()) { 100 | throw std::invalid_argument("different matrics\'s sizes"); 101 | } 102 | Matrix<_Td> c(a.RowSize(), a.ColSize()); 103 | for (size_t i = 0; i < a.RowSize(); ++i) { 104 | for (size_t j = 0; j < a.ColSize(); ++j) { 105 | c[i][j] = a[i][j] - b[i][j]; 106 | } 107 | } 108 | return c; 109 | } 110 | template 111 | bool operator==(const Matrix<_Td> &a, const Matrix<_Td> &b) 112 | { 113 | if (a.RowSize() != b.RowSize() || a.ColSize() != b.ColSize()) { 114 | return false; 115 | } 116 | for (size_t i = 0; i < a.RowSize(); ++i) { 117 | for (size_t j = 0; j < a.ColSize(); ++j) { 118 | if (a[i][j] != b[i][j]) 119 | return false; 120 | } 121 | } 122 | return true; 123 | } 124 | 125 | template 126 | Matrix<_Td> operator-(const Matrix<_Td> &mat) 127 | { 128 | Matrix<_Td> result(mat.RowSize(), mat.ColSize()); 129 | for (size_t i = 0; i < mat.RowSize(); ++i) { 130 | for (size_t j = 0; j < mat.ColSize(); ++j) { 131 | result[i][j] = -mat[i][j]; 132 | } 133 | } 134 | return result; 135 | } 136 | 137 | template 138 | Matrix<_Td> operator-(Matrix<_Td> &&mat) 139 | { 140 | for (size_t i = 0; i < mat.RowSize(); ++i) { 141 | for (size_t j = 0; j < mat.ColSize(); ++j) { 142 | mat[i][j] = -mat[i][j]; 143 | } 144 | } 145 | return mat; 146 | } 147 | 148 | /** 149 | * Multiplication of two matrics. 150 | */ 151 | template 152 | Matrix<_Td> operator*(const Matrix<_Td> &a, const Matrix<_Td> &b) 153 | { 154 | if (a.ColSize() != b.RowSize()) { 155 | throw std::invalid_argument("different matrics\'s sizes"); 156 | } 157 | Matrix<_Td> c(a.RowSize(), b.ColSize(), 0); 158 | for (size_t i = 0; i < a.RowSize(); ++i) { 159 | for (size_t j = 0; j < b.ColSize(); ++j) { 160 | for (size_t k = 0; k < a.ColSize(); ++k) { 161 | c[i][j] += a[i][k] * b[k][j]; 162 | } 163 | } 164 | } 165 | return c; 166 | } 167 | 168 | /** 169 | * Operations between a number and a matrix; 170 | */ 171 | template 172 | Matrix<_Td> operator*(const Matrix<_Td> &a, const _Td &b) 173 | { 174 | Matrix<_Td> c(a.RowSize(), a.ColSize()); 175 | for (size_t i = 0; i < a.RowSize(); ++i) { 176 | for (size_t j = 0; j < a.ColSize(); ++j) { 177 | c[i][j] = a[i][j] * b; 178 | } 179 | } 180 | return c; 181 | } 182 | 183 | template 184 | Matrix<_Td> operator*(const _Td &b, const Matrix<_Td> &a) 185 | { 186 | Matrix<_Td> c(a.RowSize(), a.ColSize()); 187 | for (size_t i = 0; i < a.RowSize(); ++i) { 188 | for (size_t j = 0; j < a.ColSize(); ++j) { 189 | c[i][j] = a[i][j] * b; 190 | } 191 | } 192 | return c; 193 | } 194 | 195 | template 196 | Matrix<_Td> operator/(const Matrix<_Td> &a, const double &b) 197 | { 198 | Matrix<_Td> c(a.RowSize(), a.ColSize()); 199 | for (size_t i = 0; i < a.RowSize(); ++i) { 200 | for (size_t j = 0; j < a.ColSize(); ++j) { 201 | c[i][j] = a[i][j] / b; 202 | } 203 | } 204 | return c; 205 | } 206 | 207 | template 208 | Matrix<_Td> Transpose(const Matrix<_Td> &a) 209 | { 210 | Matrix<_Td> res(a.ColSize(), a.RowSize()); 211 | for (size_t i = 0; i < a.ColSize(); ++i) { 212 | for (size_t j = 0; j < a.RowSize(); ++j) { 213 | res[i][j] = a[j][i]; 214 | } 215 | } 216 | return res; 217 | } 218 | 219 | template 220 | std::ostream & operator<<(std::ostream &stream, const Matrix<_Td> &mat) 221 | { 222 | std::ostream::fmtflags oldFlags = stream.flags(); 223 | stream.precision(8); 224 | stream.setf(std::ios::fixed | std::ios::right); 225 | 226 | stream << '\n'; 227 | for (size_t i = 0; i < mat.RowSize(); ++i) { 228 | for (size_t j = 0; j < mat.ColSize(); ++j) { 229 | stream << std::setw(15) << mat[i][j]; 230 | } 231 | stream << '\n'; 232 | } 233 | 234 | stream.flags(oldFlags); 235 | return stream; 236 | } 237 | 238 | template 239 | Matrix<_Td> I(const size_t &n) 240 | { 241 | Matrix<_Td> res(n, n, 0); 242 | for (size_t i = 0; i < n; ++i) { 243 | res[i][i] = static_cast<_Td>(1); 244 | } 245 | return res; 246 | } 247 | 248 | template 249 | Matrix<_Td> Pow(Matrix<_Td> A, size_t &b) 250 | { 251 | if (A.RowSize() != A.ColSize()) { 252 | throw std::invalid_argument("The row size and column size are different."); 253 | } 254 | Matrix<_Td> result = I<_Td>(A.ColSize()); 255 | while (b > 0) { 256 | if (b & static_cast(1)) { 257 | result = result * A; 258 | } 259 | A = A * A; 260 | b = b >> static_cast(1); 261 | } 262 | return result; 263 | } 264 | 265 | } 266 | #endif 267 | -------------------------------------------------------------------------------- /BTree/data/one/BTree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "BTree.hpp" 5 | // test: constructor 6 | using namespace std; 7 | sjtu::BTree bTree; 8 | void insert(int key, int value){ 9 | bTree.insert(key, value); 10 | } 11 | 12 | 13 | void erase(int key){ 14 | bTree.erase(key); 15 | } 16 | 17 | int query(int key){ 18 | return bTree.at(key); 19 | } 20 | 21 | 22 | void tester(){ 23 | int key, value; 24 | char cmd; 25 | while(cin >> cmd){ 26 | if(cmd == 'i'){ 27 | cin >> key >> value; 28 | insert(key, value); 29 | }else 30 | if(cmd == 'e'){ 31 | cin >> key; 32 | erase(key); 33 | }else 34 | if(cmd == 'q'){ 35 | cin >> key; 36 | cout << query(key) << endl; 37 | }else{ 38 | puts("bad_command"); 39 | } 40 | } 41 | } 42 | 43 | int main(){ 44 | tester(); 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /BTree/data/one/BTree.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 郑文鑫 on 2019-03-09. 3 | // 4 | 5 | #include "utility.hpp" 6 | #include 7 | #include 8 | #include "exception.hpp" 9 | #include 10 | #include 11 | namespace sjtu { 12 | template > 13 | class BTree { 14 | private: 15 | // Your private members go here 16 | std::fstream fileIO; 17 | std::map _core; 18 | public: 19 | typedef pair value_type; 20 | 21 | const std::map &getCore() const; 22 | 23 | class const_iterator; 24 | class iterator { 25 | private: 26 | // Your private members go here 27 | public: 28 | bool modify(const Value& value){ 29 | 30 | } 31 | iterator() { 32 | // TODO Default Constructor 33 | } 34 | iterator(const iterator& other) { 35 | // TODO Copy Constructor 36 | } 37 | // Return a new iterator which points to the n-next elements 38 | iterator operator++(int) { 39 | // Todo iterator++ 40 | } 41 | iterator& operator++() { 42 | // Todo ++iterator 43 | } 44 | iterator operator--(int) { 45 | // Todo iterator-- 46 | } 47 | iterator& operator--() { 48 | // Todo --iterator 49 | } 50 | // Overloaded of operator '==' and '!=' 51 | // Check whether the iterators are same 52 | bool operator==(const iterator& rhs) const { 53 | // Todo operator == 54 | } 55 | bool operator==(const const_iterator& rhs) const { 56 | // Todo operator == 57 | } 58 | bool operator!=(const iterator& rhs) const { 59 | // Todo operator != 60 | } 61 | bool operator!=(const const_iterator& rhs) const { 62 | // Todo operator != 63 | } 64 | }; 65 | class const_iterator { 66 | // it should has similar member method as iterator. 67 | // and it should be able to construct from an iterator. 68 | private: 69 | // Your private members go here 70 | public: 71 | const_iterator() { 72 | // TODO 73 | } 74 | const_iterator(const const_iterator& other) { 75 | // TODO 76 | } 77 | const_iterator(const iterator& other) { 78 | // TODO 79 | } 80 | // And other methods in iterator, please fill by yourself. 81 | }; 82 | // Default Constructor and Copy Constructor 83 | BTree() { 84 | std::ifstream ifs("target.txt"); 85 | int sizeT; 86 | if(ifs){ 87 | ifs >> sizeT; 88 | // std::cout << "[Debug IO Init] size:" << sizeT << std::endl; 89 | for(int i = 0; i < sizeT; ++i){ 90 | Key key; 91 | Value value; 92 | ifs >> key >> value; 93 | // std::cout << "[Debug IO Read] " << key << "->" << value; 94 | _core.insert(std::make_pair(key, value)); 95 | } 96 | } else{ 97 | std::cout << "Initial"; 98 | } 99 | 100 | } 101 | BTree(const BTree& other) { 102 | // Todo Copy 103 | } 104 | BTree& operator=(const BTree& other) { 105 | // Todo Assignment 106 | } 107 | ~BTree() { 108 | fileIO.open("target.txt", std::ios::in | std::ios::out | std::ios::trunc); 109 | fileIO << _core.size() << "\n"; 110 | for(auto it = _core.begin(); it != _core.end(); it++) { 111 | fileIO << it->first << std::endl; 112 | fileIO << it->second << std::endl; 113 | // std::cout << "[Debug IO Write] " << it->first << "->" << it->second << std::endl; 114 | 115 | } 116 | fileIO.close(); 117 | // Todo Destructor 118 | } 119 | pair insert(const Key& key, const Value& value) { 120 | // std::cout << "[Insertion Debug] " << key << "->" << value << std::endl; 121 | auto result = _core.insert(std::pair(key, value)); 122 | if(result.second == false) return pair(iterator(), Fail); 123 | else return pair(iterator(), Success); 124 | } 125 | // Erase: Erase the Key-Value 126 | // Return Success if it is successfully erased 127 | // Return Fail if the key doesn't exist in the database 128 | OperationResult erase(const Key& key) { 129 | // TODO erase function 130 | return Fail; // If you can't finish erase part, just remaining here. 131 | } 132 | bool empty() const { return _core.empty(); } 133 | // Return the number of pairs 134 | size_t size() const { return _core.size(); } 135 | Value at(const Key& key){ 136 | return _core[key]; 137 | } 138 | }; 139 | 140 | template 141 | const std::map &BTree::getCore() const { 142 | return _core; 143 | } 144 | } // namespace sjtu 145 | 146 | 147 | -------------------------------------------------------------------------------- /BTree/data/one/InsertionTest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | sqlite3 *db; 10 | vector results; 11 | 12 | /// 13 | /// 14 | /// useless function 15 | /// 16 | static int callback(void *NotUsed, int argc, char **argv, char **azColName) { 17 | int i; 18 | for (i = 0; i < argc; i++) { 19 | printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL"); 20 | } 21 | printf("\n"); 22 | return 0; 23 | } 24 | 25 | // 26 | // 27 | // use for query in splite 28 | // 29 | // 30 | static int query_callback(void *para, int nCount, char **pValue, char **pName) { 31 | string s; 32 | for (int i = 0; i < nCount; i++) { 33 | if (i % 2) { 34 | // s+=pValue[i]; 35 | // s+="\n"; 36 | results.push_back(atoi(pValue[i])); 37 | } 38 | } 39 | cout << s << endl; 40 | return 0; 41 | } 42 | 43 | // 44 | // 45 | // use for open database in splite 46 | // 47 | // 48 | void open_database(char *filename) { 49 | /* Open database */ 50 | int rc; 51 | rc = sqlite3_open(filename, &db); 52 | if (rc) { 53 | fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); 54 | exit(0); 55 | } else { 56 | fprintf(stdout, "Opened database successfully\n"); 57 | } 58 | } 59 | 60 | // 61 | // 62 | // use for create database in splite 63 | // 64 | // 65 | 66 | void create_database() { 67 | // if(db == NULL) fprintf(stderr, "No database: %s\n", zErrMsg); 68 | /* Create SQL statement */ 69 | int rc; 70 | char *zErrMsg = 0; 71 | char sql[300]; 72 | sprintf(sql, 73 | "CREATE TABLE PAIR(" 74 | "Key INT PRIMARY KEY," 75 | "Value INT);"); 76 | /* Execute SQL statement */ 77 | rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); 78 | if (rc != SQLITE_OK) { 79 | fprintf(stderr, "SQL error: %s\n", zErrMsg); 80 | sqlite3_free(zErrMsg); 81 | } else { 82 | fprintf(stdout, "Table created successfully\n"); 83 | } 84 | } 85 | 86 | // 87 | // 88 | // use for clearup database in splite 89 | // 90 | // 91 | void Dropout() { 92 | char sql[300]; 93 | char *zErrMsg = 0; 94 | sprintf(sql, "DROP TABLE 'PAIR';"); 95 | // int rc = 0; 96 | int rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); 97 | if (rc != SQLITE_OK) { 98 | fprintf(stderr, "SQL_Dropout error: %s\n", zErrMsg); 99 | //注意,执行失败,需要清理错误码的内存空间 100 | sqlite3_free(zErrMsg); 101 | } else { 102 | fprintf(stdout, "Records Dropout successfully\n"); 103 | } 104 | } 105 | 106 | // 107 | // 108 | // use for insert database in splite 109 | // 110 | // 111 | void insert(int key, int value) { 112 | char sql[300]; 113 | char *zErrMsg = 0; 114 | sprintf(sql, 115 | "INSERT INTO PAIR VALUES( \ 116 | %d ,%d);", 117 | key, value); 118 | 119 | /* Execute SQL statement */ 120 | int rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); 121 | if (rc != SQLITE_OK) { 122 | fprintf(stderr, "SQL error: %s\n", zErrMsg); 123 | sqlite3_free(zErrMsg); 124 | } else { 125 | // fprintf(stdout, "insert successfully\n"); 126 | } 127 | } 128 | 129 | // 130 | // 131 | // use for erase database in splite 132 | // 133 | // 134 | bool erase(int key) { 135 | char sql[3000]; 136 | char *zErrMsg = 0; 137 | sprintf(sql, "DELETE FROM PAIR WHERE Key=%d;", key); 138 | 139 | int rc = sqlite3_exec(db, sql, NULL, 0, &zErrMsg); 140 | if (rc != SQLITE_OK) { 141 | fprintf(stderr, "SQL erase error: %s\n", zErrMsg); 142 | sqlite3_free(zErrMsg); 143 | return false; 144 | } else { 145 | // fprintf(stdout, "erase successfully\n"); 146 | return true; 147 | } 148 | } 149 | 150 | // 151 | // 152 | // use for query database in splite 153 | // 154 | // 155 | void query(int key) { 156 | char sql[300]; 157 | char *zErrMsg = 0; 158 | sprintf(sql, "SELECT * from PAIR WHERE Key == %d;", key); 159 | const char *data = "Callback function called"; 160 | int rc = sqlite3_exec(db, sql, query_callback, (void *)data, &zErrMsg); 161 | if (rc != SQLITE_OK) { 162 | fprintf(stderr, "SQL query error: %s\n", zErrMsg); 163 | sqlite3_free(zErrMsg); 164 | } else { 165 | // fprintf(stdout, "query successfully\n"); 166 | } 167 | } 168 | 169 | // 170 | // 171 | // std run test! 172 | // only query will return the value and push into the vector 173 | // 174 | // 175 | void tester(string filename) { 176 | ifstream File(filename.c_str()); 177 | 178 | char cmd; 179 | int key, value; 180 | while (File >> cmd) { 181 | if (cmd == 'i') { 182 | File >> key >> value; 183 | insert(key, value); 184 | } else if (cmd == 'e') { 185 | File >> key; 186 | erase(key); 187 | } else if (cmd == 'q') { 188 | File >> key; 189 | query(key); 190 | } else { 191 | puts("bad_command"); 192 | } 193 | } 194 | 195 | File.close(); 196 | } 197 | 198 | // 199 | // 200 | // std run B+Tree! 201 | // only query will return the value and push into the vector 202 | // 203 | // 204 | vector BTree_results; 205 | void get_result(FILE *fp) { 206 | char buf[100]; 207 | int result; 208 | if (!fp) { 209 | return; 210 | } 211 | while (memset(buf, 0, sizeof(buf)), fgets(buf, sizeof(buf) - 1, fp) != 0) { 212 | result = atoi(buf); 213 | BTree_results.push_back(result); 214 | // cout << result << endl; 215 | } 216 | } 217 | 218 | void BTree_tester(string filename) { 219 | FILE *fp; 220 | fp = NULL; 221 | string program_name = "hello_world"; 222 | string cmd = "./" + program_name + " < " + filename; 223 | fp = popen(cmd.c_str(), "r"); 224 | if (!fp) { 225 | perror("popen"); 226 | exit(EXIT_FAILURE); 227 | } 228 | get_result(fp); 229 | pclose(fp); 230 | } 231 | 232 | int main(int argc, char *argv[]) { 233 | bool big = true; 234 | open_database("std_test.db"); 235 | 236 | // clear database 237 | Dropout(); 238 | 239 | // create database 240 | create_database(); 241 | 242 | if (big) { 243 | // this test for big data 244 | 245 | // first initial dataset 246 | string dataset = "insert.data"; 247 | tester(dataset); 248 | BTree_tester(dataset); 249 | 250 | // then for query 251 | string test_name = "query.data"; 252 | BTree_tester(test_name); 253 | tester(test_name); 254 | 255 | for (int i = 0; i < results.size(); i++) { 256 | if (results[i] != BTree_results[i]) { 257 | cout << "wrong at big insert + query" << endl; 258 | return 0; 259 | } 260 | } 261 | // then for erase & query 262 | // test_name = "erase_query.data"; 263 | // BTree_tester(test_name); 264 | // tester(test_name); 265 | 266 | // for (int i = 0; i < results.size(); i++) { 267 | // if (results[i] != BTree_results[i]) { 268 | // cout << "wrong at erase + query" << endl; 269 | // return 0; 270 | // } 271 | // } 272 | cout << "PASS" << endl; 273 | } else { 274 | // this test for open and close ! 275 | 276 | // first initial dataset 277 | for (int i = 1; i <= 3; i++) { 278 | string dataset = "insert" + to_string(i) + ".data"; 279 | tester(dataset); 280 | BTree_tester(dataset); 281 | 282 | // then for query 283 | string test_name = "query" + to_string(i) + ".data"; 284 | BTree_tester(test_name); 285 | tester(test_name); 286 | 287 | for (int i = 0; i < results.size(); i++) { 288 | if (results[i] != BTree_results[i]) { 289 | cout << "wrong at open and close " << i << endl; 290 | return 0; 291 | } 292 | } 293 | cout << "PASS" << endl; 294 | } 295 | } 296 | 297 | sqlite3_close(db); 298 | 299 | return 0; 300 | } 301 | 302 | /* 303 | for (auto val : results) 304 | { 305 | cout << val << endl; 306 | } 307 | 308 | for (auto val : BTree_results) 309 | { 310 | cout << val << endl; 311 | } 312 | */ 313 | -------------------------------------------------------------------------------- /BTree/data/one/data_make.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | const long long maxn = 6 * 1e7; 6 | int flag[maxn] = {0}; 7 | int key; 8 | const bool random_type = 1; 9 | int random_seed = 99962; 10 | using namespace std; 11 | inline int abs(int a){ 12 | return a > 0 ? a : -a; 13 | } 14 | 15 | int rand(){ 16 | random_seed = abs(55762 * random_seed * random_seed + 10744 * random_seed + 233 * random_seed * random_seed * random_seed + 103421); 17 | return random_seed; 18 | } 19 | 20 | 21 | int main(){ 22 | ofstream OpenFile("insert.data"); 23 | if(OpenFile.fail()){ 24 | cout<<"Error while opening files."< 2 | #include 3 | #include 4 | #include 5 | const long long maxn = 6 * 1e7; 6 | int flag[maxn] = {0}; 7 | int key; 8 | const bool random_type = 1; 9 | int random_seed = 99962; 10 | using namespace std; 11 | inline int abs(int a){ 12 | return a > 0 ? a : -a; 13 | } 14 | 15 | int rand(){ 16 | random_seed = abs(55762 * random_seed * random_seed + 10744 * random_seed + 233 * random_seed * random_seed * random_seed + 103421); 17 | return random_seed; 18 | } 19 | 20 | 21 | int main(){ 22 | ofstream OpenFile("query.data"); 23 | if(OpenFile.fail()){ 24 | cout<<"Error while opening files."< 9 | #include 10 | #include 11 | 12 | namespace sjtu { 13 | 14 | class exception { 15 | protected: 16 | const std::string variant = ""; 17 | std::string detail = ""; 18 | 19 | public: 20 | exception() {} 21 | exception(const exception &ec) : variant(ec.variant), detail(ec.detail) {} 22 | virtual std::string what() { return variant + " " + detail; } 23 | }; 24 | 25 | /** 26 | * Not needed. 27 | */ 28 | class index_out_of_bound : public exception { 29 | /* __________________________ */ 30 | }; 31 | 32 | class runtime_error : public exception { 33 | /* __________________________ */ 34 | }; 35 | 36 | class invalid_iterator : public exception { 37 | /* __________________________ */ 38 | }; 39 | 40 | class container_is_empty : public exception { 41 | /* __________________________ */ 42 | }; 43 | } // namespace sjtu 44 | 45 | #endif // BPLUSTREE_EXCEPTION_H 46 | -------------------------------------------------------------------------------- /BTree/data/one/runTest.py: -------------------------------------------------------------------------------- 1 | import os 2 | returnID = os.system('g++ -o insertionData data_make.cpp -O2 -std=c++14 -w') 3 | if returnID != 0: 4 | print('Fail to make Insertion Data Generator!') 5 | exit(-1) 6 | 7 | returnID = os.system('g++ -o queryData data_make_query.cpp -O2 -std=c++14 -w') 8 | if returnID != 0: 9 | print('Fail to make Query Data Generator!') 10 | exit(-1) 11 | 12 | os.system('./insertionData > tmp && ./queryData > tmp && rm tmp') 13 | returnID = os.system('g++ -o hello_world BTree.cpp -O2 -std=c++14 -g') 14 | if returnID != 0: 15 | print('Fail to make your BTree, please check whether there exists any compilication error!') 16 | exit(-1) 17 | 18 | os.system('g++ -o target sql_checker.cpp -O2 -std=c++14 -w -l sqlite3') 19 | print('[Accepted] Compiling') 20 | os.system('./target') 21 | -------------------------------------------------------------------------------- /BTree/data/one/sql_checker.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | using namespace std; 10 | sqlite3 *db; 11 | vector results; 12 | 13 | /// 14 | /// 15 | /// useless function 16 | /// 17 | static int callback(void *NotUsed, int argc, char **argv, char **azColName) { 18 | int i; 19 | for (i = 0; i < argc; i++) { 20 | printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL"); 21 | } 22 | printf("\n"); 23 | return 0; 24 | } 25 | 26 | // 27 | // 28 | // use for query in splite 29 | // 30 | // 31 | static int query_callback(void *para, int nCount, char **pValue, char **pName) { 32 | string s; 33 | for (int i = 0; i < nCount; i++) { 34 | if (i % 2) { 35 | // s+=pValue[i]; 36 | // s+="\n"; 37 | results.push_back(atoi(pValue[i])); 38 | } 39 | } 40 | // cout <<"[Query Callback]"<< s << endl; 41 | return 0; 42 | } 43 | 44 | // 45 | // 46 | // use for open database in splite 47 | // 48 | // 49 | void open_database(char *filename) { 50 | /* Open database */ 51 | int rc; 52 | rc = sqlite3_open(filename, &db); 53 | if (rc) { 54 | fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); 55 | exit(0); 56 | } else { 57 | fprintf(stdout, "Opened database successfully\n"); 58 | } 59 | } 60 | 61 | // 62 | // 63 | // use for create database in splite 64 | // 65 | // 66 | 67 | void create_database() { 68 | // if(db == NULL) fprintf(stderr, "No database: %s\n", zErrMsg); 69 | /* Create SQL statement */ 70 | int rc; 71 | char *zErrMsg = 0; 72 | char sql[300]; 73 | sprintf(sql, 74 | "CREATE TABLE PAIR(" 75 | "Key INT PRIMARY KEY," 76 | "Value INT);"); 77 | /* Execute SQL statement */ 78 | rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); 79 | if (rc != SQLITE_OK) { 80 | fprintf(stderr, "SQL error: %s\n", zErrMsg); 81 | sqlite3_free(zErrMsg); 82 | } else { 83 | fprintf(stdout, "Table created successfully\n"); 84 | } 85 | } 86 | 87 | // 88 | // 89 | // use for clearup database in splite 90 | // 91 | // 92 | void Dropout() { 93 | char sql[300]; 94 | char *zErrMsg = 0; 95 | sprintf(sql, "DROP TABLE 'PAIR';"); 96 | // int rc = 0; 97 | int rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); 98 | if (rc != SQLITE_OK) { 99 | fprintf(stderr, "SQL_Dropout error: %s\n", zErrMsg); 100 | //注意,执行失败,需要清理错误码的内存空间 101 | sqlite3_free(zErrMsg); 102 | } else { 103 | fprintf(stdout, "Records Dropout successfully\n"); 104 | } 105 | } 106 | 107 | // 108 | // 109 | // use for insert database in splite 110 | // 111 | // 112 | void insert(int key, int value) { 113 | char sql[300]; 114 | char *zErrMsg = 0; 115 | sprintf(sql, 116 | "INSERT INTO PAIR VALUES( \ 117 | %d ,%d);", 118 | key, value); 119 | 120 | /* Execute SQL statement */ 121 | int rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); 122 | if (rc != SQLITE_OK) { 123 | fprintf(stderr, "SQL error: %s\n", zErrMsg); 124 | sqlite3_free(zErrMsg); 125 | } else { 126 | // fprintf(stdout, "insert successfully\n"); 127 | } 128 | } 129 | 130 | // 131 | // 132 | // use for erase database in splite 133 | // 134 | // 135 | bool erase(int key) { 136 | char sql[3000]; 137 | char *zErrMsg = 0; 138 | sprintf(sql, "DELETE FROM PAIR WHERE Key=%d;", key); 139 | 140 | int rc = sqlite3_exec(db, sql, NULL, 0, &zErrMsg); 141 | if (rc != SQLITE_OK) { 142 | fprintf(stderr, "SQL erase error: %s\n", zErrMsg); 143 | sqlite3_free(zErrMsg); 144 | return false; 145 | } else { 146 | // fprintf(stdout, "erase successfully\n"); 147 | return true; 148 | } 149 | } 150 | 151 | // 152 | // 153 | // use for query database in splite 154 | // 155 | // 156 | void query(int key) { 157 | char sql[300]; 158 | char *zErrMsg = 0; 159 | sprintf(sql, "SELECT * from PAIR WHERE Key == %d;", key); 160 | const char *data = "Callback function called"; 161 | int rc = sqlite3_exec(db, sql, query_callback, (void *)data, &zErrMsg); 162 | if (rc != SQLITE_OK) { 163 | fprintf(stderr, "SQL query error: %s\n", zErrMsg); 164 | sqlite3_free(zErrMsg); 165 | } else { 166 | // fprintf(stdout, "query successfully\n"); 167 | } 168 | } 169 | 170 | // 171 | // 172 | // std run test! 173 | // only query will return the value and push into the vector 174 | // 175 | // 176 | void tester(string filename) { 177 | ifstream File(filename.c_str()); 178 | 179 | char cmd; 180 | int key, value; 181 | while (File >> cmd) { 182 | if (cmd == 'i') { 183 | File >> key >> value; 184 | insert(key, value); 185 | } else if (cmd == 'e') { 186 | File >> key; 187 | erase(key); 188 | } else if (cmd == 'q') { 189 | File >> key; 190 | query(key); 191 | } else { 192 | puts("bad_command"); 193 | } 194 | } 195 | 196 | File.close(); 197 | } 198 | 199 | // 200 | // 201 | // std run B+Tree! 202 | // only query will return the value and push into the vector 203 | // 204 | // 205 | vector BTree_results; 206 | void get_result(FILE *fp) { 207 | char buf[100]; 208 | int result; 209 | if (!fp) { 210 | return; 211 | } 212 | while (memset(buf, 0, sizeof(buf)), fgets(buf, sizeof(buf) - 1, fp) != 0) { 213 | result = atoi(buf); 214 | BTree_results.push_back(result); 215 | cout << result << endl; 216 | } 217 | } 218 | 219 | void BTree_tester(string filename) { 220 | FILE *fp; 221 | fp = NULL; 222 | string program_name = "hello_world"; 223 | string cmd = "./" + program_name + " < " + filename; 224 | // std::cout << "Command: " << cmd << std::endl; 225 | // system(cmd.c_str()); 226 | fp = popen(cmd.c_str(), "r"); 227 | if (!fp) { 228 | perror("popen"); 229 | exit(EXIT_FAILURE); 230 | } 231 | get_result(fp); 232 | pclose(fp); 233 | } 234 | 235 | int main(int argc, char *argv[]) { 236 | bool big = true; 237 | open_database("std_test.db"); 238 | 239 | // clear database 240 | Dropout(); 241 | 242 | // create database 243 | create_database(); 244 | 245 | if (big) { 246 | // this test for big data 247 | 248 | // first initial dataset 249 | string dataset = "insert.data"; 250 | tester(dataset); 251 | BTree_tester(dataset); 252 | 253 | // then for query 254 | string test_name = "query.data"; 255 | BTree_tester(test_name); 256 | tester(test_name); 257 | for (int i = 0; i < results.size(); i++) { 258 | if (results[i] != BTree_results[i]) { 259 | cout << "wrong at big insert + query" << endl; 260 | throw 1; 261 | } 262 | } 263 | cout << "PASS" << endl; 264 | } else { 265 | // this test for open and close ! 266 | 267 | // first initial dataset 268 | for (int i = 1; i <= 3; i++) { 269 | string dataset = "insert" + to_string(i) + ".data"; 270 | tester(dataset); 271 | BTree_tester(dataset); 272 | 273 | // then for query 274 | string test_name = "query" + to_string(i) + ".data"; 275 | BTree_tester(test_name); 276 | tester(test_name); 277 | 278 | for (int i = 0; i < results.size(); i++) { 279 | if (results[i] != BTree_results[i]) { 280 | cout << "wrong at open and close " << i << endl; 281 | return 0; 282 | } 283 | } 284 | cout << "PASS" << endl; 285 | } 286 | } 287 | 288 | sqlite3_close(db); 289 | 290 | return 0; 291 | } 292 | 293 | /* 294 | for (auto val : results) 295 | { 296 | cout << val << endl; 297 | } 298 | 299 | for (auto val : BTree_results) 300 | { 301 | cout << val << endl; 302 | } 303 | */ 304 | -------------------------------------------------------------------------------- /BTree/data/one/utility.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 郑文鑫 on 2019-03-09. 3 | // 4 | 5 | #ifndef BPLUSTREE_UTILITY_H 6 | #define BPLUSTREE_UTILITY_H 7 | 8 | #include 9 | 10 | namespace sjtu{ 11 | enum OperationResult{ 12 | Success, Duplicated, Fail 13 | }; 14 | template 15 | class pair { 16 | public: 17 | T1 first; 18 | T2 second; 19 | constexpr pair() : first(), second() {} 20 | pair(const pair &other) = default; 21 | pair(pair &&other) = default; 22 | pair(const T1 &x, const T2 &y) : first(x), second(y) {} 23 | template 24 | pair(U1 &&x, U2 &&y) : first(x), second(y) {} 25 | template 26 | pair(const pair &other) : first(other.first), second(other.second) {} 27 | template 28 | pair(pair &&other) : first(other.first), second(other.second) {} 29 | }; 30 | 31 | } 32 | 33 | 34 | #endif //BPLUSTREE_UTILITY_H 35 | -------------------------------------------------------------------------------- /BTree/data/three/BTree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "BTree.hpp" 5 | // test: constructor 6 | using namespace std; 7 | sjtu::BTree bTree; 8 | void insert(int key, int value){ 9 | bTree.insert(key, value); 10 | } 11 | 12 | 13 | void erase(int key){ 14 | bTree.erase(key); 15 | } 16 | 17 | int query(int key){ 18 | return bTree.at(key); 19 | } 20 | 21 | 22 | void tester(){ 23 | //assert(bTree.begin() == bTree.begin()); 24 | int key, value; 25 | char cmd; 26 | while(cin >> cmd){ 27 | if(cmd == 'i'){ 28 | cin >> key >> value; 29 | insert(key, value); 30 | }else 31 | if(cmd == 'e'){ 32 | cin >> key; 33 | erase(key); 34 | }else 35 | if(cmd == 'q'){ 36 | cin >> key; 37 | cout << query(key) << endl; 38 | }else{ 39 | puts("bad_command"); 40 | } 41 | } 42 | } 43 | 44 | int main(){ 45 | tester(); 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /BTree/data/three/BTree.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 郑文鑫 on 2019-03-09. 3 | // 4 | 5 | #include "utility.hpp" 6 | #include 7 | #include 8 | #include "exception.hpp" 9 | #include 10 | #include 11 | namespace sjtu { 12 | template > 13 | class BTree { 14 | private: 15 | // Your private members go here 16 | std::fstream fileIO; 17 | std::map _core; 18 | public: 19 | typedef pair value_type; 20 | 21 | const std::map &getCore() const; 22 | 23 | class const_iterator; 24 | class iterator { 25 | private: 26 | // Your private members go here 27 | public: 28 | bool modify(const Value& value){ 29 | 30 | } 31 | iterator() { 32 | // TODO Default Constructor 33 | } 34 | iterator(const iterator& other) { 35 | // TODO Copy Constructor 36 | } 37 | // Return a new iterator which points to the n-next elements 38 | iterator operator++(int) { 39 | // Todo iterator++ 40 | } 41 | iterator& operator++() { 42 | // Todo ++iterator 43 | } 44 | iterator operator--(int) { 45 | // Todo iterator-- 46 | } 47 | iterator& operator--() { 48 | // Todo --iterator 49 | } 50 | // Overloaded of operator '==' and '!=' 51 | // Check whether the iterators are same 52 | bool operator==(const iterator& rhs) const { 53 | // Todo operator == 54 | } 55 | bool operator==(const const_iterator& rhs) const { 56 | // Todo operator == 57 | } 58 | bool operator!=(const iterator& rhs) const { 59 | // Todo operator != 60 | } 61 | bool operator!=(const const_iterator& rhs) const { 62 | // Todo operator != 63 | } 64 | }; 65 | class const_iterator { 66 | // it should has similar member method as iterator. 67 | // and it should be able to construct from an iterator. 68 | private: 69 | // Your private members go here 70 | public: 71 | const_iterator() { 72 | // TODO 73 | } 74 | const_iterator(const const_iterator& other) { 75 | // TODO 76 | } 77 | const_iterator(const iterator& other) { 78 | // TODO 79 | } 80 | // And other methods in iterator, please fill by yourself. 81 | }; 82 | // Default Constructor and Copy Constructor 83 | BTree() { 84 | std::ifstream ifs("target.txt"); 85 | int sizeT; 86 | if(ifs){ 87 | ifs >> sizeT; 88 | // std::cout << "[Debug IO Init] size:" << sizeT << std::endl; 89 | for(int i = 0; i < sizeT; ++i){ 90 | Key key; 91 | Value value; 92 | ifs >> key >> value; 93 | // std::cout << "[Debug IO Read] " << key << "->" << value; 94 | _core.insert(std::make_pair(key, value)); 95 | } 96 | } else{ 97 | std::cout << "Initial"; 98 | } 99 | 100 | } 101 | BTree(const BTree& other) { 102 | // Todo Copy 103 | } 104 | BTree& operator=(const BTree& other) { 105 | // Todo Assignment 106 | } 107 | ~BTree() { 108 | fileIO.open("target.txt", std::ios::in | std::ios::out | std::ios::trunc); 109 | fileIO << _core.size() << "\n"; 110 | for(auto it = _core.begin(); it != _core.end(); it++) { 111 | fileIO << it->first << std::endl; 112 | fileIO << it->second << std::endl; 113 | // std::cout << "[Debug IO Write] " << it->first << "->" << it->second << std::endl; 114 | 115 | } 116 | fileIO.close(); 117 | // Todo Destructor 118 | } 119 | pair insert(const Key& key, const Value& value) { 120 | // std::cout << "[Insertion Debug] " << key << "->" << value << std::endl; 121 | auto result = _core.insert(std::pair(key, value)); 122 | if(result.second == false) return pair(iterator(), Fail); 123 | else return pair(iterator(), Success); 124 | } 125 | // Erase: Erase the Key-Value 126 | // Return Success if it is successfully erased 127 | // Return Fail if the key doesn't exist in the database 128 | OperationResult erase(const Key& key) { 129 | // TODO erase function 130 | return Fail; // If you can't finish erase part, just remaining here. 131 | } 132 | bool empty() const { return _core.empty(); } 133 | // Return the number of pairs 134 | size_t size() const { return _core.size(); } 135 | Value at(const Key& key){ 136 | return _core[key]; 137 | } 138 | }; 139 | 140 | template 141 | const std::map &BTree::getCore() const { 142 | return _core; 143 | } 144 | } // namespace sjtu 145 | 146 | 147 | -------------------------------------------------------------------------------- /BTree/data/three/InsertionTest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | sqlite3 *db; 10 | vector results; 11 | 12 | /// 13 | /// 14 | /// useless function 15 | /// 16 | static int callback(void *NotUsed, int argc, char **argv, char **azColName) { 17 | int i; 18 | for (i = 0; i < argc; i++) { 19 | printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL"); 20 | } 21 | printf("\n"); 22 | return 0; 23 | } 24 | 25 | // 26 | // 27 | // use for query in splite 28 | // 29 | // 30 | static int query_callback(void *para, int nCount, char **pValue, char **pName) { 31 | string s; 32 | for (int i = 0; i < nCount; i++) { 33 | if (i % 2) { 34 | // s+=pValue[i]; 35 | // s+="\n"; 36 | results.push_back(atoi(pValue[i])); 37 | } 38 | } 39 | cout << s << endl; 40 | return 0; 41 | } 42 | 43 | // 44 | // 45 | // use for open database in splite 46 | // 47 | // 48 | void open_database(char *filename) { 49 | /* Open database */ 50 | int rc; 51 | rc = sqlite3_open(filename, &db); 52 | if (rc) { 53 | fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); 54 | exit(0); 55 | } else { 56 | fprintf(stdout, "Opened database successfully\n"); 57 | } 58 | } 59 | 60 | // 61 | // 62 | // use for create database in splite 63 | // 64 | // 65 | 66 | void create_database() { 67 | // if(db == NULL) fprintf(stderr, "No database: %s\n", zErrMsg); 68 | /* Create SQL statement */ 69 | int rc; 70 | char *zErrMsg = 0; 71 | char sql[300]; 72 | sprintf(sql, 73 | "CREATE TABLE PAIR(" 74 | "Key INT PRIMARY KEY," 75 | "Value INT);"); 76 | /* Execute SQL statement */ 77 | rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); 78 | if (rc != SQLITE_OK) { 79 | fprintf(stderr, "SQL error: %s\n", zErrMsg); 80 | sqlite3_free(zErrMsg); 81 | } else { 82 | fprintf(stdout, "Table created successfully\n"); 83 | } 84 | } 85 | 86 | // 87 | // 88 | // use for clearup database in splite 89 | // 90 | // 91 | void Dropout() { 92 | char sql[300]; 93 | char *zErrMsg = 0; 94 | sprintf(sql, "DROP TABLE 'PAIR';"); 95 | // int rc = 0; 96 | int rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); 97 | if (rc != SQLITE_OK) { 98 | fprintf(stderr, "SQL_Dropout error: %s\n", zErrMsg); 99 | //注意,执行失败,需要清理错误码的内存空间 100 | sqlite3_free(zErrMsg); 101 | } else { 102 | fprintf(stdout, "Records Dropout successfully\n"); 103 | } 104 | } 105 | 106 | // 107 | // 108 | // use for insert database in splite 109 | // 110 | // 111 | void insert(int key, int value) { 112 | char sql[300]; 113 | char *zErrMsg = 0; 114 | sprintf(sql, 115 | "INSERT INTO PAIR VALUES( \ 116 | %d ,%d);", 117 | key, value); 118 | 119 | /* Execute SQL statement */ 120 | int rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); 121 | if (rc != SQLITE_OK) { 122 | fprintf(stderr, "SQL error: %s\n", zErrMsg); 123 | sqlite3_free(zErrMsg); 124 | } else { 125 | // fprintf(stdout, "insert successfully\n"); 126 | } 127 | } 128 | 129 | // 130 | // 131 | // use for erase database in splite 132 | // 133 | // 134 | bool erase(int key) { 135 | char sql[3000]; 136 | char *zErrMsg = 0; 137 | sprintf(sql, "DELETE FROM PAIR WHERE Key=%d;", key); 138 | 139 | int rc = sqlite3_exec(db, sql, NULL, 0, &zErrMsg); 140 | if (rc != SQLITE_OK) { 141 | fprintf(stderr, "SQL erase error: %s\n", zErrMsg); 142 | sqlite3_free(zErrMsg); 143 | return false; 144 | } else { 145 | // fprintf(stdout, "erase successfully\n"); 146 | return true; 147 | } 148 | } 149 | 150 | // 151 | // 152 | // use for query database in splite 153 | // 154 | // 155 | void query(int key) { 156 | char sql[300]; 157 | char *zErrMsg = 0; 158 | sprintf(sql, "SELECT * from PAIR WHERE Key == %d;", key); 159 | const char *data = "Callback function called"; 160 | int rc = sqlite3_exec(db, sql, query_callback, (void *)data, &zErrMsg); 161 | if (rc != SQLITE_OK) { 162 | fprintf(stderr, "SQL query error: %s\n", zErrMsg); 163 | sqlite3_free(zErrMsg); 164 | } else { 165 | // fprintf(stdout, "query successfully\n"); 166 | } 167 | } 168 | 169 | // 170 | // 171 | // std run test! 172 | // only query will return the value and push into the vector 173 | // 174 | // 175 | void tester(string filename) { 176 | ifstream File(filename.c_str()); 177 | 178 | char cmd; 179 | int key, value; 180 | while (File >> cmd) { 181 | if (cmd == 'i') { 182 | File >> key >> value; 183 | insert(key, value); 184 | } else if (cmd == 'e') { 185 | File >> key; 186 | erase(key); 187 | } else if (cmd == 'q') { 188 | File >> key; 189 | query(key); 190 | } else { 191 | puts("bad_command"); 192 | } 193 | } 194 | 195 | File.close(); 196 | } 197 | 198 | // 199 | // 200 | // std run B+Tree! 201 | // only query will return the value and push into the vector 202 | // 203 | // 204 | vector BTree_results; 205 | void get_result(FILE *fp) { 206 | char buf[100]; 207 | int result; 208 | if (!fp) { 209 | return; 210 | } 211 | while (memset(buf, 0, sizeof(buf)), fgets(buf, sizeof(buf) - 1, fp) != 0) { 212 | result = atoi(buf); 213 | BTree_results.push_back(result); 214 | // cout << result << endl; 215 | } 216 | } 217 | 218 | void BTree_tester(string filename) { 219 | FILE *fp; 220 | fp = NULL; 221 | string program_name = "hello_world"; 222 | string cmd = "./" + program_name + " < " + filename; 223 | fp = popen(cmd.c_str(), "r"); 224 | if (!fp) { 225 | perror("popen"); 226 | exit(EXIT_FAILURE); 227 | } 228 | get_result(fp); 229 | pclose(fp); 230 | } 231 | 232 | int main(int argc, char *argv[]) { 233 | bool big = true; 234 | open_database("std_test.db"); 235 | 236 | // clear database 237 | Dropout(); 238 | 239 | // create database 240 | create_database(); 241 | 242 | if (big) { 243 | // this test for big data 244 | 245 | // first initial dataset 246 | string dataset = "insert.data"; 247 | tester(dataset); 248 | BTree_tester(dataset); 249 | 250 | // then for query 251 | string test_name = "query.data"; 252 | BTree_tester(test_name); 253 | tester(test_name); 254 | 255 | for (int i = 0; i < results.size(); i++) { 256 | if (results[i] != BTree_results[i]) { 257 | cout << "wrong at big insert + query" << endl; 258 | return 0; 259 | } 260 | } 261 | // then for erase & query 262 | // test_name = "erase_query.data"; 263 | // BTree_tester(test_name); 264 | // tester(test_name); 265 | 266 | // for (int i = 0; i < results.size(); i++) { 267 | // if (results[i] != BTree_results[i]) { 268 | // cout << "wrong at erase + query" << endl; 269 | // return 0; 270 | // } 271 | // } 272 | cout << "PASS" << endl; 273 | } else { 274 | // this test for open and close ! 275 | 276 | // first initial dataset 277 | for (int i = 1; i <= 3; i++) { 278 | string dataset = "insert" + to_string(i) + ".data"; 279 | tester(dataset); 280 | BTree_tester(dataset); 281 | 282 | // then for query 283 | string test_name = "query" + to_string(i) + ".data"; 284 | BTree_tester(test_name); 285 | tester(test_name); 286 | 287 | for (int i = 0; i < results.size(); i++) { 288 | if (results[i] != BTree_results[i]) { 289 | cout << "wrong at open and close " << i << endl; 290 | return 0; 291 | } 292 | } 293 | cout << "PASS" << endl; 294 | } 295 | } 296 | 297 | sqlite3_close(db); 298 | 299 | return 0; 300 | } 301 | 302 | /* 303 | for (auto val : results) 304 | { 305 | cout << val << endl; 306 | } 307 | 308 | for (auto val : BTree_results) 309 | { 310 | cout << val << endl; 311 | } 312 | */ 313 | -------------------------------------------------------------------------------- /BTree/data/three/data_make.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | const long long maxn = 6 * 1e7; 6 | int flag[maxn] = {0}; 7 | int key; 8 | const bool random_type = 1; 9 | int random_seed = 99962; 10 | using namespace std; 11 | inline int abs(int a){ 12 | return a > 0 ? a : -a; 13 | } 14 | 15 | int rand(){ 16 | random_seed = abs(55762 * random_seed * random_seed + 10744 * random_seed + 233 * random_seed * random_seed * random_seed + 103421); 17 | return random_seed; 18 | } 19 | 20 | 21 | int main(){ 22 | ofstream OpenFile("insert.data"); 23 | if(OpenFile.fail()){ 24 | cout<<"Error while opening files."< 3 | #include 4 | #include 5 | #include 6 | const long long maxn = 6 * 1e6; 7 | int flag[maxn] = {0}; 8 | int key; 9 | const bool random_type = 1; 10 | int random_seed = 99962; 11 | using namespace std; 12 | inline int abs(int a){ 13 | return a > 0 ? a : -a; 14 | } 15 | 16 | int rand(){ 17 | random_seed = abs(55762 * random_seed * random_seed + 10744 * random_seed + 233 * random_seed * random_seed * random_seed + 103421); 18 | return random_seed; 19 | } 20 | 21 | 22 | int main(){ 23 | ofstream OpenFile("erase.data"); 24 | if(OpenFile.fail()){ 25 | cout<<"Error while opening files."< 2 | #include 3 | #include 4 | #include 5 | const long long maxn = 6 * 1e7; 6 | int flag[maxn] = {0}; 7 | int key; 8 | const bool random_type = 1; 9 | int random_seed = 99962; 10 | using namespace std; 11 | inline int abs(int a){ 12 | return a > 0 ? a : -a; 13 | } 14 | 15 | int rand(){ 16 | random_seed = abs(55762 * random_seed * random_seed + 10744 * random_seed + 233 * random_seed * random_seed * random_seed + 103421); 17 | return random_seed; 18 | } 19 | 20 | 21 | int main(){ 22 | ofstream OpenFile("query.data"); 23 | if(OpenFile.fail()){ 24 | cout<<"Error while opening files."< 9 | #include 10 | #include 11 | 12 | namespace sjtu { 13 | 14 | class exception { 15 | protected: 16 | const std::string variant = ""; 17 | std::string detail = ""; 18 | 19 | public: 20 | exception() {} 21 | exception(const exception &ec) : variant(ec.variant), detail(ec.detail) {} 22 | virtual std::string what() { return variant + " " + detail; } 23 | }; 24 | 25 | /** 26 | * Not needed. 27 | */ 28 | class index_out_of_bound : public exception { 29 | /* __________________________ */ 30 | }; 31 | 32 | class runtime_error : public exception { 33 | /* __________________________ */ 34 | }; 35 | 36 | class invalid_iterator : public exception { 37 | /* __________________________ */ 38 | }; 39 | 40 | class container_is_empty : public exception { 41 | /* __________________________ */ 42 | }; 43 | } // namespace sjtu 44 | 45 | #endif // BPLUSTREE_EXCEPTION_H 46 | -------------------------------------------------------------------------------- /BTree/data/three/runTest.py: -------------------------------------------------------------------------------- 1 | import os 2 | returnID = os.system('g++ -o insertionData data_make.cpp -O2 -std=c++14 -w') 3 | if returnID != 0: 4 | print('Fail to make Insertion Data Generator!') 5 | exit(-1) 6 | 7 | returnID = os.system('g++ -o queryData data_make_query.cpp -O2 -std=c++14 -w') 8 | if returnID != 0: 9 | print('Fail to make Query Data Generator!') 10 | exit(-1) 11 | 12 | returnID = os.system('g++ -o eraseData data_make_erase.cpp -O2 -std=c++14 -w') 13 | if returnID != 0: 14 | print('Fail to make Erase Data Generator!') 15 | exit(-1) 16 | 17 | os.system('./insertionData > tmp && ./queryData > tmp && ./eraseData > tmp && rm tmp') 18 | returnID = os.system('g++ -o hello_world BTree.cpp -O2 -std=c++14 -g') 19 | if returnID != 0: 20 | print('Fail to make your BTree, please check whether there exists any compilication error!') 21 | exit(-1) 22 | 23 | os.system('g++ -o target sql_checker.cpp -O2 -std=c++14 -w -l sqlite3') 24 | print('[Accepted] Compiling') 25 | os.system('./target') 26 | -------------------------------------------------------------------------------- /BTree/data/three/sql_checker.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | using namespace std; 10 | sqlite3 *db; 11 | vector results; 12 | 13 | /// 14 | /// 15 | /// useless function 16 | /// 17 | static int callback(void *NotUsed, int argc, char **argv, char **azColName) { 18 | int i; 19 | for (i = 0; i < argc; i++) { 20 | printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL"); 21 | } 22 | printf("\n"); 23 | return 0; 24 | } 25 | 26 | // 27 | // 28 | // use for query in splite 29 | // 30 | // 31 | static int query_callback(void *para, int nCount, char **pValue, char **pName) { 32 | string s; 33 | for (int i = 0; i < nCount; i++) { 34 | if (i % 2) { 35 | // s+=pValue[i]; 36 | // s+="\n"; 37 | results.push_back(atoi(pValue[i])); 38 | } 39 | } 40 | // cout <<"[Query Callback]"<< s << endl; 41 | return 0; 42 | } 43 | 44 | // 45 | // 46 | // use for open database in splite 47 | // 48 | // 49 | void open_database(char *filename) { 50 | /* Open database */ 51 | int rc; 52 | rc = sqlite3_open(filename, &db); 53 | if (rc) { 54 | fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); 55 | exit(0); 56 | } else { 57 | fprintf(stdout, "Opened database successfully\n"); 58 | } 59 | } 60 | 61 | // 62 | // 63 | // use for create database in splite 64 | // 65 | // 66 | 67 | void create_database() { 68 | // if(db == NULL) fprintf(stderr, "No database: %s\n", zErrMsg); 69 | /* Create SQL statement */ 70 | int rc; 71 | char *zErrMsg = 0; 72 | char sql[300]; 73 | sprintf(sql, 74 | "CREATE TABLE PAIR(" 75 | "Key INT PRIMARY KEY," 76 | "Value INT);"); 77 | /* Execute SQL statement */ 78 | rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); 79 | if (rc != SQLITE_OK) { 80 | fprintf(stderr, "SQL error: %s\n", zErrMsg); 81 | sqlite3_free(zErrMsg); 82 | } else { 83 | fprintf(stdout, "Table created successfully\n"); 84 | } 85 | } 86 | 87 | // 88 | // 89 | // use for clearup database in splite 90 | // 91 | // 92 | void Dropout() { 93 | char sql[300]; 94 | char *zErrMsg = 0; 95 | sprintf(sql, "DROP TABLE 'PAIR';"); 96 | // int rc = 0; 97 | int rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); 98 | if (rc != SQLITE_OK) { 99 | fprintf(stderr, "SQL_Dropout error: %s\n", zErrMsg); 100 | //注意,执行失败,需要清理错误码的内存空间 101 | sqlite3_free(zErrMsg); 102 | } else { 103 | fprintf(stdout, "Records Dropout successfully\n"); 104 | } 105 | } 106 | 107 | // 108 | // 109 | // use for insert database in splite 110 | // 111 | // 112 | void insert(int key, int value) { 113 | char sql[300]; 114 | char *zErrMsg = 0; 115 | sprintf(sql, 116 | "INSERT INTO PAIR VALUES( \ 117 | %d ,%d);", 118 | key, value); 119 | 120 | /* Execute SQL statement */ 121 | int rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); 122 | if (rc != SQLITE_OK) { 123 | fprintf(stderr, "SQL error: %s\n", zErrMsg); 124 | sqlite3_free(zErrMsg); 125 | } else { 126 | // fprintf(stdout, "insert successfully\n"); 127 | } 128 | } 129 | 130 | // 131 | // 132 | // use for erase database in splite 133 | // 134 | // 135 | bool erase(int key) { 136 | char sql[3000]; 137 | char *zErrMsg = 0; 138 | sprintf(sql, "DELETE FROM PAIR WHERE Key=%d;", key); 139 | 140 | int rc = sqlite3_exec(db, sql, NULL, 0, &zErrMsg); 141 | if (rc != SQLITE_OK) { 142 | fprintf(stderr, "SQL erase error: %s\n", zErrMsg); 143 | sqlite3_free(zErrMsg); 144 | return false; 145 | } else { 146 | // fprintf(stdout, "erase successfully\n"); 147 | return true; 148 | } 149 | } 150 | 151 | // 152 | // 153 | // use for query database in splite 154 | // 155 | // 156 | void query(int key) { 157 | char sql[300]; 158 | char *zErrMsg = 0; 159 | sprintf(sql, "SELECT * from PAIR WHERE Key == %d;", key); 160 | const char *data = "Callback function called"; 161 | int rc = sqlite3_exec(db, sql, query_callback, (void *)data, &zErrMsg); 162 | if (rc != SQLITE_OK) { 163 | fprintf(stderr, "SQL query error: %s\n", zErrMsg); 164 | sqlite3_free(zErrMsg); 165 | } else { 166 | // fprintf(stdout, "query successfully\n"); 167 | } 168 | } 169 | 170 | // 171 | // 172 | // std run test! 173 | // only query will return the value and push into the vector 174 | // 175 | // 176 | void tester(string filename) { 177 | ifstream File(filename.c_str()); 178 | 179 | char cmd; 180 | int key, value; 181 | while (File >> cmd) { 182 | if (cmd == 'i') { 183 | File >> key >> value; 184 | insert(key, value); 185 | } else if (cmd == 'e') { 186 | File >> key; 187 | erase(key); 188 | } else if (cmd == 'q') { 189 | File >> key; 190 | query(key); 191 | } else { 192 | puts("bad_command"); 193 | } 194 | } 195 | 196 | File.close(); 197 | } 198 | 199 | // 200 | // 201 | // std run B+Tree! 202 | // only query will return the value and push into the vector 203 | // 204 | // 205 | vector BTree_results; 206 | void get_result(FILE *fp) { 207 | char buf[100]; 208 | int result; 209 | if (!fp) { 210 | return; 211 | } 212 | while (memset(buf, 0, sizeof(buf)), fgets(buf, sizeof(buf) - 1, fp) != 0) { 213 | result = atoi(buf); 214 | BTree_results.push_back(result); 215 | cout << result << endl; 216 | } 217 | } 218 | 219 | void BTree_tester(string filename) { 220 | FILE *fp; 221 | fp = NULL; 222 | string program_name = "hello_world"; 223 | string cmd = "./" + program_name + " < " + filename; 224 | // std::cout << "Command: " << cmd << std::endl; 225 | // system(cmd.c_str()); 226 | fp = popen(cmd.c_str(), "r"); 227 | if (!fp) { 228 | perror("popen"); 229 | exit(EXIT_FAILURE); 230 | } 231 | get_result(fp); 232 | pclose(fp); 233 | } 234 | 235 | int main(int argc, char *argv[]) { 236 | bool big = true; 237 | open_database("std_test.db"); 238 | 239 | // clear database 240 | Dropout(); 241 | 242 | // create database 243 | create_database(); 244 | 245 | if (big) { 246 | // this test for big data 247 | 248 | // first initial dataset 249 | string dataset = "insert.data"; 250 | tester(dataset); 251 | BTree_tester(dataset); 252 | 253 | // then for query 254 | string test_name = "query.data"; 255 | BTree_tester(test_name); 256 | tester(test_name); 257 | for (int i = 0; i < results.size(); i++) { 258 | if (results[i] != BTree_results[i]) { 259 | cout << "wrong at big insert + query" << endl; 260 | throw 1; 261 | } 262 | } 263 | 264 | test_name = "erase.data"; 265 | BTree_tester(test_name); 266 | tester(test_name); 267 | 268 | for (int i = 0; i < results.size(); i++) { 269 | if (results[i] != BTree_results[i]) { 270 | cout << "wrong at erase + query" << endl; 271 | throw 1; 272 | } 273 | } 274 | cout << "PASS" << endl; 275 | } else { 276 | // this test for open and close ! 277 | 278 | // first initial dataset 279 | for (int i = 1; i <= 3; i++) { 280 | string dataset = "insert" + to_string(i) + ".data"; 281 | tester(dataset); 282 | BTree_tester(dataset); 283 | 284 | // then for query 285 | string test_name = "query" + to_string(i) + ".data"; 286 | BTree_tester(test_name); 287 | tester(test_name); 288 | 289 | for (int i = 0; i < results.size(); i++) { 290 | if (results[i] != BTree_results[i]) { 291 | cout << "wrong at open and close " << i << endl; 292 | return 0; 293 | } 294 | } 295 | cout << "PASS" << endl; 296 | } 297 | } 298 | 299 | sqlite3_close(db); 300 | 301 | return 0; 302 | } 303 | 304 | /* 305 | for (auto val : results) 306 | { 307 | cout << val << endl; 308 | } 309 | 310 | for (auto val : BTree_results) 311 | { 312 | cout << val << endl; 313 | } 314 | */ 315 | -------------------------------------------------------------------------------- /BTree/data/three/utility.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 郑文鑫 on 2019-03-09. 3 | // 4 | 5 | #ifndef BPLUSTREE_UTILITY_H 6 | #define BPLUSTREE_UTILITY_H 7 | 8 | #include 9 | 10 | namespace sjtu{ 11 | enum OperationResult{ 12 | Success, Duplicated, Fail 13 | }; 14 | template 15 | class pair { 16 | public: 17 | T1 first; 18 | T2 second; 19 | constexpr pair() : first(), second() {} 20 | pair(const pair &other) = default; 21 | pair(pair &&other) = default; 22 | pair(const T1 &x, const T2 &y) : first(x), second(y) {} 23 | template 24 | pair(U1 &&x, U2 &&y) : first(x), second(y) {} 25 | template 26 | pair(const pair &other) : first(other.first), second(other.second) {} 27 | template 28 | pair(pair &&other) : first(other.first), second(other.second) {} 29 | }; 30 | 31 | } 32 | 33 | 34 | #endif //BPLUSTREE_UTILITY_H 35 | -------------------------------------------------------------------------------- /BTree/data/two/BTree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "BTree.hpp" 5 | // test: constructor 6 | using namespace std; 7 | sjtu::BTree bTree; 8 | void insert(int key, int value){ 9 | bTree.insert(key, value); 10 | } 11 | 12 | 13 | void erase(int key){ 14 | bTree.erase(key); 15 | } 16 | 17 | int query(int key){ 18 | return bTree.at(key); 19 | } 20 | 21 | 22 | void tester(){ 23 | int key, value; 24 | char cmd; 25 | while(cin >> cmd){ 26 | if(cmd == 'i'){ 27 | cin >> key >> value; 28 | insert(key, value); 29 | }else 30 | if(cmd == 'e'){ 31 | cin >> key; 32 | erase(key); 33 | }else 34 | if(cmd == 'q'){ 35 | cin >> key; 36 | cout << query(key) << endl; 37 | }else{ 38 | puts("bad_command"); 39 | } 40 | } 41 | } 42 | 43 | int main(){ 44 | tester(); 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /BTree/data/two/BTree.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 郑文鑫 on 2019-03-09. 3 | // 4 | 5 | #include "utility.hpp" 6 | #include 7 | #include 8 | #include "exception.hpp" 9 | #include 10 | #include 11 | namespace sjtu { 12 | template > 13 | class BTree { 14 | private: 15 | // Your private members go here 16 | std::fstream fileIO; 17 | std::map _core; 18 | public: 19 | typedef pair value_type; 20 | 21 | const std::map &getCore() const; 22 | 23 | class const_iterator; 24 | class iterator { 25 | private: 26 | // Your private members go here 27 | public: 28 | bool modify(const Value& value){ 29 | 30 | } 31 | iterator() { 32 | // TODO Default Constructor 33 | } 34 | iterator(const iterator& other) { 35 | // TODO Copy Constructor 36 | } 37 | // Return a new iterator which points to the n-next elements 38 | iterator operator++(int) { 39 | // Todo iterator++ 40 | } 41 | iterator& operator++() { 42 | // Todo ++iterator 43 | } 44 | iterator operator--(int) { 45 | // Todo iterator-- 46 | } 47 | iterator& operator--() { 48 | // Todo --iterator 49 | } 50 | // Overloaded of operator '==' and '!=' 51 | // Check whether the iterators are same 52 | bool operator==(const iterator& rhs) const { 53 | // Todo operator == 54 | } 55 | bool operator==(const const_iterator& rhs) const { 56 | // Todo operator == 57 | } 58 | bool operator!=(const iterator& rhs) const { 59 | // Todo operator != 60 | } 61 | bool operator!=(const const_iterator& rhs) const { 62 | // Todo operator != 63 | } 64 | }; 65 | class const_iterator { 66 | // it should has similar member method as iterator. 67 | // and it should be able to construct from an iterator. 68 | private: 69 | // Your private members go here 70 | public: 71 | const_iterator() { 72 | // TODO 73 | } 74 | const_iterator(const const_iterator& other) { 75 | // TODO 76 | } 77 | const_iterator(const iterator& other) { 78 | // TODO 79 | } 80 | // And other methods in iterator, please fill by yourself. 81 | }; 82 | // Default Constructor and Copy Constructor 83 | BTree() { 84 | std::ifstream ifs("target.txt"); 85 | int sizeT; 86 | if(ifs){ 87 | ifs >> sizeT; 88 | // std::cout << "[Debug IO Init] size:" << sizeT << std::endl; 89 | for(int i = 0; i < sizeT; ++i){ 90 | Key key; 91 | Value value; 92 | ifs >> key >> value; 93 | // std::cout << "[Debug IO Read] " << key << "->" << value; 94 | _core.insert(std::make_pair(key, value)); 95 | } 96 | } else{ 97 | std::cout << "Initial"; 98 | } 99 | 100 | } 101 | BTree(const BTree& other) { 102 | // Todo Copy 103 | } 104 | BTree& operator=(const BTree& other) { 105 | // Todo Assignment 106 | } 107 | ~BTree() { 108 | fileIO.open("target.txt", std::ios::in | std::ios::out | std::ios::trunc); 109 | fileIO << _core.size() << "\n"; 110 | for(auto it = _core.begin(); it != _core.end(); it++) { 111 | fileIO << it->first << std::endl; 112 | fileIO << it->second << std::endl; 113 | // std::cout << "[Debug IO Write] " << it->first << "->" << it->second << std::endl; 114 | 115 | } 116 | fileIO.close(); 117 | // Todo Destructor 118 | } 119 | pair insert(const Key& key, const Value& value) { 120 | // std::cout << "[Insertion Debug] " << key << "->" << value << std::endl; 121 | auto result = _core.insert(std::pair(key, value)); 122 | if(result.second == false) return pair(iterator(), Fail); 123 | else return pair(iterator(), Success); 124 | } 125 | // Erase: Erase the Key-Value 126 | // Return Success if it is successfully erased 127 | // Return Fail if the key doesn't exist in the database 128 | OperationResult erase(const Key& key) { 129 | // TODO erase function 130 | return Fail; // If you can't finish erase part, just remaining here. 131 | } 132 | bool empty() const { return _core.empty(); } 133 | // Return the number of pairs 134 | size_t size() const { return _core.size(); } 135 | Value at(const Key& key){ 136 | return _core[key]; 137 | } 138 | }; 139 | 140 | template 141 | const std::map &BTree::getCore() const { 142 | return _core; 143 | } 144 | } // namespace sjtu 145 | 146 | 147 | -------------------------------------------------------------------------------- /BTree/data/two/InsertionTest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | sqlite3 *db; 10 | vector results; 11 | 12 | /// 13 | /// 14 | /// useless function 15 | /// 16 | static int callback(void *NotUsed, int argc, char **argv, char **azColName) { 17 | int i; 18 | for (i = 0; i < argc; i++) { 19 | printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL"); 20 | } 21 | printf("\n"); 22 | return 0; 23 | } 24 | 25 | // 26 | // 27 | // use for query in splite 28 | // 29 | // 30 | static int query_callback(void *para, int nCount, char **pValue, char **pName) { 31 | string s; 32 | for (int i = 0; i < nCount; i++) { 33 | if (i % 2) { 34 | // s+=pValue[i]; 35 | // s+="\n"; 36 | results.push_back(atoi(pValue[i])); 37 | } 38 | } 39 | cout << s << endl; 40 | return 0; 41 | } 42 | 43 | // 44 | // 45 | // use for open database in splite 46 | // 47 | // 48 | void open_database(char *filename) { 49 | /* Open database */ 50 | int rc; 51 | rc = sqlite3_open(filename, &db); 52 | if (rc) { 53 | fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); 54 | exit(0); 55 | } else { 56 | fprintf(stdout, "Opened database successfully\n"); 57 | } 58 | } 59 | 60 | // 61 | // 62 | // use for create database in splite 63 | // 64 | // 65 | 66 | void create_database() { 67 | // if(db == NULL) fprintf(stderr, "No database: %s\n", zErrMsg); 68 | /* Create SQL statement */ 69 | int rc; 70 | char *zErrMsg = 0; 71 | char sql[300]; 72 | sprintf(sql, 73 | "CREATE TABLE PAIR(" 74 | "Key INT PRIMARY KEY," 75 | "Value INT);"); 76 | /* Execute SQL statement */ 77 | rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); 78 | if (rc != SQLITE_OK) { 79 | fprintf(stderr, "SQL error: %s\n", zErrMsg); 80 | sqlite3_free(zErrMsg); 81 | } else { 82 | fprintf(stdout, "Table created successfully\n"); 83 | } 84 | } 85 | 86 | // 87 | // 88 | // use for clearup database in splite 89 | // 90 | // 91 | void Dropout() { 92 | char sql[300]; 93 | char *zErrMsg = 0; 94 | sprintf(sql, "DROP TABLE 'PAIR';"); 95 | // int rc = 0; 96 | int rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); 97 | if (rc != SQLITE_OK) { 98 | fprintf(stderr, "SQL_Dropout error: %s\n", zErrMsg); 99 | //注意,执行失败,需要清理错误码的内存空间 100 | sqlite3_free(zErrMsg); 101 | } else { 102 | fprintf(stdout, "Records Dropout successfully\n"); 103 | } 104 | } 105 | 106 | // 107 | // 108 | // use for insert database in splite 109 | // 110 | // 111 | void insert(int key, int value) { 112 | char sql[300]; 113 | char *zErrMsg = 0; 114 | sprintf(sql, 115 | "INSERT INTO PAIR VALUES( \ 116 | %d ,%d);", 117 | key, value); 118 | 119 | /* Execute SQL statement */ 120 | int rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); 121 | if (rc != SQLITE_OK) { 122 | fprintf(stderr, "SQL error: %s\n", zErrMsg); 123 | sqlite3_free(zErrMsg); 124 | } else { 125 | // fprintf(stdout, "insert successfully\n"); 126 | } 127 | } 128 | 129 | // 130 | // 131 | // use for erase database in splite 132 | // 133 | // 134 | bool erase(int key) { 135 | char sql[3000]; 136 | char *zErrMsg = 0; 137 | sprintf(sql, "DELETE FROM PAIR WHERE Key=%d;", key); 138 | 139 | int rc = sqlite3_exec(db, sql, NULL, 0, &zErrMsg); 140 | if (rc != SQLITE_OK) { 141 | fprintf(stderr, "SQL erase error: %s\n", zErrMsg); 142 | sqlite3_free(zErrMsg); 143 | return false; 144 | } else { 145 | // fprintf(stdout, "erase successfully\n"); 146 | return true; 147 | } 148 | } 149 | 150 | // 151 | // 152 | // use for query database in splite 153 | // 154 | // 155 | void query(int key) { 156 | char sql[300]; 157 | char *zErrMsg = 0; 158 | sprintf(sql, "SELECT * from PAIR WHERE Key == %d;", key); 159 | const char *data = "Callback function called"; 160 | int rc = sqlite3_exec(db, sql, query_callback, (void *)data, &zErrMsg); 161 | if (rc != SQLITE_OK) { 162 | fprintf(stderr, "SQL query error: %s\n", zErrMsg); 163 | sqlite3_free(zErrMsg); 164 | } else { 165 | // fprintf(stdout, "query successfully\n"); 166 | } 167 | } 168 | 169 | // 170 | // 171 | // std run test! 172 | // only query will return the value and push into the vector 173 | // 174 | // 175 | void tester(string filename) { 176 | ifstream File(filename.c_str()); 177 | 178 | char cmd; 179 | int key, value; 180 | while (File >> cmd) { 181 | if (cmd == 'i') { 182 | File >> key >> value; 183 | insert(key, value); 184 | } else if (cmd == 'e') { 185 | File >> key; 186 | erase(key); 187 | } else if (cmd == 'q') { 188 | File >> key; 189 | query(key); 190 | } else { 191 | puts("bad_command"); 192 | } 193 | } 194 | 195 | File.close(); 196 | } 197 | 198 | // 199 | // 200 | // std run B+Tree! 201 | // only query will return the value and push into the vector 202 | // 203 | // 204 | vector BTree_results; 205 | void get_result(FILE *fp) { 206 | char buf[100]; 207 | int result; 208 | if (!fp) { 209 | return; 210 | } 211 | while (memset(buf, 0, sizeof(buf)), fgets(buf, sizeof(buf) - 1, fp) != 0) { 212 | result = atoi(buf); 213 | BTree_results.push_back(result); 214 | // cout << result << endl; 215 | } 216 | } 217 | 218 | void BTree_tester(string filename) { 219 | FILE *fp; 220 | fp = NULL; 221 | string program_name = "hello_world"; 222 | string cmd = "./" + program_name + " < " + filename; 223 | fp = popen(cmd.c_str(), "r"); 224 | if (!fp) { 225 | perror("popen"); 226 | exit(EXIT_FAILURE); 227 | } 228 | get_result(fp); 229 | pclose(fp); 230 | } 231 | 232 | int main(int argc, char *argv[]) { 233 | bool big = true; 234 | open_database("std_test.db"); 235 | 236 | // clear database 237 | Dropout(); 238 | 239 | // create database 240 | create_database(); 241 | 242 | if (big) { 243 | // this test for big data 244 | 245 | // first initial dataset 246 | string dataset = "insert.data"; 247 | tester(dataset); 248 | BTree_tester(dataset); 249 | 250 | // then for query 251 | string test_name = "query.data"; 252 | BTree_tester(test_name); 253 | tester(test_name); 254 | 255 | for (int i = 0; i < results.size(); i++) { 256 | if (results[i] != BTree_results[i]) { 257 | cout << "wrong at big insert + query" << endl; 258 | return 0; 259 | } 260 | } 261 | // then for erase & query 262 | // test_name = "erase_query.data"; 263 | // BTree_tester(test_name); 264 | // tester(test_name); 265 | 266 | // for (int i = 0; i < results.size(); i++) { 267 | // if (results[i] != BTree_results[i]) { 268 | // cout << "wrong at erase + query" << endl; 269 | // return 0; 270 | // } 271 | // } 272 | cout << "PASS" << endl; 273 | } else { 274 | // this test for open and close ! 275 | 276 | // first initial dataset 277 | for (int i = 1; i <= 3; i++) { 278 | string dataset = "insert" + to_string(i) + ".data"; 279 | tester(dataset); 280 | BTree_tester(dataset); 281 | 282 | // then for query 283 | string test_name = "query" + to_string(i) + ".data"; 284 | BTree_tester(test_name); 285 | tester(test_name); 286 | 287 | for (int i = 0; i < results.size(); i++) { 288 | if (results[i] != BTree_results[i]) { 289 | cout << "wrong at open and close " << i << endl; 290 | return 0; 291 | } 292 | } 293 | cout << "PASS" << endl; 294 | } 295 | } 296 | 297 | sqlite3_close(db); 298 | 299 | return 0; 300 | } 301 | 302 | /* 303 | for (auto val : results) 304 | { 305 | cout << val << endl; 306 | } 307 | 308 | for (auto val : BTree_results) 309 | { 310 | cout << val << endl; 311 | } 312 | */ 313 | -------------------------------------------------------------------------------- /BTree/data/two/data_make.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | const long long maxn = 1e8; 6 | int flag[maxn] = {0}; 7 | int key; 8 | const bool random_type = 1; 9 | int random_seed = 10280; 10 | using namespace std; 11 | inline int abs(int a){ 12 | return a > 0 ? a : -a; 13 | } 14 | 15 | int rand(){ 16 | random_seed = abs(55762 * random_seed * random_seed + 10744 * random_seed + 233 * random_seed * random_seed * random_seed + 103421); 17 | return random_seed; 18 | } 19 | 20 | 21 | int main(){ 22 | ofstream OpenFile("insert.data"); 23 | if(OpenFile.fail()){ 24 | cout<<"Error while opening files."< 2 | #include 3 | #include 4 | #include 5 | const long long maxn = 1e8; 6 | int flag[maxn] = {0}; 7 | int key; 8 | const bool random_type = 1; 9 | int random_seed = 10280; 10 | using namespace std; 11 | inline int abs(int a){ 12 | return a > 0 ? a : -a; 13 | } 14 | 15 | int rand(){ 16 | random_seed = abs(55762 * random_seed * random_seed + 10744 * random_seed + 233 * random_seed * random_seed * random_seed + 103421); 17 | return random_seed; 18 | } 19 | 20 | 21 | int main(){ 22 | ofstream OpenFile("query.data"); 23 | if(OpenFile.fail()){ 24 | cout<<"Error while opening files."< 9 | #include 10 | #include 11 | 12 | namespace sjtu { 13 | 14 | class exception { 15 | protected: 16 | const std::string variant = ""; 17 | std::string detail = ""; 18 | 19 | public: 20 | exception() {} 21 | exception(const exception &ec) : variant(ec.variant), detail(ec.detail) {} 22 | virtual std::string what() { return variant + " " + detail; } 23 | }; 24 | 25 | /** 26 | * Not needed. 27 | */ 28 | class index_out_of_bound : public exception { 29 | /* __________________________ */ 30 | }; 31 | 32 | class runtime_error : public exception { 33 | /* __________________________ */ 34 | }; 35 | 36 | class invalid_iterator : public exception { 37 | /* __________________________ */ 38 | }; 39 | 40 | class container_is_empty : public exception { 41 | /* __________________________ */ 42 | }; 43 | } // namespace sjtu 44 | 45 | #endif // BPLUSTREE_EXCEPTION_H 46 | -------------------------------------------------------------------------------- /BTree/data/two/runTest.py: -------------------------------------------------------------------------------- 1 | import os 2 | returnID = os.system('g++ -o insertionData data_make.cpp -O2 -std=c++14 -w') 3 | if returnID != 0: 4 | print('Fail to make Insertion Data Generator!') 5 | exit(-1) 6 | 7 | returnID = os.system('g++ -o queryData data_make_query.cpp -O2 -std=c++14 -w') 8 | if returnID != 0: 9 | print('Fail to make Query Data Generator!') 10 | exit(-1) 11 | 12 | os.system('./insertionData > tmp && ./queryData > tmp && rm tmp') 13 | returnID = os.system('g++ -o hello_world BTree.cpp -O2 -std=c++14 -g') 14 | if returnID != 0: 15 | print('Fail to make your BTree, please check whether there exists any compilication error!') 16 | exit(-1) 17 | 18 | os.system('g++ -o target sql_checker.cpp -O2 -std=c++14 -w -l sqlite3') 19 | print('[Accepted] Compiling') 20 | os.system('./target') 21 | -------------------------------------------------------------------------------- /BTree/data/two/sql_checker.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | using namespace std; 10 | sqlite3 *db; 11 | vector results; 12 | 13 | /// 14 | /// 15 | /// useless function 16 | /// 17 | static int callback(void *NotUsed, int argc, char **argv, char **azColName) { 18 | int i; 19 | for (i = 0; i < argc; i++) { 20 | printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL"); 21 | } 22 | printf("\n"); 23 | return 0; 24 | } 25 | 26 | // 27 | // 28 | // use for query in splite 29 | // 30 | // 31 | static int query_callback(void *para, int nCount, char **pValue, char **pName) { 32 | string s; 33 | for (int i = 0; i < nCount; i++) { 34 | if (i % 2) { 35 | // s+=pValue[i]; 36 | // s+="\n"; 37 | results.push_back(atoi(pValue[i])); 38 | } 39 | } 40 | // cout <<"[Query Callback]"<< s << endl; 41 | return 0; 42 | } 43 | 44 | // 45 | // 46 | // use for open database in splite 47 | // 48 | // 49 | void open_database(char *filename) { 50 | /* Open database */ 51 | int rc; 52 | rc = sqlite3_open(filename, &db); 53 | if (rc) { 54 | fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); 55 | exit(0); 56 | } else { 57 | fprintf(stdout, "Opened database successfully\n"); 58 | } 59 | } 60 | 61 | // 62 | // 63 | // use for create database in splite 64 | // 65 | // 66 | 67 | void create_database() { 68 | // if(db == NULL) fprintf(stderr, "No database: %s\n", zErrMsg); 69 | /* Create SQL statement */ 70 | int rc; 71 | char *zErrMsg = 0; 72 | char sql[300]; 73 | sprintf(sql, 74 | "CREATE TABLE PAIR(" 75 | "Key INT PRIMARY KEY," 76 | "Value INT);"); 77 | /* Execute SQL statement */ 78 | rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); 79 | if (rc != SQLITE_OK) { 80 | fprintf(stderr, "SQL error: %s\n", zErrMsg); 81 | sqlite3_free(zErrMsg); 82 | } else { 83 | fprintf(stdout, "Table created successfully\n"); 84 | } 85 | } 86 | 87 | // 88 | // 89 | // use for clearup database in splite 90 | // 91 | // 92 | void Dropout() { 93 | char sql[300]; 94 | char *zErrMsg = 0; 95 | sprintf(sql, "DROP TABLE 'PAIR';"); 96 | // int rc = 0; 97 | int rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); 98 | if (rc != SQLITE_OK) { 99 | fprintf(stderr, "SQL_Dropout error: %s\n", zErrMsg); 100 | //注意,执行失败,需要清理错误码的内存空间 101 | sqlite3_free(zErrMsg); 102 | } else { 103 | fprintf(stdout, "Records Dropout successfully\n"); 104 | } 105 | } 106 | 107 | // 108 | // 109 | // use for insert database in splite 110 | // 111 | // 112 | void insert(int key, int value) { 113 | char sql[300]; 114 | char *zErrMsg = 0; 115 | sprintf(sql, 116 | "INSERT INTO PAIR VALUES( \ 117 | %d ,%d);", 118 | key, value); 119 | 120 | /* Execute SQL statement */ 121 | int rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); 122 | if (rc != SQLITE_OK) { 123 | fprintf(stderr, "SQL error: %s\n", zErrMsg); 124 | sqlite3_free(zErrMsg); 125 | } else { 126 | // fprintf(stdout, "insert successfully\n"); 127 | } 128 | } 129 | 130 | // 131 | // 132 | // use for erase database in splite 133 | // 134 | // 135 | bool erase(int key) { 136 | char sql[3000]; 137 | char *zErrMsg = 0; 138 | sprintf(sql, "DELETE FROM PAIR WHERE Key=%d;", key); 139 | 140 | int rc = sqlite3_exec(db, sql, NULL, 0, &zErrMsg); 141 | if (rc != SQLITE_OK) { 142 | fprintf(stderr, "SQL erase error: %s\n", zErrMsg); 143 | sqlite3_free(zErrMsg); 144 | return false; 145 | } else { 146 | // fprintf(stdout, "erase successfully\n"); 147 | return true; 148 | } 149 | } 150 | 151 | // 152 | // 153 | // use for query database in splite 154 | // 155 | // 156 | void query(int key) { 157 | char sql[300]; 158 | char *zErrMsg = 0; 159 | sprintf(sql, "SELECT * from PAIR WHERE Key == %d;", key); 160 | const char *data = "Callback function called"; 161 | int rc = sqlite3_exec(db, sql, query_callback, (void *)data, &zErrMsg); 162 | if (rc != SQLITE_OK) { 163 | fprintf(stderr, "SQL query error: %s\n", zErrMsg); 164 | sqlite3_free(zErrMsg); 165 | } else { 166 | // fprintf(stdout, "query successfully\n"); 167 | } 168 | } 169 | 170 | // 171 | // 172 | // std run test! 173 | // only query will return the value and push into the vector 174 | // 175 | // 176 | void tester(string filename) { 177 | ifstream File(filename.c_str()); 178 | 179 | char cmd; 180 | int key, value; 181 | while (File >> cmd) { 182 | if (cmd == 'i') { 183 | File >> key >> value; 184 | insert(key, value); 185 | } else if (cmd == 'e') { 186 | File >> key; 187 | erase(key); 188 | } else if (cmd == 'q') { 189 | File >> key; 190 | query(key); 191 | } else { 192 | puts("bad_command"); 193 | } 194 | } 195 | 196 | File.close(); 197 | } 198 | 199 | // 200 | // 201 | // std run B+Tree! 202 | // only query will return the value and push into the vector 203 | // 204 | // 205 | vector BTree_results; 206 | void get_result(FILE *fp) { 207 | char buf[100]; 208 | int result; 209 | if (!fp) { 210 | return; 211 | } 212 | while (memset(buf, 0, sizeof(buf)), fgets(buf, sizeof(buf) - 1, fp) != 0) { 213 | result = atoi(buf); 214 | BTree_results.push_back(result); 215 | cout << result << endl; 216 | } 217 | } 218 | 219 | void BTree_tester(string filename) { 220 | FILE *fp; 221 | fp = NULL; 222 | string program_name = "hello_world"; 223 | string cmd = "./" + program_name + " < " + filename; 224 | // std::cout << "Command: " << cmd << std::endl; 225 | // system(cmd.c_str()); 226 | fp = popen(cmd.c_str(), "r"); 227 | if (!fp) { 228 | perror("popen"); 229 | exit(EXIT_FAILURE); 230 | } 231 | get_result(fp); 232 | pclose(fp); 233 | } 234 | 235 | int main(int argc, char *argv[]) { 236 | bool big = true; 237 | open_database("std_test.db"); 238 | 239 | // clear database 240 | Dropout(); 241 | 242 | // create database 243 | create_database(); 244 | 245 | if (big) { 246 | // this test for big data 247 | 248 | // first initial dataset 249 | string dataset = "insert.data"; 250 | tester(dataset); 251 | BTree_tester(dataset); 252 | 253 | // then for query 254 | string test_name = "query.data"; 255 | BTree_tester(test_name); 256 | tester(test_name); 257 | for (int i = 0; i < results.size(); i++) { 258 | if (results[i] != BTree_results[i]) { 259 | cout << "wrong at big insert + query" << endl; 260 | throw 1; 261 | } 262 | } 263 | cout << "PASS" << endl; 264 | } else { 265 | // this test for open and close ! 266 | 267 | // first initial dataset 268 | for (int i = 1; i <= 3; i++) { 269 | string dataset = "insert" + to_string(i) + ".data"; 270 | tester(dataset); 271 | BTree_tester(dataset); 272 | 273 | // then for query 274 | string test_name = "query" + to_string(i) + ".data"; 275 | BTree_tester(test_name); 276 | tester(test_name); 277 | 278 | for (int i = 0; i < results.size(); i++) { 279 | if (results[i] != BTree_results[i]) { 280 | cout << "wrong at open and close " << i << endl; 281 | return 0; 282 | } 283 | } 284 | cout << "PASS" << endl; 285 | } 286 | } 287 | 288 | sqlite3_close(db); 289 | 290 | return 0; 291 | } 292 | 293 | /* 294 | for (auto val : results) 295 | { 296 | cout << val << endl; 297 | } 298 | 299 | for (auto val : BTree_results) 300 | { 301 | cout << val << endl; 302 | } 303 | */ 304 | -------------------------------------------------------------------------------- /BTree/data/two/utility.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 郑文鑫 on 2019-03-09. 3 | // 4 | 5 | #ifndef BPLUSTREE_UTILITY_H 6 | #define BPLUSTREE_UTILITY_H 7 | 8 | #include 9 | 10 | namespace sjtu{ 11 | enum OperationResult{ 12 | Success, Duplicated, Fail 13 | }; 14 | template 15 | class pair { 16 | public: 17 | T1 first; 18 | T2 second; 19 | constexpr pair() : first(), second() {} 20 | pair(const pair &other) = default; 21 | pair(pair &&other) = default; 22 | pair(const T1 &x, const T2 &y) : first(x), second(y) {} 23 | template 24 | pair(U1 &&x, U2 &&y) : first(x), second(y) {} 25 | template 26 | pair(const pair &other) : first(other.first), second(other.second) {} 27 | template 28 | pair(pair &&other) : first(other.first), second(other.second) {} 29 | }; 30 | 31 | } 32 | 33 | 34 | #endif //BPLUSTREE_UTILITY_H 35 | -------------------------------------------------------------------------------- /BTree/exception.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 郑文鑫 on 2019-03-10. 3 | // 4 | 5 | #ifndef BPLUSTREE_EXCEPTION_H 6 | #define BPLUSTREE_EXCEPTION_H 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | namespace sjtu { 13 | 14 | class exception { 15 | protected: 16 | const std::string variant = ""; 17 | std::string detail = ""; 18 | 19 | public: 20 | exception() {} 21 | exception(const exception &ec) : variant(ec.variant), detail(ec.detail) {} 22 | virtual std::string what() { return variant + " " + detail; } 23 | }; 24 | 25 | /** 26 | * Not needed. 27 | */ 28 | class index_out_of_bound : public exception { 29 | /* __________________________ */ 30 | }; 31 | 32 | class runtime_error : public exception { 33 | /* __________________________ */ 34 | }; 35 | 36 | class invalid_iterator : public exception { 37 | /* __________________________ */ 38 | }; 39 | 40 | class container_is_empty : public exception { 41 | /* __________________________ */ 42 | }; 43 | } // namespace sjtu 44 | 45 | #endif // BPLUSTREE_EXCEPTION_H 46 | -------------------------------------------------------------------------------- /BTree/utility.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 郑文鑫 on 2019-03-09. 3 | // 4 | 5 | #ifndef BPLUSTREE_UTILITY_H 6 | #define BPLUSTREE_UTILITY_H 7 | 8 | #include 9 | 10 | namespace sjtu{ 11 | enum OperationResult{ 12 | Success, Duplicated, Fail 13 | }; 14 | template 15 | class pair { 16 | public: 17 | T1 first; 18 | T2 second; 19 | constexpr pair() : first(), second() {} 20 | pair(const pair &other) = default; 21 | pair(pair &&other) = default; 22 | pair(const T1 &x, const T2 &y) : first(x), second(y) {} 23 | template 24 | pair(U1 &&x, U2 &&y) : first(x), second(y) {} 25 | template 26 | pair(const pair &other) : first(other.first), second(other.second) {} 27 | template 28 | pair(pair &&other) : first(other.first), second(other.second) {} 29 | }; 30 | 31 | } 32 | } 33 | 34 | #endif //BPLUSTREE_UTILITY_H 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Wenxin Zheng 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Spring 2019 CS158 Data Structure(Honor) Course Project 2 | 2019春季 数据结构(荣誉) 3 | 4 | 5 | > ## 内容概述 6 | > 本学期⼤作业要求同学们完成两个任务,第⼀个是完成STL库中的deque库,即实现⼀个双端队列,要求封装。第⼆个是B+树,要求封装。实现代码的接⼝框架与头⽂件,助教已经给出,同学们需要给出完整的实现。 7 | > 8 | >两个大作业的截止日期分别为: 9 | >- deque :确定 第10周周六(5月4日) 18:00。 10 | >- B+ :确定 第15周周六(6月8日) 18:00。 11 | > 12 | >同学们需要在截⽌⽇期前,完成以上两个库的实现,并提交到OJ上,助教会在期末前安排code review,并综合测试结果和code review给分。 13 | > 14 | >测试数据及源文件:https://github.com/peterzheng98/CS158-DS_Project 15 | > 16 | --- 17 | >## 文件说明 18 | >在BTree(deque)文件夹下分别有数据和接口文件。其中`BTree.hpp(deque.hpp)`是接口文件,也是最终提交的代码;`exceptions.hpp`和`utility.hpp`是两个辅助文件(不可修改),提供了一些异常处理类和pair类,这些可以自由使用。 19 | > 20 | >data文件夹中有多组测试数据,分别位于多个文件夹中,其中标有`memcheck`的数据是用来进行内存泄漏检查的。 21 | > 22 | >若想在本地测试,请将`class-bint.hpp、class-integer.hpp、class-matrix.hpp`和外层文件夹中的三个hpp文件放入测试点所属的文件夹,编译并运行`code.cpp`。 23 | > 24 | --- 25 | > ## 评测及提交方式 26 | >评测采用OJ在线评测的方式,请在OJ上用学号的方式注册账号(同onlinejudge),之后再problem中找到相应题目,然后提交`BTree.hpp(deque.hpp)`中的内容进行测试。 27 | > 28 | >OJ地址:http://oj.peterzheng.cn 29 | > 30 | > 31 | --- 32 | > ## 迟交惩罚 33 | >到第i天上交,扣1+2+..+i分 34 | >类似于:迟交1天 -1, 迟交2天 -1-2, 迟交3天 -1-2-3。。 35 | >OJ地址:http://oj.peterzheng.cn 36 | > 37 | > 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /deque/data/class-bint.hpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace Util { 9 | 10 | const size_t MIN_CAPACITY = 2048; 11 | 12 | class Bint { 13 | class NewSpaceFailed : public std::runtime_error { 14 | public: 15 | NewSpaceFailed(); 16 | }; 17 | class BadCast : public std::invalid_argument { 18 | public: 19 | BadCast(); 20 | }; 21 | bool isMinus = false; 22 | size_t length; 23 | int *data = nullptr; 24 | size_t capacity = MIN_CAPACITY; 25 | void _DoubleSpace(); 26 | void _SafeNewSpace(int *&p, const size_t &len); 27 | explicit Bint(const size_t &capa); 28 | public: 29 | Bint(); 30 | Bint(int x); 31 | Bint(long long x); 32 | Bint(std::string x); 33 | Bint(const Bint &b); 34 | Bint(Bint &&b) noexcept; 35 | 36 | Bint &operator=(int rhs); 37 | Bint &operator=(long long rhs); 38 | Bint &operator=(const Bint &rhs); 39 | Bint &operator=(Bint &&rhs) noexcept; 40 | 41 | friend Bint abs(const Bint &x); 42 | friend Bint abs(Bint &&x); 43 | 44 | friend bool operator==(const Bint &lhs, const Bint &rhs); 45 | friend bool operator!=(const Bint &lhs, const Bint &rhs); 46 | friend bool operator<(const Bint &lhs, const Bint &rhs); 47 | friend bool operator>(const Bint &lhs, const Bint &rhs); 48 | friend bool operator<=(const Bint &lhs, const Bint &rhs); 49 | friend bool operator>=(const Bint &lhs, const Bint &rhs); 50 | 51 | friend Bint operator+(const Bint &lhs, const Bint &rhs); 52 | friend Bint operator-(const Bint &b); 53 | friend Bint operator-(Bint &&b); 54 | friend Bint operator-(const Bint &lhs, const Bint &rhs); 55 | friend Bint operator*(const Bint &lhs, const Bint &rhs); 56 | 57 | friend std::istream &operator>>(std::istream &is, Bint &b); 58 | friend std::ostream &operator<<(std::ostream &os, const Bint &b); 59 | 60 | ~Bint(); 61 | }; 62 | } 63 | 64 | #include 65 | #include 66 | 67 | namespace Util { 68 | 69 | Bint::NewSpaceFailed::NewSpaceFailed() : std::runtime_error("No Enough Memory Space.") {} 70 | Bint::BadCast::BadCast() : std::invalid_argument("Cannot convert to a Bint object") {} 71 | 72 | void Bint::_SafeNewSpace(int *&p, const size_t &len) 73 | { 74 | if (p != nullptr) { 75 | delete[] p; 76 | p = nullptr; 77 | } 78 | p = new int[len]; 79 | if (p == nullptr) { 80 | throw NewSpaceFailed(); 81 | } 82 | memset(p, 0, len * sizeof(unsigned int)); 83 | } 84 | 85 | void Bint::_DoubleSpace() 86 | { 87 | int *newMem = nullptr; 88 | _SafeNewSpace(newMem, capacity << 1); 89 | memcpy(newMem, data, capacity * sizeof(int)); 90 | delete[] data; 91 | data = newMem; 92 | capacity <<= 1; 93 | } 94 | 95 | Bint::Bint() 96 | : length(1) 97 | { 98 | _SafeNewSpace(data, capacity); 99 | } 100 | 101 | Bint::Bint(int x) 102 | : length(0) 103 | { 104 | _SafeNewSpace(data, capacity); 105 | if (x < 0) { 106 | isMinus = true; 107 | x = -x; 108 | } 109 | while (x) { 110 | data[length++] = x % 10000; 111 | x /= 10000; 112 | } 113 | if (!length) { 114 | length = 1; 115 | } 116 | } 117 | 118 | Bint::Bint(long long x) 119 | : length(0) 120 | { 121 | _SafeNewSpace(data, capacity); 122 | if (x < 0) { 123 | isMinus = true; 124 | x = -x; 125 | } 126 | while (x) { 127 | data[length++] = static_cast(x % 10000); 128 | x /= 10000; 129 | } 130 | if (!length) { 131 | length = 1; 132 | } 133 | } 134 | 135 | Bint::Bint(const size_t &capa) 136 | : length(1) 137 | { 138 | while (capacity < capa) { 139 | capacity <<= 1; 140 | } 141 | _SafeNewSpace(data, capacity); 142 | } 143 | 144 | Bint::Bint(std::string x) 145 | { 146 | while (x[0] == '-') { 147 | isMinus = !isMinus; 148 | x.erase(0, 1); 149 | } 150 | while ((capacity << 2) <= x.length()) { 151 | capacity <<= 1; 152 | } 153 | 154 | _SafeNewSpace(data, capacity); 155 | 156 | size_t mid = x.length() >> 1; 157 | for (size_t i = 0; i < mid; ++i) { 158 | std::swap(x[i], x[x.length() - 1 - i]); 159 | } 160 | 161 | const static unsigned int pow10[4] = {1, 10, 100, 1000}; 162 | for (size_t i = 0; i < capacity; ++i) { 163 | if ((i << 2) >= x.length()) { 164 | length = i; 165 | break; 166 | } 167 | for (size_t j = 0; j < 4; ++j) { 168 | if ((i << 2) + j >= x.length()) { 169 | break; 170 | } 171 | if (x[(i << 2) + j] > '9' || x[(i << 2) + j] < '0') { 172 | throw BadCast(); 173 | } 174 | data[i] = data[i] + (x[(i << 2) + j] - '0') * pow10[j]; 175 | } 176 | } 177 | } 178 | 179 | Bint::Bint(const Bint &b) 180 | : isMinus(b.isMinus), length(b.length), capacity(b.capacity) 181 | { 182 | _SafeNewSpace(data, capacity); 183 | memcpy(data, b.data, sizeof(unsigned int) * capacity); 184 | } 185 | 186 | Bint::Bint(Bint &&b) noexcept 187 | : isMinus(b.isMinus), length(b.length), capacity(b.capacity) 188 | { 189 | data = b.data; 190 | b.data = nullptr; 191 | } 192 | 193 | Bint &Bint::operator=(int x) 194 | { 195 | memset(data, 0, sizeof(unsigned int) * capacity); 196 | length = 0; 197 | if (x < 0) { 198 | isMinus = true; 199 | x = -x; 200 | } 201 | while (x) { 202 | data[length++] = x % 10000; 203 | x /= 10000; 204 | } 205 | if (!length) { 206 | length = 1; 207 | } 208 | return *this; 209 | } 210 | 211 | Bint &Bint::operator=(long long x) 212 | { 213 | memset(data, 0, sizeof(unsigned int) * capacity); 214 | length = 0; 215 | if (x < 0) { 216 | isMinus = true; 217 | x = -x; 218 | } 219 | while (x) { 220 | data[length++] = static_cast(x % 10000); 221 | x /= 10000; 222 | } 223 | if (!length) { 224 | length = 1; 225 | } 226 | return *this; 227 | } 228 | 229 | Bint &Bint::operator=(const Bint &rhs) 230 | { 231 | if (this == &rhs) { 232 | return *this; 233 | } 234 | if (rhs.capacity > capacity) { 235 | capacity = rhs.capacity; 236 | _SafeNewSpace(data, capacity); 237 | } 238 | memcpy(data, rhs.data, sizeof(unsigned int) * rhs.capacity); 239 | length = rhs.length; 240 | isMinus = rhs.isMinus; 241 | return *this; 242 | } 243 | 244 | Bint &Bint::operator=(Bint &&rhs) noexcept 245 | { 246 | if (this == &rhs) { 247 | return *this; 248 | } 249 | capacity = rhs.capacity; 250 | length = rhs.length; 251 | isMinus = rhs.isMinus; 252 | data = rhs.data; 253 | rhs.data = nullptr; 254 | return *this; 255 | } 256 | 257 | std::istream &operator>>(std::istream &is, Bint &b) 258 | { 259 | std::string s; 260 | is >> s; 261 | b = Bint(s); 262 | return is; 263 | } 264 | 265 | std::ostream &operator<<(std::ostream &os, const Bint &b) 266 | { 267 | if (b.data == nullptr) { 268 | return os; 269 | } 270 | if (b.isMinus && (b.length > 1 || b.data[0] != 0)) { 271 | os << "-"; 272 | } 273 | os << b.data[b.length - 1]; 274 | for (long long i = b.length - 2LL; i >= 0; --i) { 275 | os << std::setw(4) << std::setfill('0') << b.data[i]; 276 | } 277 | return os; 278 | } 279 | 280 | Bint abs(const Bint &b) 281 | { 282 | Bint result(b); 283 | result.isMinus = false; 284 | return result; 285 | } 286 | 287 | Bint abs(Bint &&b) 288 | { 289 | b.isMinus = false; 290 | return b; 291 | } 292 | 293 | bool operator==(const Bint &lhs, const Bint &rhs) 294 | { 295 | if (lhs.isMinus != rhs.isMinus) { 296 | return false; 297 | } 298 | if (lhs.length != rhs.length) { 299 | return false; 300 | } 301 | for (size_t i = 0; i < lhs.length; ++i) { 302 | if (lhs.data[i] != rhs.data[i]) { 303 | return false; 304 | } 305 | } 306 | return true; 307 | } 308 | 309 | bool operator!=(const Bint &lhs, const Bint &rhs) 310 | { 311 | if (lhs.isMinus != rhs.isMinus) { 312 | return true; 313 | } 314 | if (lhs.length != rhs.length) { 315 | return true; 316 | } 317 | for (size_t i = 0; i < lhs.length; ++i) { 318 | if (lhs.data[i] != rhs.data[i]) { 319 | return true; 320 | } 321 | } 322 | return false; 323 | } 324 | 325 | bool operator<(const Bint &lhs, const Bint &rhs) 326 | { 327 | if (lhs.isMinus != rhs.isMinus) { 328 | return !lhs.isMinus; 329 | } 330 | if (lhs.isMinus) { 331 | if (lhs.length != rhs.length) { 332 | return lhs.length > rhs.length; 333 | } 334 | for (long long i = lhs.length - 1; i >= 0; --i) { 335 | if (lhs.data[i] != rhs.data[i]) { 336 | return lhs.data[i] > rhs.data[i]; 337 | } 338 | } 339 | return false; 340 | } else { 341 | if (lhs.length != rhs.length) { 342 | return lhs.length < rhs.length; 343 | } 344 | for (long long i = lhs.length - 1; i >= 0; --i) { 345 | if (lhs.data[i] != rhs.data[i]) { 346 | return lhs.data[i] < rhs.data[i]; 347 | } 348 | } 349 | return false; 350 | } 351 | } 352 | 353 | bool operator>(const Bint &lhs, const Bint &rhs) 354 | { 355 | return rhs < lhs; 356 | } 357 | 358 | bool operator<=(const Bint &lhs, const Bint &rhs) 359 | { 360 | if (lhs.isMinus != rhs.isMinus) { 361 | return !lhs.isMinus; 362 | } 363 | if (lhs.isMinus) { 364 | if (lhs.length != rhs.length) { 365 | return lhs.length > rhs.length; 366 | } 367 | for (long long i = lhs.length - 1; i >= 0; --i) { 368 | if (lhs.data[i] != rhs.data[i]) { 369 | return lhs.data[i] > rhs.data[i]; 370 | } 371 | } 372 | return true; 373 | } else { 374 | if (lhs.length != rhs.length) { 375 | return lhs.length < rhs.length; 376 | } 377 | for (long long i = lhs.length - 1; i >= 0; --i) { 378 | if (lhs.data[i] != rhs.data[i]) { 379 | return lhs.data[i] < rhs.data[i]; 380 | } 381 | } 382 | return true; 383 | } 384 | } 385 | 386 | bool operator>=(const Bint &lhs, const Bint &rhs) 387 | { 388 | if (lhs.isMinus != rhs.isMinus) { 389 | return lhs.isMinus; 390 | } 391 | if (lhs.isMinus) { 392 | if (lhs.length != rhs.length) { 393 | return lhs.length < rhs.length; 394 | } 395 | for (long long i = lhs.length - 1; i >= 0; --i) { 396 | if (lhs.data[i] != rhs.data[i]) { 397 | return lhs.data[i] < rhs.data[i]; 398 | } 399 | } 400 | return true; 401 | } else { 402 | if (lhs.length != rhs.length) { 403 | return lhs.length > rhs.length; 404 | } 405 | for (long long i = lhs.length - 1; i >= 0; --i) { 406 | if (lhs.data[i] != rhs.data[i]) { 407 | return lhs.data[i] > rhs.data[i]; 408 | } 409 | } 410 | return true; 411 | } 412 | } 413 | 414 | 415 | Bint operator+(const Bint &lhs, const Bint &rhs) 416 | { 417 | if (lhs.isMinus == rhs.isMinus) { 418 | size_t maxLen = std::max(lhs.length, rhs.length); 419 | size_t expectLen = maxLen + 1; 420 | Bint result(expectLen); // special constructor 421 | for (size_t i = 0; i < maxLen; ++i) { 422 | result.data[i] = lhs.data[i] + rhs.data[i]; 423 | } 424 | for (size_t i = 0; i < maxLen; ++i) { 425 | if (result.data[i] > 10000) { 426 | result.data[i] -= 10000; 427 | ++result.data[i + 1]; 428 | } 429 | } 430 | result.length = result.data[maxLen] > 0 ? maxLen + 1 : maxLen; 431 | result.isMinus = lhs.isMinus; 432 | return result; 433 | } else { 434 | if (lhs.isMinus) { 435 | return rhs - abs(lhs); 436 | } else { 437 | return lhs - abs(rhs); 438 | } 439 | } 440 | } 441 | 442 | Bint operator-(const Bint &b) 443 | { 444 | Bint result(b); 445 | result.isMinus = !result.isMinus; 446 | return result; 447 | } 448 | 449 | Bint operator-(Bint &&b) 450 | { 451 | b.isMinus = !b.isMinus; 452 | return b; 453 | } 454 | 455 | Bint operator-(const Bint &lhs, const Bint &rhs) 456 | { 457 | if (lhs.isMinus == rhs.isMinus) { 458 | if (lhs.isMinus) { 459 | return -(abs(lhs) - abs(rhs)); 460 | } else { 461 | if (lhs < rhs) { 462 | return -(rhs - lhs); 463 | } 464 | Bint result(std::max(lhs.length, rhs.length)); 465 | for (size_t i = 0; i < lhs.length; ++i) { 466 | result.data[i] = lhs.data[i] - rhs.data[i]; 467 | } 468 | for (size_t i = 0; i < lhs.length; ++i) { 469 | if (result.data[i] < 0) { 470 | result.data[i] += 10000; 471 | ++result.data[i + 1]; 472 | } 473 | } 474 | while (result.length > 1 && result.data[result.length - 1] == 0) { 475 | --result.length; 476 | } 477 | return result; 478 | } 479 | } else { 480 | return lhs + (-rhs); 481 | } 482 | } 483 | 484 | Bint operator*(const Bint &lhs, const Bint &rhs) 485 | { 486 | size_t expectLen = lhs.length + rhs.length + 2; 487 | Bint result(expectLen); 488 | for (size_t i = 0; i < lhs.length; ++i) { 489 | for (size_t j = 0; j < rhs.length; ++j) { 490 | long long tmp = result.data[i + j] + static_cast(lhs.data[i]) * rhs.data[j]; 491 | if (tmp >= 10000) { 492 | result.data[i + j] = tmp % 10000; 493 | result.data[i + j + 1] += static_cast(tmp / 10000); 494 | } else { 495 | result.data[i + j] = tmp; 496 | } 497 | } 498 | } 499 | result.length = lhs.length + rhs.length -1; 500 | while (result.data[result.length] > 0) { 501 | ++result.length; 502 | } 503 | while (result.length > 1 && result.data[result.length - 1] == 0) { 504 | --result.length; 505 | } 506 | return result; 507 | } 508 | 509 | Bint::~Bint() 510 | { 511 | if (data != nullptr) { 512 | delete[] data; 513 | data = nullptr; 514 | } 515 | } 516 | } 517 | -------------------------------------------------------------------------------- /deque/data/class-integer.hpp: -------------------------------------------------------------------------------- 1 | class Integer { 2 | private: 3 | int data; 4 | public: 5 | Integer(const int &value) : data(value) {} 6 | Integer(const Integer &other) : data(other.data) {} 7 | bool operator==(const Integer &t) 8 | { 9 | return data == t.data; 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /deque/data/class-matrix.hpp: -------------------------------------------------------------------------------- 1 | #ifndef DIAMOND_MATRIX_HPP 2 | #define DIAMOND_MATRIX_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace Diamond { 10 | 11 | template 12 | class Matrix { 13 | protected: 14 | size_t n_rows = 0; 15 | size_t n_cols = 0; 16 | std::vector> data; 17 | class RowProxy { 18 | std::vector<_Td> &row; 19 | public: 20 | RowProxy(std::vector<_Td> & _row) : row(_row) {} 21 | _Td & operator[](const size_t &pos) 22 | { 23 | return row[pos]; 24 | } 25 | }; 26 | class ConstRowProxy { 27 | const std::vector<_Td> &row; 28 | public: 29 | ConstRowProxy(const std::vector<_Td> &_row) : row(_row) {} 30 | const _Td & operator[](const size_t &pos) const 31 | { 32 | return row[pos]; 33 | } 34 | }; 35 | public: 36 | Matrix() {}; 37 | Matrix(const size_t &_n_rows, const size_t &_n_cols) 38 | : n_rows(_n_rows), n_cols(_n_cols), data(std::vector>(n_rows, std::vector<_Td>(n_cols))) {} 39 | Matrix(const size_t &_n_rows, const size_t &_n_cols, const _Td &fillValue) 40 | : n_rows(_n_rows), n_cols(_n_cols), data(std::vector>(n_rows, std::vector<_Td>(n_cols, fillValue))) {} 41 | Matrix(const Matrix<_Td> &mat) 42 | : n_rows(mat.n_rows), n_cols(mat.n_cols), data(mat.data) {} 43 | Matrix(Matrix<_Td> &&mat) noexcept 44 | : n_rows(mat.n_rows), n_cols(mat.n_cols), data(mat.data) {} 45 | Matrix<_Td> & operator=(const Matrix<_Td> &rhs) 46 | { 47 | this->n_rows = rhs.n_rows; 48 | this->n_cols = rhs.n_cols; 49 | this->data = rhs.data; 50 | return *this; 51 | } 52 | Matrix<_Td> & operator=(Matrix<_Td> &&rhs) 53 | { 54 | this->n_rows = rhs.n_rows; 55 | this->n_cols = rhs.n_cols; 56 | this->data = rhs.data; 57 | return *this; 58 | } 59 | inline const size_t & RowSize() const 60 | { 61 | return n_rows; 62 | } 63 | inline const size_t & ColSize() const 64 | { 65 | return n_cols; 66 | } 67 | RowProxy operator[](const size_t &Kth) 68 | { 69 | return RowProxy(this->data[Kth]); 70 | } 71 | const ConstRowProxy operator[](const size_t &Kth) const 72 | { 73 | return ConstRowProxy(this->data[Kth]); 74 | } 75 | ~Matrix() = default; 76 | }; 77 | 78 | /** 79 | * Sum of two matrics. 80 | */ 81 | template 82 | Matrix<_Td> operator+(const Matrix<_Td> &a, const Matrix<_Td> &b) 83 | { 84 | if (a.RowSize() != b.RowSize() || a.ColSize() != b.ColSize()) { 85 | throw std::invalid_argument("different matrics\'s sizes"); 86 | } 87 | Matrix<_Td> c(a.RowSize(), a.ColSize()); 88 | for (size_t i = 0; i < a.RowSize(); ++i) { 89 | for (size_t j = 0; j < a.ColSize(); ++j) { 90 | c[i][j] = a[i][j] + b[i][j]; 91 | } 92 | } 93 | return c; 94 | } 95 | 96 | template 97 | Matrix<_Td> operator-(const Matrix<_Td> &a, const Matrix<_Td> &b) 98 | { 99 | if (a.RowSize() != b.RowSize() || a.ColSize() != b.ColSize()) { 100 | throw std::invalid_argument("different matrics\'s sizes"); 101 | } 102 | Matrix<_Td> c(a.RowSize(), a.ColSize()); 103 | for (size_t i = 0; i < a.RowSize(); ++i) { 104 | for (size_t j = 0; j < a.ColSize(); ++j) { 105 | c[i][j] = a[i][j] - b[i][j]; 106 | } 107 | } 108 | return c; 109 | } 110 | template 111 | bool operator==(const Matrix<_Td> &a, const Matrix<_Td> &b) 112 | { 113 | if (a.RowSize() != b.RowSize() || a.ColSize() != b.ColSize()) { 114 | return false; 115 | } 116 | for (size_t i = 0; i < a.RowSize(); ++i) { 117 | for (size_t j = 0; j < a.ColSize(); ++j) { 118 | if (a[i][j] != b[i][j]) 119 | return false; 120 | } 121 | } 122 | return true; 123 | } 124 | 125 | template 126 | Matrix<_Td> operator-(const Matrix<_Td> &mat) 127 | { 128 | Matrix<_Td> result(mat.RowSize(), mat.ColSize()); 129 | for (size_t i = 0; i < mat.RowSize(); ++i) { 130 | for (size_t j = 0; j < mat.ColSize(); ++j) { 131 | result[i][j] = -mat[i][j]; 132 | } 133 | } 134 | return result; 135 | } 136 | 137 | template 138 | Matrix<_Td> operator-(Matrix<_Td> &&mat) 139 | { 140 | for (size_t i = 0; i < mat.RowSize(); ++i) { 141 | for (size_t j = 0; j < mat.ColSize(); ++j) { 142 | mat[i][j] = -mat[i][j]; 143 | } 144 | } 145 | return mat; 146 | } 147 | 148 | /** 149 | * Multiplication of two matrics. 150 | */ 151 | template 152 | Matrix<_Td> operator*(const Matrix<_Td> &a, const Matrix<_Td> &b) 153 | { 154 | if (a.ColSize() != b.RowSize()) { 155 | throw std::invalid_argument("different matrics\'s sizes"); 156 | } 157 | Matrix<_Td> c(a.RowSize(), b.ColSize(), 0); 158 | for (size_t i = 0; i < a.RowSize(); ++i) { 159 | for (size_t j = 0; j < b.ColSize(); ++j) { 160 | for (size_t k = 0; k < a.ColSize(); ++k) { 161 | c[i][j] += a[i][k] * b[k][j]; 162 | } 163 | } 164 | } 165 | return c; 166 | } 167 | 168 | /** 169 | * Operations between a number and a matrix; 170 | */ 171 | template 172 | Matrix<_Td> operator*(const Matrix<_Td> &a, const _Td &b) 173 | { 174 | Matrix<_Td> c(a.RowSize(), a.ColSize()); 175 | for (size_t i = 0; i < a.RowSize(); ++i) { 176 | for (size_t j = 0; j < a.ColSize(); ++j) { 177 | c[i][j] = a[i][j] * b; 178 | } 179 | } 180 | return c; 181 | } 182 | 183 | template 184 | Matrix<_Td> operator*(const _Td &b, const Matrix<_Td> &a) 185 | { 186 | Matrix<_Td> c(a.RowSize(), a.ColSize()); 187 | for (size_t i = 0; i < a.RowSize(); ++i) { 188 | for (size_t j = 0; j < a.ColSize(); ++j) { 189 | c[i][j] = a[i][j] * b; 190 | } 191 | } 192 | return c; 193 | } 194 | 195 | template 196 | Matrix<_Td> operator/(const Matrix<_Td> &a, const double &b) 197 | { 198 | Matrix<_Td> c(a.RowSize(), a.ColSize()); 199 | for (size_t i = 0; i < a.RowSize(); ++i) { 200 | for (size_t j = 0; j < a.ColSize(); ++j) { 201 | c[i][j] = a[i][j] / b; 202 | } 203 | } 204 | return c; 205 | } 206 | 207 | template 208 | Matrix<_Td> Transpose(const Matrix<_Td> &a) 209 | { 210 | Matrix<_Td> res(a.ColSize(), a.RowSize()); 211 | for (size_t i = 0; i < a.ColSize(); ++i) { 212 | for (size_t j = 0; j < a.RowSize(); ++j) { 213 | res[i][j] = a[j][i]; 214 | } 215 | } 216 | return res; 217 | } 218 | 219 | template 220 | std::ostream & operator<<(std::ostream &stream, const Matrix<_Td> &mat) 221 | { 222 | std::ostream::fmtflags oldFlags = stream.flags(); 223 | stream.precision(8); 224 | stream.setf(std::ios::fixed | std::ios::right); 225 | 226 | stream << '\n'; 227 | for (size_t i = 0; i < mat.RowSize(); ++i) { 228 | for (size_t j = 0; j < mat.ColSize(); ++j) { 229 | stream << std::setw(15) << mat[i][j]; 230 | } 231 | stream << '\n'; 232 | } 233 | 234 | stream.flags(oldFlags); 235 | return stream; 236 | } 237 | 238 | template 239 | Matrix<_Td> I(const size_t &n) 240 | { 241 | Matrix<_Td> res(n, n, 0); 242 | for (size_t i = 0; i < n; ++i) { 243 | res[i][i] = static_cast<_Td>(1); 244 | } 245 | return res; 246 | } 247 | 248 | template 249 | Matrix<_Td> Pow(Matrix<_Td> A, size_t &b) 250 | { 251 | if (A.RowSize() != A.ColSize()) { 252 | throw std::invalid_argument("The row size and column size are different."); 253 | } 254 | Matrix<_Td> result = I<_Td>(A.ColSize()); 255 | while (b > 0) { 256 | if (b & static_cast(1)) { 257 | result = result * A; 258 | } 259 | A = A * A; 260 | b = b >> static_cast(1); 261 | } 262 | return result; 263 | } 264 | 265 | } 266 | #endif 267 | -------------------------------------------------------------------------------- /deque/data/five/answer.txt: -------------------------------------------------------------------------------- 1 | test start: 2 | test1: push & pop Accept 3 | test2: at & [] & front & back Accept 4 | test3: itetator operation Accept 5 | test4: const_itetator operation Accept 6 | test5: erase & insert Accept 7 | test6: clear & copy & assignment Accept 8 | test7: complexity Accept 9 | -------------------------------------------------------------------------------- /deque/data/five/code.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "deque.hpp" 10 | #include "exceptions.hpp" 11 | 12 | 13 | /***************************/ 14 | bool need_to_check_throw = 1; 15 | bool good_complexity = 0;//if the complexity is N^2, change to 0 16 | int N = good_complexity ? 300000 : 1000; 17 | /***************************/ 18 | 19 | 20 | class T{ 21 | private: 22 | int x; 23 | public: 24 | T(int x):x(x){} 25 | int num()const {return x;} 26 | void change(int y){ 27 | x = y; 28 | } 29 | }; 30 | bool operator == (const T &a, const T &b){ 31 | return a.num() == b.num(); 32 | } 33 | bool operator != (const T &a, const T &b){ 34 | return a.num() != b.num(); 35 | } 36 | sjtu::deque q; 37 | std::deque stl; 38 | sjtu::deque::iterator it_q; 39 | std::deque::iterator it_stl; 40 | sjtu::deque::const_iterator _it_q; 41 | std::deque::const_iterator _it_stl; 42 | bool equal(){ 43 | if(q.size() != stl.size()) return 0; 44 | if(q.empty() != stl.empty()) return 0; 45 | int cnt = 0; 46 | for(it_q = q.begin(), it_stl = stl.begin(); it_q != q.end() || it_stl != stl.end(); it_q++, it_stl++){ 47 | if(*it_q != *it_stl) { 48 | printf("cnt = %d\n",cnt); 49 | return 0; 50 | } 51 | cnt++; 52 | } 53 | return 1; 54 | } 55 | void test1(){ 56 | printf("test1: push & pop "); 57 | for(int i=1;i<=N;i++){ 58 | if(i % 10 <= 3) q.push_back(T(i)), stl.push_back(T(i));else 59 | if(i % 10 <= 7) q.push_front(T(i)), stl.push_front(T(i));else 60 | if(i % 10 <= 8) q.pop_back(), stl.pop_back();else 61 | if(i % 10 <= 9) q.pop_front(), stl.pop_front(); 62 | } 63 | if(!equal()){puts("Wrong Answer");return;} 64 | while (!q.empty()){ 65 | q.pop_back(); 66 | stl.pop_back(); 67 | } 68 | puts("Accept"); 69 | } 70 | void test2(){ 71 | printf("test2: at & [] & front & back "); 72 | int flag = 0; 73 | try{ 74 | int t = q.front().num(); 75 | }catch(...){flag ++;} 76 | 77 | try{ 78 | int t = q.back().num(); 79 | }catch(...){flag ++;} 80 | if(flag != 2 && need_to_check_throw){puts("Wrong Answer");return;} 81 | for(int i=1;i<=N;i++){ 82 | if(i % 10 <= 3) q.push_back(T(i)), stl.push_back(T(i));else 83 | if(i % 10 <= 7) q.push_front(T(i)), stl.push_front(T(i));else 84 | if(i % 10 <= 8) q.pop_back(), stl.pop_back();else 85 | if(i % 10 <= 9) q.pop_front(), stl.pop_front(); 86 | } 87 | flag = 0; 88 | try{ 89 | int t = (q.at(q.size() + 100)).num(); 90 | }catch(...){flag = 1;} 91 | if(flag != 1 && need_to_check_throw){puts("Wrong Answer");return;} 92 | int num = q.size(); 93 | for(int i=0;i<100;i++) 94 | { 95 | int t = rand() % num; 96 | if(q[t] != stl[t] || q.at(t) != stl.at(t)){puts("Wrong Answer");return;} 97 | } 98 | if(q.front() != stl.front() || q.back() != stl.back()){puts("Wrong Answer");return;} 99 | puts("Accept"); 100 | } 101 | void test3(){ 102 | printf("test3: itetator operation "); 103 | int num = q.size(); 104 | for(int i =1 ; i <= 1000; i++) 105 | { 106 | int t1 = rand() % num; 107 | int t2 = rand() % num; 108 | if(*(q.begin() + t1) != *(stl.begin() + t1)){puts("Wrong Answer");return;} 109 | if(t2 && *(q.end() - t2) != *(stl.end() - t2)){puts("Wrong Answer");return;} 110 | if((q.begin() + t1) - (q.begin() + t2) != (t1 - t2)){puts("Wrong Answer");return;} 111 | } 112 | if((q.begin() + num) != q.end()) {puts("Wrong Answer");return;} 113 | if((q.end() - num) != q.begin()) {puts("Wrong Answer");return;} 114 | bool flag=0; 115 | sjtu::deque other; 116 | try{ 117 | int t = q.begin() - other.begin(); 118 | }catch(...){ 119 | flag=1; 120 | } 121 | if(!flag && need_to_check_throw) {puts("Wrong Answer");return;} 122 | it_q = q.begin(); 123 | it_stl = stl.begin(); 124 | for(int i=1;i<=10;i++){ 125 | int t = rand() % (num / 10); 126 | it_q += t; 127 | it_stl += t; 128 | if(*it_q != *it_stl) {puts("Wrong Answer");return;} 129 | if(it_q -> num() != it_stl -> num()) {puts("Wrong Answer");return;} 130 | } 131 | it_q = --q.end(); 132 | it_stl = --stl.end(); 133 | if(*it_q != *it_stl) {puts("Wrong Answer");return;} 134 | for(int i=1;i<10;i++){ 135 | int t = rand() % (num / 10); 136 | it_q -= t; 137 | it_stl -= t; 138 | if(*it_q != *it_stl) {puts("Wrong Answer");return;} 139 | it_q -> change(t);; 140 | it_stl -> change(t); 141 | if(*it_q != *it_stl) {puts("Wrong Answer");return;} 142 | } 143 | if(!equal()) {puts("Wrong Answer");return;} 144 | if (!(q.begin() + 10 == q.begin() +5 + 6 - 1)) {puts("Wrong Answer");return;} 145 | sjtu::deque pp; 146 | if(q.end() == pp.end()){puts("Wrong Answer");return;} 147 | 148 | int t = rand() % (q.size() - 1); 149 | it_q = q.begin() + t; 150 | it_stl = stl.begin() + t; 151 | const sjtu::deque::iterator it_q_const(++it_q); 152 | const std::deque::iterator it_stl_const(++it_stl); 153 | if(*it_q_const != *it_stl_const){puts("Wrong Answer");return;} 154 | if(it_q_const -> num() != it_stl_const -> num()){puts("Wrong Answer");return;} 155 | it_q_const -> change(t); 156 | it_stl_const -> change(t); 157 | if(!equal()){puts("Wrong Answer");return;} 158 | puts("Accept"); 159 | } 160 | 161 | void test4(){ 162 | printf("test4: const_itetator operation "); 163 | const sjtu::deque _q(q); 164 | const std::deque _stl(stl); 165 | int num = _q.size(); 166 | for(int i =1 ; i <= 1000; i++) 167 | { 168 | int t1 = rand() % num; 169 | int t2 = rand() % num; 170 | if(*(_q.cbegin() + t1) != *(_stl.cbegin() + t1)){puts("Wrong Answer");return;} 171 | if(t2 && *(_q.cend() - t2) != *(_stl.cend() - t2)){puts("Wrong Answer");return;} 172 | if((_q.cbegin() + t1) - (_q.cbegin() + t2) != (t1 - t2)){puts("Wrong Answer");return;} 173 | } 174 | if((_q.cbegin() + num) != _q.cend()) {puts("Wrong Answer");return;} 175 | if((_q.cend() - num) != _q.cbegin()) {puts("Wrong Answer");return;} 176 | _it_q = _q.cbegin(); 177 | _it_stl = _stl.cbegin(); 178 | for(int i=1;i<=10;i++){ 179 | int t = rand() % (num / 10); 180 | _it_q += t; 181 | _it_stl += t; 182 | if(*_it_q != *_it_stl) {puts("Wrong Answer");return;} 183 | if(_it_q -> num() != _it_stl -> num()) {puts("Wrong Answer");return;} 184 | } 185 | _it_q = --_q.cend(); 186 | _it_stl = --_stl.cend(); 187 | if(*_it_q != *_it_stl) {puts("Wrong Answer");return;} 188 | if (!(_q.cbegin() + 10 == _q.cbegin() +5 + 6 - 1)) {puts("Wrong Answer");return;} 189 | puts("Accept"); 190 | } 191 | 192 | void test5(){ 193 | printf("test5: erase & insert "); 194 | for(int i=1;i<=sqrt(N) && q.size()>=10;i++) 195 | { 196 | int t = rand() % (q.size() - 3); 197 | it_q = q.begin() + t; 198 | it_stl = stl.begin() + t; 199 | it_q = q.erase(it_q); 200 | it_stl = stl.erase(it_stl); 201 | it_q = q.erase(it_q); 202 | it_stl = stl.erase(it_stl); 203 | it_q -> change(t); 204 | it_stl -> change(t); 205 | } 206 | if(!equal()) {puts("Wrong Answer");return;} 207 | it_q = q.erase(q.end() - 1); 208 | it_stl = stl.erase(stl.end() - 1); 209 | if(it_q != q.end()){puts("Wrong Answer");return;} 210 | for(int i = 1; i <= sqrt(N); i++) 211 | { 212 | int t = rand() % q.size(); 213 | it_q = q.begin() + t; 214 | it_stl = stl.begin() + t; 215 | it_q = q.insert(it_q, T(t)); 216 | it_stl = stl.insert(it_stl, T(t)); 217 | 218 | it_q = q.insert(it_q, T(t + 1)); 219 | it_stl = stl.insert(it_stl, T(t + 1)); 220 | } 221 | it_q = q.begin(); 222 | it_stl = stl.begin(); 223 | for(int i=1;i<=sqrt(N);i++) 224 | { 225 | it_q = q.insert(it_q, T(i)); 226 | it_stl = stl.insert(it_stl, T(i)); 227 | } 228 | it_q = q.insert(q.end(), T(23333)); 229 | it_stl = stl.insert(stl.end(),T(23333)); 230 | if(it_q != q.end() - 1){puts("Wrong Answer");return;} 231 | if(!equal()) {puts("Wrong Answer");return;} 232 | puts("Accept"); 233 | } 234 | void test6(){ 235 | printf("test6: clear & copy & assignment "); 236 | sjtu::deque p(q), r; 237 | r = q; 238 | q.clear(); 239 | if(!q.empty() || q.size() != 0 || q.begin()!=q.end()){puts("Wrong Answer");return;} 240 | q=q=q; 241 | if(!q.empty() || q.size() != 0 || q.begin()!=q.end()){puts("Wrong Answer");return;} 242 | for(int i=1;i<=100;i++) 243 | { 244 | int t = rand() % p.size(); 245 | p.push_back(T(t)); 246 | p.insert(p.begin() + t, T(t)); 247 | r.push_back(T(t)); 248 | r.insert(r.begin() + t, T(t)); 249 | stl.push_back(T(t)); 250 | stl.insert(stl.begin() + t, T(t)); 251 | } 252 | 253 | q = p; 254 | p.clear(); 255 | q=q=q=q; 256 | if(!equal()) {puts("Wrong Answer");return;} 257 | q.clear(); 258 | q = r; 259 | r.clear(); 260 | q=q=q=q; 261 | if(!equal()) {puts("Wrong Answer");return;} 262 | puts("Accept"); 263 | } 264 | void test7(){ 265 | printf("test7: complexity "); 266 | int num = 500000; 267 | static sjtu::deque q; 268 | for(int i = 0; i < num; i++) q.push_front(T(i)); 269 | for(int i = 0; i < num; i++) q.pop_front(); 270 | for(int i = 0; i < num; i++) q.push_back(T(i)); 271 | for(int i = 0; i < num; i++) q.pop_back(); 272 | for(int i = 0; i < num;i++){ 273 | if(i % 10 <= 3) q.push_back(T(i));else 274 | if(i % 10 <= 7) q.push_front(T(i));else 275 | if(i % 10 <= 8) q.pop_back();else 276 | if(i % 10 <= 9) q.pop_front(); 277 | } 278 | int test_num = 5000000; 279 | it_q = q.begin() + q.size() - 10; 280 | for(int i = 0; i < test_num; i++) 281 | { 282 | int tmp = (*it_q).num(); 283 | tmp = it_q -> num(); 284 | if(i % (test_num / 10) == 0) it_q = q.begin() + rand() % q.size(); 285 | } 286 | for(int i = 0; i < N; i++){ 287 | it_q = q.begin() + rand() % q.size(); 288 | q.insert(it_q, T(rand())); 289 | } 290 | for(int i = 0; i < N; i++){ 291 | it_q = q.begin() + rand() % q.size(); 292 | q.erase(it_q); 293 | } 294 | for(int i = 0; i < N; i++){ 295 | int tmp = q[rand() % q.size()].num(); 296 | tmp = q.at(rand() % q.size()).num(); 297 | } 298 | if(good_complexity){ 299 | q.clear(); 300 | for(int i=0;i<4000000;i++) 301 | q.push_back(i); 302 | while (q.size()>2010){ 303 | if(rand() % 2) q.pop_front(); 304 | else q.pop_back(); 305 | } 306 | int tmp; 307 | for(int i=0;i<2000000;i++){ 308 | tmp = q[2000].num(); 309 | tmp = q[1000].num(); 310 | } 311 | } 312 | puts("Accept"); 313 | } 314 | int main(){ 315 | srand(time(NULL)); 316 | puts("test start:"); 317 | test1();//push & pop 318 | test2();//at & [] & front & back 319 | test3();//iterator operation 320 | test4();//const_iterator operation 321 | test5();//erase & insert 322 | test6();//clear & copy & assignment 323 | test7();//complexity 324 | } 325 | -------------------------------------------------------------------------------- /deque/data/four.memcheck/answer.txt: -------------------------------------------------------------------------------- 1 | test start: 2 | test1: push & pop Accept 3 | test2: at & [] & front & back Accept 4 | test3: itetator operation Accept 5 | test4: const_itetator operation Accept 6 | test5: erase & insert Accept 7 | test6: clear & copy & assignment Accept 8 | test7: complexity Accept 9 | -------------------------------------------------------------------------------- /deque/data/four.memcheck/code.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "deque.hpp" 10 | #include "exceptions.hpp" 11 | 12 | 13 | /***************************/ 14 | bool need_to_check_throw = 1; 15 | bool good_complexity = 0;//if the complexity is N^2, change to 0 16 | int N = good_complexity ? 300000 : 1000; 17 | /***************************/ 18 | 19 | 20 | class T{ 21 | private: 22 | int x; 23 | public: 24 | T(int x):x(x){} 25 | int num()const {return x;} 26 | void change(int y){ 27 | x = y; 28 | } 29 | }; 30 | bool operator == (const T &a, const T &b){ 31 | return a.num() == b.num(); 32 | } 33 | bool operator != (const T &a, const T &b){ 34 | return a.num() != b.num(); 35 | } 36 | sjtu::deque q; 37 | std::deque stl; 38 | sjtu::deque::iterator it_q; 39 | std::deque::iterator it_stl; 40 | sjtu::deque::const_iterator _it_q; 41 | std::deque::const_iterator _it_stl; 42 | bool equal(){ 43 | if(q.size() != stl.size()) return 0; 44 | if(q.empty() != stl.empty()) return 0; 45 | int cnt = 0; 46 | for(it_q = q.begin(), it_stl = stl.begin(); it_q != q.end() || it_stl != stl.end(); it_q++, it_stl++){ 47 | if(*it_q != *it_stl) { 48 | printf("cnt = %d\n",cnt); 49 | return 0; 50 | } 51 | cnt++; 52 | } 53 | return 1; 54 | } 55 | void test1(){ 56 | printf("test1: push & pop "); 57 | for(int i=1;i<=N;i++){ 58 | if(i % 10 <= 3) q.push_back(T(i)), stl.push_back(T(i));else 59 | if(i % 10 <= 7) q.push_front(T(i)), stl.push_front(T(i));else 60 | if(i % 10 <= 8) q.pop_back(), stl.pop_back();else 61 | if(i % 10 <= 9) q.pop_front(), stl.pop_front(); 62 | } 63 | if(!equal()){puts("Wrong Answer");return;} 64 | while (!q.empty()){ 65 | q.pop_back(); 66 | stl.pop_back(); 67 | } 68 | puts("Accept"); 69 | } 70 | void test2(){ 71 | printf("test2: at & [] & front & back "); 72 | int flag = 0; 73 | try{ 74 | int t = q.front().num(); 75 | }catch(...){flag ++;} 76 | 77 | try{ 78 | int t = q.back().num(); 79 | }catch(...){flag ++;} 80 | if(flag != 2 && need_to_check_throw){puts("Wrong Answer");return;} 81 | for(int i=1;i<=N;i++){ 82 | if(i % 10 <= 3) q.push_back(T(i)), stl.push_back(T(i));else 83 | if(i % 10 <= 7) q.push_front(T(i)), stl.push_front(T(i));else 84 | if(i % 10 <= 8) q.pop_back(), stl.pop_back();else 85 | if(i % 10 <= 9) q.pop_front(), stl.pop_front(); 86 | } 87 | flag = 0; 88 | try{ 89 | int t = (q.at(q.size() + 100)).num(); 90 | }catch(...){flag = 1;} 91 | if(flag != 1 && need_to_check_throw){puts("Wrong Answer");return;} 92 | int num = q.size(); 93 | for(int i=0;i<100;i++) 94 | { 95 | int t = rand() % num; 96 | if(q[t] != stl[t] || q.at(t) != stl.at(t)){puts("Wrong Answer");return;} 97 | } 98 | if(q.front() != stl.front() || q.back() != stl.back()){puts("Wrong Answer");return;} 99 | puts("Accept"); 100 | } 101 | void test3(){ 102 | printf("test3: itetator operation "); 103 | int num = q.size(); 104 | for(int i =1 ; i <= 1000; i++) 105 | { 106 | int t1 = rand() % num; 107 | int t2 = rand() % num; 108 | if(*(q.begin() + t1) != *(stl.begin() + t1)){puts("Wrong Answer");return;} 109 | if(t2 && *(q.end() - t2) != *(stl.end() - t2)){puts("Wrong Answer");return;} 110 | if((q.begin() + t1) - (q.begin() + t2) != (t1 - t2)){puts("Wrong Answer");return;} 111 | } 112 | if((q.begin() + num) != q.end()) {puts("Wrong Answer");return;} 113 | if((q.end() - num) != q.begin()) {puts("Wrong Answer");return;} 114 | bool flag=0; 115 | sjtu::deque other; 116 | try{ 117 | int t = q.begin() - other.begin(); 118 | }catch(...){ 119 | flag=1; 120 | } 121 | if(!flag && need_to_check_throw) {puts("Wrong Answer");return;} 122 | it_q = q.begin(); 123 | it_stl = stl.begin(); 124 | for(int i=1;i<=10;i++){ 125 | int t = rand() % (num / 10); 126 | it_q += t; 127 | it_stl += t; 128 | if(*it_q != *it_stl) {puts("Wrong Answer");return;} 129 | if(it_q -> num() != it_stl -> num()) {puts("Wrong Answer");return;} 130 | } 131 | it_q = --q.end(); 132 | it_stl = --stl.end(); 133 | if(*it_q != *it_stl) {puts("Wrong Answer");return;} 134 | for(int i=1;i<10;i++){ 135 | int t = rand() % (num / 10); 136 | it_q -= t; 137 | it_stl -= t; 138 | if(*it_q != *it_stl) {puts("Wrong Answer");return;} 139 | it_q -> change(t);; 140 | it_stl -> change(t); 141 | if(*it_q != *it_stl) {puts("Wrong Answer");return;} 142 | } 143 | if(!equal()) {puts("Wrong Answer");return;} 144 | if (!(q.begin() + 10 == q.begin() +5 + 6 - 1)) {puts("Wrong Answer");return;} 145 | sjtu::deque pp; 146 | if(q.end() == pp.end()){puts("Wrong Answer");return;} 147 | 148 | int t = rand() % (q.size() - 1); 149 | it_q = q.begin() + t; 150 | it_stl = stl.begin() + t; 151 | const sjtu::deque::iterator it_q_const(++it_q); 152 | const std::deque::iterator it_stl_const(++it_stl); 153 | if(*it_q_const != *it_stl_const){puts("Wrong Answer");return;} 154 | if(it_q_const -> num() != it_stl_const -> num()){puts("Wrong Answer");return;} 155 | it_q_const -> change(t); 156 | it_stl_const -> change(t); 157 | if(!equal()){puts("Wrong Answer");return;} 158 | puts("Accept"); 159 | } 160 | 161 | void test4(){ 162 | printf("test4: const_itetator operation "); 163 | const sjtu::deque _q(q); 164 | const std::deque _stl(stl); 165 | int num = _q.size(); 166 | for(int i =1 ; i <= 1000; i++) 167 | { 168 | int t1 = rand() % num; 169 | int t2 = rand() % num; 170 | if(*(_q.cbegin() + t1) != *(_stl.cbegin() + t1)){puts("Wrong Answer");return;} 171 | if(t2 && *(_q.cend() - t2) != *(_stl.cend() - t2)){puts("Wrong Answer");return;} 172 | if((_q.cbegin() + t1) - (_q.cbegin() + t2) != (t1 - t2)){puts("Wrong Answer");return;} 173 | } 174 | if((_q.cbegin() + num) != _q.cend()) {puts("Wrong Answer");return;} 175 | if((_q.cend() - num) != _q.cbegin()) {puts("Wrong Answer");return;} 176 | _it_q = _q.cbegin(); 177 | _it_stl = _stl.cbegin(); 178 | for(int i=1;i<=10;i++){ 179 | int t = rand() % (num / 10); 180 | _it_q += t; 181 | _it_stl += t; 182 | if(*_it_q != *_it_stl) {puts("Wrong Answer");return;} 183 | if(_it_q -> num() != _it_stl -> num()) {puts("Wrong Answer");return;} 184 | } 185 | _it_q = --_q.cend(); 186 | _it_stl = --_stl.cend(); 187 | if(*_it_q != *_it_stl) {puts("Wrong Answer");return;} 188 | if (!(_q.cbegin() + 10 == _q.cbegin() +5 + 6 - 1)) {puts("Wrong Answer");return;} 189 | puts("Accept"); 190 | } 191 | 192 | void test5(){ 193 | printf("test5: erase & insert "); 194 | for(int i=1;i<=sqrt(N) && q.size()>=10;i++) 195 | { 196 | int t = rand() % (q.size() - 3); 197 | it_q = q.begin() + t; 198 | it_stl = stl.begin() + t; 199 | it_q = q.erase(it_q); 200 | it_stl = stl.erase(it_stl); 201 | it_q = q.erase(it_q); 202 | it_stl = stl.erase(it_stl); 203 | it_q -> change(t); 204 | it_stl -> change(t); 205 | } 206 | if(!equal()) {puts("Wrong Answer");return;} 207 | it_q = q.erase(q.end() - 1); 208 | it_stl = stl.erase(stl.end() - 1); 209 | if(it_q != q.end()){puts("Wrong Answer");return;} 210 | for(int i = 1; i <= sqrt(N); i++) 211 | { 212 | int t = rand() % q.size(); 213 | it_q = q.begin() + t; 214 | it_stl = stl.begin() + t; 215 | it_q = q.insert(it_q, T(t)); 216 | it_stl = stl.insert(it_stl, T(t)); 217 | 218 | it_q = q.insert(it_q, T(t + 1)); 219 | it_stl = stl.insert(it_stl, T(t + 1)); 220 | } 221 | it_q = q.begin(); 222 | it_stl = stl.begin(); 223 | for(int i=1;i<=sqrt(N);i++) 224 | { 225 | it_q = q.insert(it_q, T(i)); 226 | it_stl = stl.insert(it_stl, T(i)); 227 | } 228 | it_q = q.insert(q.end(), T(23333)); 229 | it_stl = stl.insert(stl.end(),T(23333)); 230 | if(it_q != q.end() - 1){puts("Wrong Answer");return;} 231 | if(!equal()) {puts("Wrong Answer");return;} 232 | puts("Accept"); 233 | } 234 | void test6(){ 235 | printf("test6: clear & copy & assignment "); 236 | sjtu::deque p(q), r; 237 | r = q; 238 | q.clear(); 239 | if(!q.empty() || q.size() != 0 || q.begin()!=q.end()){puts("Wrong Answer");return;} 240 | q=q=q; 241 | if(!q.empty() || q.size() != 0 || q.begin()!=q.end()){puts("Wrong Answer");return;} 242 | for(int i=1;i<=100;i++) 243 | { 244 | int t = rand() % p.size(); 245 | p.push_back(T(t)); 246 | p.insert(p.begin() + t, T(t)); 247 | r.push_back(T(t)); 248 | r.insert(r.begin() + t, T(t)); 249 | stl.push_back(T(t)); 250 | stl.insert(stl.begin() + t, T(t)); 251 | } 252 | 253 | q = p; 254 | p.clear(); 255 | q=q=q=q; 256 | if(!equal()) {puts("Wrong Answer");return;} 257 | q.clear(); 258 | q = r; 259 | r.clear(); 260 | q=q=q=q; 261 | if(!equal()) {puts("Wrong Answer");return;} 262 | puts("Accept"); 263 | } 264 | void test7(){ 265 | printf("test7: complexity "); 266 | int num = 500000; 267 | static sjtu::deque q; 268 | for(int i = 0; i < num; i++) q.push_front(T(i)); 269 | for(int i = 0; i < num; i++) q.pop_front(); 270 | for(int i = 0; i < num; i++) q.push_back(T(i)); 271 | for(int i = 0; i < num; i++) q.pop_back(); 272 | for(int i = 0; i < num;i++){ 273 | if(i % 10 <= 3) q.push_back(T(i));else 274 | if(i % 10 <= 7) q.push_front(T(i));else 275 | if(i % 10 <= 8) q.pop_back();else 276 | if(i % 10 <= 9) q.pop_front(); 277 | } 278 | int test_num = 5000000; 279 | it_q = q.begin() + q.size() - 10; 280 | for(int i = 0; i < test_num; i++) 281 | { 282 | int tmp = (*it_q).num(); 283 | tmp = it_q -> num(); 284 | if(i % (test_num / 10) == 0) it_q = q.begin() + rand() % q.size(); 285 | } 286 | for(int i = 0; i < N; i++){ 287 | it_q = q.begin() + rand() % q.size(); 288 | q.insert(it_q, T(rand())); 289 | } 290 | for(int i = 0; i < N; i++){ 291 | it_q = q.begin() + rand() % q.size(); 292 | q.erase(it_q); 293 | } 294 | for(int i = 0; i < N; i++){ 295 | int tmp = q[rand() % q.size()].num(); 296 | tmp = q.at(rand() % q.size()).num(); 297 | } 298 | if(good_complexity){ 299 | q.clear(); 300 | for(int i=0;i<4000000;i++) 301 | q.push_back(i); 302 | while (q.size()>2010){ 303 | if(rand() % 2) q.pop_front(); 304 | else q.pop_back(); 305 | } 306 | int tmp; 307 | for(int i=0;i<2000000;i++){ 308 | tmp = q[2000].num(); 309 | tmp = q[1000].num(); 310 | } 311 | } 312 | puts("Accept"); 313 | } 314 | int main(){ 315 | srand(time(NULL)); 316 | puts("test start:"); 317 | test1();//push & pop 318 | test2();//at & [] & front & back 319 | test3();//iterator operation 320 | test4();//const_iterator operation 321 | test5();//erase & insert 322 | test6();//clear & copy & assignment 323 | test7();//complexity 324 | } 325 | -------------------------------------------------------------------------------- /deque/data/four/answer.txt: -------------------------------------------------------------------------------- 1 | Deque CheckTool Package Version 1.5 Offical Version 2 | 3 | --------------------------------------------------------------------------- 4 | Test Zone B: Operation speed individually Testing... 5 | Test Size: 21000 Element(s) 6 | Test 1: push_back PASSED 7 | Test 2: pop_back PASSED 8 | Test 3: push_front PASSED 9 | Test 4: pop_front PASSED 10 | Test 5: front PASSED 11 | Test 6: back PASSED 12 | Test 7: begin PASSED 13 | Test 8: end PASSED 14 | Test 9: at PASSED 15 | Test 10: [] PASSED 16 | Test 11: iterator ++ PASSED 17 | Test 12: iterator -- PASSED 18 | Test 13: iterator +n PASSED 19 | Test 14: iterator -n PASSED 20 | Test 15: insert PASSED 21 | Test 16: erase PASSED 22 | Test 17: Copy Constructor PASSED 23 | Test 18: Equal Operator PASSED 24 | --------------------------------------------------------------------------- 25 | -------------------------------------------------------------------------------- /deque/data/one.memcheck/answer.txt: -------------------------------------------------------------------------------- 1 | Test 1 : Test for classes without default constructor...Correct. 2 | Test 2 : Test for Matrix, a class with dynamic members...Correct. 3 | Test 3 : Test for big integer...Correct. 4 | Test 4 : Test for copy constructor and operator=...Correct. 5 | Test 5 : Test for accessing the container in the order of the sequence, using iterator...Correct. 6 | Test 6 : Test for accessing the container randomly, using iterator...Correct. 7 | Test 7 : Test for random erase and insert...Correct. 8 | Test 8 : Test for pop() and push()...Correct. 9 | Congratulations. Your submission has passed all correctness tests. Use valgrind to ensure that there ain't any memory leaks in your deque. Good job! :) 10 | -------------------------------------------------------------------------------- /deque/data/one.memcheck/code.cpp: -------------------------------------------------------------------------------- 1 | //Provided by desire2020/Steve Lu 2 | 3 | /*********************************************************************** 4 | Hint: This test case almost completely tests the correctness of your deque. 5 | So if all tests are passed, feel free to enhance your performance! :) 6 | Yours Sincerely. Rabbit. 7 | ***********************************************************************/ 8 | #include "class-integer.hpp" 9 | #include "class-matrix.hpp" 10 | #include "class-bint.hpp" 11 | #include 12 | #include 13 | #include 14 | #include "deque.hpp" 15 | 16 | long long randNum(long long x,long long maxNum) 17 | { 18 | x = (x * 10007) % maxNum; 19 | return x + 1; 20 | } 21 | const size_t N = 10005LL; 22 | 23 | void error() 24 | { 25 | std::cout << "Error, mismatch found." << std::endl; 26 | exit(0); 27 | } 28 | 29 | void TestInteger() 30 | { 31 | std::cout << "Test 1 : Test for classes without default constructor..."; 32 | sjtu::deque dInt; 33 | std::vector vInt; 34 | for (int i = 0; i < N; ++i) { 35 | vInt.push_back(Integer(randNum(i, N + 17))); 36 | dInt.push_back(vInt[i]); 37 | } 38 | for (int i = 0; i < N; ++i) { 39 | if (!(vInt[i] == dInt[i])) 40 | error(); 41 | } 42 | std::cout << "Correct." << std::endl; 43 | } 44 | void TestMatrix() 45 | { 46 | std::cout << "Test 2 : Test for Matrix, a class with dynamic members..."; 47 | sjtu::deque> dM; 48 | std::vector> vM; 49 | for (int i = 0; i < N; ++i) { 50 | vM.push_back(Diamond::Matrix(randNum(i + 1, 10 + 7), randNum(i + 2, 10 + 7), randNum(i + 3, (100 + 17)) * 1.0 / randNum(i, 17))); 51 | dM.push_back(vM[i]); 52 | } 53 | for (int i = 0; i < N; ++i) { 54 | if (!(vM[i] == dM[i])) 55 | error(); 56 | } 57 | std::cout << "Correct." << std::endl; 58 | } 59 | 60 | void TestBint() 61 | { 62 | std::cout << "Test 3 : Test for big integer..."; 63 | sjtu::deque dBint; 64 | std::vector vBint; 65 | for (long long i = 1LL << 50; i < (1LL << 50) + N; ++i) { 66 | vBint.push_back(Util::Bint(i) * randNum(i, (1 << 25) )); 67 | dBint.push_back(vBint.back()); 68 | } 69 | 70 | for (int i = 0; i < N; ++i) { 71 | if (!(vBint[i] == dBint[i])) 72 | error(); 73 | } 74 | std::cout << "Correct." << std::endl; 75 | } 76 | 77 | void TestCopyConstructorAndOperatorEqu() 78 | { 79 | std::cout << "Test 4 : Test for copy constructor and operator=..."; 80 | sjtu::deque *pInt; 81 | pInt = new sjtu::deque; 82 | for (long long i = 0; i < N; ++i) { 83 | pInt -> push_back(i); 84 | } 85 | sjtu::deque &dInt = *pInt; 86 | sjtu::deque dualInt(dInt); 87 | sjtu::deque dualInt_oper; 88 | dualInt_oper = dInt; 89 | for (long long i = 0; i < N; ++i) 90 | { 91 | if (dualInt[i] != dInt[i] || dualInt_oper[i] != dInt[i]) 92 | error(); 93 | } 94 | dualInt_oper = dualInt_oper; 95 | delete pInt; 96 | for (long long i = 0; i < N; ++i) 97 | { 98 | if (dualInt_oper[i] != dualInt[i]) 99 | error(); 100 | } 101 | std::cout << "Correct." << std::endl; 102 | } 103 | 104 | void TestIteratorSequenceAccess() 105 | { 106 | std::cout << "Test 5 : Test for accessing the container in the order of the sequence, using iterator..."; 107 | sjtu::deque dInt; 108 | for (long long i = 0; i < N; ++i) { 109 | dInt.push_back(i); 110 | } 111 | sjtu::deque :: iterator it; 112 | it = dInt.begin(); 113 | for (long long i = 0; i < N; ++i) { 114 | if (!(*it == dInt[i])) 115 | error(); 116 | ++it; 117 | } 118 | if (it != dInt.end()) 119 | error(); 120 | std::cout << "Correct." << std::endl; 121 | } 122 | 123 | void TestIteratorRandomAccess() 124 | { 125 | std::cout << "Test 6 : Test for accessing the container randomly, using iterator..."; 126 | sjtu::deque dInt; 127 | std::vector vInt; 128 | for (long long i = 0; i < N; ++i) { 129 | dInt.push_back(i); 130 | vInt.push_back(i); 131 | } 132 | for (long long i = 0; i < N; ++i) { 133 | if (!(*(dInt.begin() + i) == vInt[i])) 134 | error(); 135 | } 136 | std::cout << "Correct." << std::endl; 137 | } 138 | 139 | void TestInsertAndErase() 140 | { 141 | std::cout << "Test 7 : Test for random erase and insert..."; 142 | sjtu::deque dInt; 143 | std::vector vInt; 144 | for (long long i = 0; i < N; ++i) { 145 | dInt.push_back(i); 146 | vInt.push_back(i); 147 | } 148 | vInt.insert(vInt.begin() + 2, 2); 149 | dInt.insert(dInt.begin() + 2, 2); 150 | vInt.insert(vInt.begin() + 23, 23); 151 | dInt.insert(dInt.begin() + 23, 23); 152 | vInt.insert(vInt.begin() + 233, 233); 153 | dInt.insert(dInt.begin() + 233, 233); 154 | vInt.erase(vInt.begin() + 2333); 155 | dInt.erase(dInt.begin() + 2333); 156 | for (long long i = 0; i < N; ++i) { 157 | if (!(*(dInt.begin() + i) == vInt[i])) 158 | error(); 159 | } 160 | std::cout << "Correct." << std::endl; 161 | } 162 | 163 | void TestPopAndPush() 164 | { 165 | std::cout << "Test 8 : Test for pop() and push()..."; 166 | sjtu::deque dInt, drInt; 167 | std::vector vInt; 168 | std::vector rInt; 169 | for (size_t i = 0; i < 1114LL; ++i) 170 | { 171 | dInt.push_back(i); 172 | vInt.push_back(i); 173 | } 174 | for (size_t i = 0; i < 107LL; ++i) 175 | { 176 | dInt.pop_back(); 177 | vInt.pop_back(); 178 | } 179 | for (size_t i = 0; i < 1114LL; ++i) 180 | { 181 | drInt.push_front(i); 182 | rInt.push_back(i); 183 | } 184 | for (size_t i = 0; i < 107LL; ++i) 185 | { 186 | drInt.pop_front(); 187 | rInt.pop_back(); 188 | } 189 | for (size_t i = 0; i < 1007LL; ++i) 190 | { 191 | if (!(dInt[i] == vInt[i])) 192 | error(); 193 | if (!(drInt[1006LL - i] == rInt[i])) 194 | error(); 195 | } 196 | 197 | std::cout << "Correct." << std::endl; 198 | 199 | } 200 | 201 | int main() 202 | { 203 | TestInteger(); 204 | TestMatrix(); 205 | TestBint(); 206 | TestCopyConstructorAndOperatorEqu(); 207 | TestIteratorSequenceAccess(); 208 | TestIteratorRandomAccess(); 209 | TestInsertAndErase(); 210 | TestPopAndPush(); 211 | std::cout << "Congratulations. Your submission has passed all correctness tests. Use valgrind to ensure that there ain't any memory leaks in your deque. Good job! :)" << std::endl; 212 | return 0; 213 | } -------------------------------------------------------------------------------- /deque/data/one/answer.txt: -------------------------------------------------------------------------------- 1 | Test 1 : Test for classes without default constructor...Correct. 2 | Test 2 : Test for Matrix, a class with dynamic members...Correct. 3 | Test 3 : Test for big integer...Correct. 4 | Test 4 : Test for copy constructor and operator=...Correct. 5 | Test 5 : Test for accessing the container in the order of the sequence, using iterator...Correct. 6 | Test 6 : Test for accessing the container randomly, using iterator...Correct. 7 | Test 7 : Test for random erase and insert...Correct. 8 | Test 8 : Test for pop() and push()...Correct. 9 | Congratulations. Your submission has passed all correctness tests. Use valgrind to ensure that there ain't any memory leaks in your deque. Good job! :) 10 | -------------------------------------------------------------------------------- /deque/data/one/code.cpp: -------------------------------------------------------------------------------- 1 | //Provided by desire2020/Steve Lu 2 | 3 | /*********************************************************************** 4 | Hint: This test case almost completely tests the correctness of your deque. 5 | So if all tests are passed, feel free to enhance your performance! :) 6 | Yours Sincerely. Rabbit. 7 | ***********************************************************************/ 8 | #include "class-integer.hpp" 9 | #include "class-matrix.hpp" 10 | #include "class-bint.hpp" 11 | #include 12 | #include 13 | #include 14 | #include "deque.hpp" 15 | 16 | long long randNum(long long x,long long maxNum) 17 | { 18 | x = (x * 10007) % maxNum; 19 | return x + 1; 20 | } 21 | const size_t N = 10005LL; 22 | 23 | void error() 24 | { 25 | std::cout << "Error, mismatch found." << std::endl; 26 | exit(0); 27 | } 28 | 29 | void TestInteger() 30 | { 31 | std::cout << "Test 1 : Test for classes without default constructor..."; 32 | sjtu::deque dInt; 33 | std::vector vInt; 34 | for (int i = 0; i < N; ++i) { 35 | vInt.push_back(Integer(randNum(i, N + 17))); 36 | dInt.push_back(vInt[i]); 37 | } 38 | for (int i = 0; i < N; ++i) { 39 | if (!(vInt[i] == dInt[i])) 40 | error(); 41 | } 42 | std::cout << "Correct." << std::endl; 43 | } 44 | void TestMatrix() 45 | { 46 | std::cout << "Test 2 : Test for Matrix, a class with dynamic members..."; 47 | sjtu::deque> dM; 48 | std::vector> vM; 49 | for (int i = 0; i < N; ++i) { 50 | vM.push_back(Diamond::Matrix(randNum(i + 1, 10 + 7), randNum(i + 2, 10 + 7), randNum(i + 3, (100 + 17)) * 1.0 / randNum(i, 17))); 51 | dM.push_back(vM[i]); 52 | } 53 | for (int i = 0; i < N; ++i) { 54 | if (!(vM[i] == dM[i])) 55 | error(); 56 | } 57 | std::cout << "Correct." << std::endl; 58 | } 59 | 60 | void TestBint() 61 | { 62 | std::cout << "Test 3 : Test for big integer..."; 63 | sjtu::deque dBint; 64 | std::vector vBint; 65 | for (long long i = 1LL << 50; i < (1LL << 50) + N; ++i) { 66 | vBint.push_back(Util::Bint(i) * randNum(i, (1 << 25) )); 67 | dBint.push_back(vBint.back()); 68 | } 69 | 70 | for (int i = 0; i < N; ++i) { 71 | if (!(vBint[i] == dBint[i])) 72 | error(); 73 | } 74 | std::cout << "Correct." << std::endl; 75 | } 76 | 77 | void TestCopyConstructorAndOperatorEqu() 78 | { 79 | std::cout << "Test 4 : Test for copy constructor and operator=..."; 80 | sjtu::deque *pInt; 81 | pInt = new sjtu::deque; 82 | for (long long i = 0; i < N; ++i) { 83 | pInt -> push_back(i); 84 | } 85 | sjtu::deque &dInt = *pInt; 86 | sjtu::deque dualInt(dInt); 87 | sjtu::deque dualInt_oper; 88 | dualInt_oper = dInt; 89 | for (long long i = 0; i < N; ++i) 90 | { 91 | if (dualInt[i] != dInt[i] || dualInt_oper[i] != dInt[i]) 92 | error(); 93 | } 94 | dualInt_oper = dualInt_oper; 95 | delete pInt; 96 | for (long long i = 0; i < N; ++i) 97 | { 98 | if (dualInt_oper[i] != dualInt[i]) 99 | error(); 100 | } 101 | std::cout << "Correct." << std::endl; 102 | } 103 | 104 | void TestIteratorSequenceAccess() 105 | { 106 | std::cout << "Test 5 : Test for accessing the container in the order of the sequence, using iterator..."; 107 | sjtu::deque dInt; 108 | for (long long i = 0; i < N; ++i) { 109 | dInt.push_back(i); 110 | } 111 | sjtu::deque :: iterator it; 112 | it = dInt.begin(); 113 | for (long long i = 0; i < N; ++i) { 114 | if (!(*it == dInt[i])) 115 | error(); 116 | ++it; 117 | } 118 | if (it != dInt.end()) 119 | error(); 120 | std::cout << "Correct." << std::endl; 121 | } 122 | 123 | void TestIteratorRandomAccess() 124 | { 125 | std::cout << "Test 6 : Test for accessing the container randomly, using iterator..."; 126 | sjtu::deque dInt; 127 | std::vector vInt; 128 | for (long long i = 0; i < N; ++i) { 129 | dInt.push_back(i); 130 | vInt.push_back(i); 131 | } 132 | for (long long i = 0; i < N; ++i) { 133 | if (!(*(dInt.begin() + i) == vInt[i])) 134 | error(); 135 | } 136 | std::cout << "Correct." << std::endl; 137 | } 138 | 139 | void TestInsertAndErase() 140 | { 141 | std::cout << "Test 7 : Test for random erase and insert..."; 142 | sjtu::deque dInt; 143 | std::vector vInt; 144 | for (long long i = 0; i < N; ++i) { 145 | dInt.push_back(i); 146 | vInt.push_back(i); 147 | } 148 | vInt.insert(vInt.begin() + 2, 2); 149 | dInt.insert(dInt.begin() + 2, 2); 150 | vInt.insert(vInt.begin() + 23, 23); 151 | dInt.insert(dInt.begin() + 23, 23); 152 | vInt.insert(vInt.begin() + 233, 233); 153 | dInt.insert(dInt.begin() + 233, 233); 154 | vInt.erase(vInt.begin() + 2333); 155 | dInt.erase(dInt.begin() + 2333); 156 | for (long long i = 0; i < N; ++i) { 157 | if (!(*(dInt.begin() + i) == vInt[i])) 158 | error(); 159 | } 160 | std::cout << "Correct." << std::endl; 161 | } 162 | 163 | void TestPopAndPush() 164 | { 165 | std::cout << "Test 8 : Test for pop() and push()..."; 166 | sjtu::deque dInt, drInt; 167 | std::vector vInt; 168 | std::vector rInt; 169 | for (size_t i = 0; i < 1114LL; ++i) 170 | { 171 | dInt.push_back(i); 172 | vInt.push_back(i); 173 | } 174 | for (size_t i = 0; i < 107LL; ++i) 175 | { 176 | dInt.pop_back(); 177 | vInt.pop_back(); 178 | } 179 | for (size_t i = 0; i < 1114LL; ++i) 180 | { 181 | drInt.push_front(i); 182 | rInt.push_back(i); 183 | } 184 | for (size_t i = 0; i < 107LL; ++i) 185 | { 186 | drInt.pop_front(); 187 | rInt.pop_back(); 188 | } 189 | for (size_t i = 0; i < 1007LL; ++i) 190 | { 191 | if (!(dInt[i] == vInt[i])) 192 | error(); 193 | if (!(drInt[1006LL - i] == rInt[i])) 194 | error(); 195 | } 196 | 197 | std::cout << "Correct." << std::endl; 198 | 199 | } 200 | 201 | int main() 202 | { 203 | TestInteger(); 204 | TestMatrix(); 205 | TestBint(); 206 | TestCopyConstructorAndOperatorEqu(); 207 | TestIteratorSequenceAccess(); 208 | TestIteratorRandomAccess(); 209 | TestInsertAndErase(); 210 | TestPopAndPush(); 211 | std::cout << "Congratulations. Your submission has passed all correctness tests. Use valgrind to ensure that there ain't any memory leaks in your deque. Good job! :)" << std::endl; 212 | return 0; 213 | } -------------------------------------------------------------------------------- /deque/data/six/answer.txt: -------------------------------------------------------------------------------- 1 | test start: 2 | test1: push & pop Accept 3 | test2: at & [] & front & back Accept 4 | test3: itetator operation Accept 5 | test4: const_itetator operation Accept 6 | test5: erase & insert Accept 7 | test6: clear & copy & assignment Accept 8 | test7: complexity Accept 9 | -------------------------------------------------------------------------------- /deque/data/six/code.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "deque.hpp" 10 | #include "exceptions.hpp" 11 | 12 | 13 | /***************************/ 14 | bool need_to_check_throw = 1; 15 | bool good_complexity = 1;//if the complexity is N^2, change to 0 16 | int N = good_complexity ? 300000 : 1000; 17 | /***************************/ 18 | 19 | 20 | class T{ 21 | private: 22 | int x; 23 | public: 24 | T(int x):x(x){} 25 | int num()const {return x;} 26 | void change(int y){ 27 | x = y; 28 | } 29 | }; 30 | bool operator == (const T &a, const T &b){ 31 | return a.num() == b.num(); 32 | } 33 | bool operator != (const T &a, const T &b){ 34 | return a.num() != b.num(); 35 | } 36 | sjtu::deque q; 37 | std::deque stl; 38 | sjtu::deque::iterator it_q; 39 | std::deque::iterator it_stl; 40 | sjtu::deque::const_iterator _it_q; 41 | std::deque::const_iterator _it_stl; 42 | bool equal(){ 43 | if(q.size() != stl.size()) return 0; 44 | if(q.empty() != stl.empty()) return 0; 45 | int cnt = 0; 46 | for(it_q = q.begin(), it_stl = stl.begin(); it_q != q.end() || it_stl != stl.end(); it_q++, it_stl++){ 47 | if(*it_q != *it_stl) { 48 | printf("cnt = %d\n",cnt); 49 | return 0; 50 | } 51 | cnt++; 52 | } 53 | return 1; 54 | } 55 | void test1(){ 56 | printf("test1: push & pop "); 57 | for(int i=1;i<=N;i++){ 58 | if(i % 10 <= 3) q.push_back(T(i)), stl.push_back(T(i));else 59 | if(i % 10 <= 7) q.push_front(T(i)), stl.push_front(T(i));else 60 | if(i % 10 <= 8) q.pop_back(), stl.pop_back();else 61 | if(i % 10 <= 9) q.pop_front(), stl.pop_front(); 62 | } 63 | if(!equal()){puts("Wrong Answer");return;} 64 | while (!q.empty()){ 65 | q.pop_back(); 66 | stl.pop_back(); 67 | } 68 | puts("Accept"); 69 | } 70 | void test2(){ 71 | printf("test2: at & [] & front & back "); 72 | int flag = 0; 73 | try{ 74 | int t = q.front().num(); 75 | }catch(...){flag ++;} 76 | 77 | try{ 78 | int t = q.back().num(); 79 | }catch(...){flag ++;} 80 | if(flag != 2 && need_to_check_throw){puts("Wrong Answer");return;} 81 | for(int i=1;i<=N;i++){ 82 | if(i % 10 <= 3) q.push_back(T(i)), stl.push_back(T(i));else 83 | if(i % 10 <= 7) q.push_front(T(i)), stl.push_front(T(i));else 84 | if(i % 10 <= 8) q.pop_back(), stl.pop_back();else 85 | if(i % 10 <= 9) q.pop_front(), stl.pop_front(); 86 | } 87 | flag = 0; 88 | try{ 89 | int t = (q.at(q.size() + 100)).num(); 90 | }catch(...){flag = 1;} 91 | if(flag != 1 && need_to_check_throw){puts("Wrong Answer");return;} 92 | int num = q.size(); 93 | for(int i=0;i<100;i++) 94 | { 95 | int t = rand() % num; 96 | if(q[t] != stl[t] || q.at(t) != stl.at(t)){puts("Wrong Answer");return;} 97 | } 98 | if(q.front() != stl.front() || q.back() != stl.back()){puts("Wrong Answer");return;} 99 | puts("Accept"); 100 | } 101 | void test3(){ 102 | printf("test3: itetator operation "); 103 | int num = q.size(); 104 | for(int i =1 ; i <= 1000; i++) 105 | { 106 | int t1 = rand() % num; 107 | int t2 = rand() % num; 108 | if(*(q.begin() + t1) != *(stl.begin() + t1)){puts("Wrong Answer");return;} 109 | if(t2 && *(q.end() - t2) != *(stl.end() - t2)){puts("Wrong Answer");return;} 110 | if((q.begin() + t1) - (q.begin() + t2) != (t1 - t2)){puts("Wrong Answer");return;} 111 | } 112 | if((q.begin() + num) != q.end()) {puts("Wrong Answer");return;} 113 | if((q.end() - num) != q.begin()) {puts("Wrong Answer");return;} 114 | bool flag=0; 115 | sjtu::deque other; 116 | try{ 117 | int t = q.begin() - other.begin(); 118 | }catch(...){ 119 | flag=1; 120 | } 121 | if(!flag && need_to_check_throw) {puts("Wrong Answer");return;} 122 | it_q = q.begin(); 123 | it_stl = stl.begin(); 124 | for(int i=1;i<=10;i++){ 125 | int t = rand() % (num / 10); 126 | it_q += t; 127 | it_stl += t; 128 | if(*it_q != *it_stl) {puts("Wrong Answer");return;} 129 | if(it_q -> num() != it_stl -> num()) {puts("Wrong Answer");return;} 130 | } 131 | it_q = --q.end(); 132 | it_stl = --stl.end(); 133 | if(*it_q != *it_stl) {puts("Wrong Answer");return;} 134 | for(int i=1;i<10;i++){ 135 | int t = rand() % (num / 10); 136 | it_q -= t; 137 | it_stl -= t; 138 | if(*it_q != *it_stl) {puts("Wrong Answer");return;} 139 | it_q -> change(t);; 140 | it_stl -> change(t); 141 | if(*it_q != *it_stl) {puts("Wrong Answer");return;} 142 | } 143 | if(!equal()) {puts("Wrong Answer");return;} 144 | if (!(q.begin() + 10 == q.begin() +5 + 6 - 1)) {puts("Wrong Answer");return;} 145 | sjtu::deque pp; 146 | if(q.end() == pp.end()){puts("Wrong Answer");return;} 147 | 148 | int t = rand() % (q.size() - 1); 149 | it_q = q.begin() + t; 150 | it_stl = stl.begin() + t; 151 | const sjtu::deque::iterator it_q_const(++it_q); 152 | const std::deque::iterator it_stl_const(++it_stl); 153 | if(*it_q_const != *it_stl_const){puts("Wrong Answer");return;} 154 | if(it_q_const -> num() != it_stl_const -> num()){puts("Wrong Answer");return;} 155 | it_q_const -> change(t); 156 | it_stl_const -> change(t); 157 | if(!equal()){puts("Wrong Answer");return;} 158 | puts("Accept"); 159 | } 160 | 161 | void test4(){ 162 | printf("test4: const_itetator operation "); 163 | const sjtu::deque _q(q); 164 | const std::deque _stl(stl); 165 | int num = _q.size(); 166 | for(int i =1 ; i <= 1000; i++) 167 | { 168 | int t1 = rand() % num; 169 | int t2 = rand() % num; 170 | if(*(_q.cbegin() + t1) != *(_stl.cbegin() + t1)){puts("Wrong Answer");return;} 171 | if(t2 && *(_q.cend() - t2) != *(_stl.cend() - t2)){puts("Wrong Answer");return;} 172 | if((_q.cbegin() + t1) - (_q.cbegin() + t2) != (t1 - t2)){puts("Wrong Answer");return;} 173 | } 174 | if((_q.cbegin() + num) != _q.cend()) {puts("Wrong Answer");return;} 175 | if((_q.cend() - num) != _q.cbegin()) {puts("Wrong Answer");return;} 176 | _it_q = _q.cbegin(); 177 | _it_stl = _stl.cbegin(); 178 | for(int i=1;i<=10;i++){ 179 | int t = rand() % (num / 10); 180 | _it_q += t; 181 | _it_stl += t; 182 | if(*_it_q != *_it_stl) {puts("Wrong Answer");return;} 183 | if(_it_q -> num() != _it_stl -> num()) {puts("Wrong Answer");return;} 184 | } 185 | _it_q = --_q.cend(); 186 | _it_stl = --_stl.cend(); 187 | if(*_it_q != *_it_stl) {puts("Wrong Answer");return;} 188 | if (!(_q.cbegin() + 10 == _q.cbegin() +5 + 6 - 1)) {puts("Wrong Answer");return;} 189 | puts("Accept"); 190 | } 191 | 192 | void test5(){ 193 | printf("test5: erase & insert "); 194 | for(int i=1;i<=sqrt(N) && q.size()>=10;i++) 195 | { 196 | int t = rand() % (q.size() - 3); 197 | it_q = q.begin() + t; 198 | it_stl = stl.begin() + t; 199 | it_q = q.erase(it_q); 200 | it_stl = stl.erase(it_stl); 201 | it_q = q.erase(it_q); 202 | it_stl = stl.erase(it_stl); 203 | it_q -> change(t); 204 | it_stl -> change(t); 205 | } 206 | if(!equal()) {puts("Wrong Answer");return;} 207 | it_q = q.erase(q.end() - 1); 208 | it_stl = stl.erase(stl.end() - 1); 209 | if(it_q != q.end()){puts("Wrong Answer");return;} 210 | for(int i = 1; i <= sqrt(N); i++) 211 | { 212 | int t = rand() % q.size(); 213 | it_q = q.begin() + t; 214 | it_stl = stl.begin() + t; 215 | it_q = q.insert(it_q, T(t)); 216 | it_stl = stl.insert(it_stl, T(t)); 217 | 218 | it_q = q.insert(it_q, T(t + 1)); 219 | it_stl = stl.insert(it_stl, T(t + 1)); 220 | } 221 | it_q = q.begin(); 222 | it_stl = stl.begin(); 223 | for(int i=1;i<=sqrt(N);i++) 224 | { 225 | it_q = q.insert(it_q, T(i)); 226 | it_stl = stl.insert(it_stl, T(i)); 227 | } 228 | it_q = q.insert(q.end(), T(23333)); 229 | it_stl = stl.insert(stl.end(),T(23333)); 230 | if(it_q != q.end() - 1){puts("Wrong Answer");return;} 231 | if(!equal()) {puts("Wrong Answer");return;} 232 | puts("Accept"); 233 | } 234 | void test6(){ 235 | printf("test6: clear & copy & assignment "); 236 | sjtu::deque p(q), r; 237 | r = q; 238 | q.clear(); 239 | if(!q.empty() || q.size() != 0 || q.begin()!=q.end()){puts("Wrong Answer");return;} 240 | q=q=q; 241 | if(!q.empty() || q.size() != 0 || q.begin()!=q.end()){puts("Wrong Answer");return;} 242 | for(int i=1;i<=100;i++) 243 | { 244 | int t = rand() % p.size(); 245 | p.push_back(T(t)); 246 | p.insert(p.begin() + t, T(t)); 247 | r.push_back(T(t)); 248 | r.insert(r.begin() + t, T(t)); 249 | stl.push_back(T(t)); 250 | stl.insert(stl.begin() + t, T(t)); 251 | } 252 | 253 | q = p; 254 | p.clear(); 255 | q=q=q=q; 256 | if(!equal()) {puts("Wrong Answer");return;} 257 | q.clear(); 258 | q = r; 259 | r.clear(); 260 | q=q=q=q; 261 | if(!equal()) {puts("Wrong Answer");return;} 262 | puts("Accept"); 263 | } 264 | void test7(){ 265 | printf("test7: complexity "); 266 | int num = 500000; 267 | static sjtu::deque q; 268 | for(int i = 0; i < num; i++) q.push_front(T(i)); 269 | for(int i = 0; i < num; i++) q.pop_front(); 270 | for(int i = 0; i < num; i++) q.push_back(T(i)); 271 | for(int i = 0; i < num; i++) q.pop_back(); 272 | for(int i = 0; i < num;i++){ 273 | if(i % 10 <= 3) q.push_back(T(i));else 274 | if(i % 10 <= 7) q.push_front(T(i));else 275 | if(i % 10 <= 8) q.pop_back();else 276 | if(i % 10 <= 9) q.pop_front(); 277 | } 278 | int test_num = 5000000; 279 | it_q = q.begin() + q.size() - 10; 280 | for(int i = 0; i < test_num; i++) 281 | { 282 | int tmp = (*it_q).num(); 283 | tmp = it_q -> num(); 284 | if(i % (test_num / 10) == 0) it_q = q.begin() + rand() % q.size(); 285 | } 286 | for(int i = 0; i < N; i++){ 287 | it_q = q.begin() + rand() % q.size(); 288 | q.insert(it_q, T(rand())); 289 | } 290 | for(int i = 0; i < N; i++){ 291 | it_q = q.begin() + rand() % q.size(); 292 | q.erase(it_q); 293 | } 294 | for(int i = 0; i < N; i++){ 295 | int tmp = q[rand() % q.size()].num(); 296 | tmp = q.at(rand() % q.size()).num(); 297 | } 298 | if(good_complexity){ 299 | q.clear(); 300 | for(int i=0;i<4000000;i++) 301 | q.push_back(i); 302 | while (q.size()>2010){ 303 | if(rand() % 2) q.pop_front(); 304 | else q.pop_back(); 305 | } 306 | int tmp; 307 | for(int i=0;i<2000000;i++){ 308 | tmp = q[2000].num(); 309 | tmp = q[1000].num(); 310 | } 311 | } 312 | puts("Accept"); 313 | } 314 | int main(){ 315 | srand(time(NULL)); 316 | puts("test start:"); 317 | test1();//push & pop 318 | test2();//at & [] & front & back 319 | test3();//iterator operation 320 | test4();//const_iterator operation 321 | test5();//erase & insert 322 | test6();//clear & copy & assignment 323 | test7();//complexity 324 | } 325 | -------------------------------------------------------------------------------- /deque/data/three.memcheck/answer.txt: -------------------------------------------------------------------------------- 1 | Deque CheckTool Package Version 1.5 Offical Version 2 | 3 | --------------------------------------------------------------------------- 4 | Test Zone A: Correctness Testing... 5 | Test 1: Push Series -> push_back operation testing... PASSED 6 | Test 2: Push Series -> push_front operation testing... PASSED 7 | Test 3: Pop Series -> pop_back operation testing... PASSED 8 | Test 4: Pop Series -> pop_front operation testing... PASSED 9 | Test 5: Push Series -> insert operation testing... PASSED 10 | Test 6: Pop Series -> erase operation testing... PASSED 11 | Test 7: Visitation Series -> at operation testing... PASSED 12 | Test 8: Visitation Series -> constantly at operation testing... PASSED 13 | Test 9: Visitation Series -> [] operator testing... PASSED 14 | Test 10: Visitation Series -> constantly [] operator testing... PASSED 15 | Test 11: Visitation Series -> front operation testing... PASSED 16 | Test 12: Visitation Series -> back operator testing... PASSED 17 | Test 13: Iterator Series -> +n operator testing... PASSED 18 | Test 14: Iterator Series -> -n operator testing... PASSED 19 | Test 15: Iterator Series -> +=n operator testing... PASSED 20 | Test 16: Iterator Series -> -=n operator testing... PASSED 21 | Test 17: Iterator Serise: Prefix ++ operator testing... PASSED 22 | Test 18: Iterator Series -> Prefix -- operator testing... PASSED 23 | Test 19: Iterator Series -> Suffix ++ operator testing... PASSED 24 | Test 20: Iterator Series -> Suffix -- operator testing... PASSED 25 | Test 21: Iterator Series -> - operator testing... PASSED 26 | Test 22: Iterator Series -> Iterator insert persistence testing... PASSED 27 | Test 23: Iterator Series -> Iterator erase persistence testing... PASSED 28 | Test 24: Robustness Series -> Invalid visitation by []... PASSED 29 | Test 25: Robustness Series -> Invalid visitation by at... PASSED 30 | Test 26: Robustness Series -> Invalid visitation by iterator... PASSED 31 | Test 27: Robustness Series -> Invalid insert operation... PASSED 32 | Test 28: Robustness Series -> Invalid erase operation... PASSED 33 | Test 29: Basic Series -> size function testing... PASSED 34 | Test 30: Basic Series -> empty function testing... PASSED 35 | Test 31: Independence Series -> Copy constructor testing... PASSED 36 | Test 32: Independence Series -> Operator = testing... PASSED 37 | Test 33: Memory Series -> Memory leak testing... PASSED 38 | Test 34: Synthesis Series -> Comprehensive testing... PASSED 39 | --------------------------------------------------------------------------- 40 | -------------------------------------------------------------------------------- /deque/data/three/answer.txt: -------------------------------------------------------------------------------- 1 | Deque CheckTool Package Version 1.5 Offical Version 2 | 3 | --------------------------------------------------------------------------- 4 | Test Zone A: Correctness Testing... 5 | Test 1: Push Series -> push_back operation testing... PASSED 6 | Test 2: Push Series -> push_front operation testing... PASSED 7 | Test 3: Pop Series -> pop_back operation testing... PASSED 8 | Test 4: Pop Series -> pop_front operation testing... PASSED 9 | Test 5: Push Series -> insert operation testing... PASSED 10 | Test 6: Pop Series -> erase operation testing... PASSED 11 | Test 7: Visitation Series -> at operation testing... PASSED 12 | Test 8: Visitation Series -> constantly at operation testing... PASSED 13 | Test 9: Visitation Series -> [] operator testing... PASSED 14 | Test 10: Visitation Series -> constantly [] operator testing... PASSED 15 | Test 11: Visitation Series -> front operation testing... PASSED 16 | Test 12: Visitation Series -> back operator testing... PASSED 17 | Test 13: Iterator Series -> +n operator testing... PASSED 18 | Test 14: Iterator Series -> -n operator testing... PASSED 19 | Test 15: Iterator Series -> +=n operator testing... PASSED 20 | Test 16: Iterator Series -> -=n operator testing... PASSED 21 | Test 17: Iterator Serise: Prefix ++ operator testing... PASSED 22 | Test 18: Iterator Series -> Prefix -- operator testing... PASSED 23 | Test 19: Iterator Series -> Suffix ++ operator testing... PASSED 24 | Test 20: Iterator Series -> Suffix -- operator testing... PASSED 25 | Test 21: Iterator Series -> - operator testing... PASSED 26 | Test 22: Iterator Series -> Iterator insert persistence testing... PASSED 27 | Test 23: Iterator Series -> Iterator erase persistence testing... PASSED 28 | Test 24: Robustness Series -> Invalid visitation by []... PASSED 29 | Test 25: Robustness Series -> Invalid visitation by at... PASSED 30 | Test 26: Robustness Series -> Invalid visitation by iterator... PASSED 31 | Test 27: Robustness Series -> Invalid insert operation... PASSED 32 | Test 28: Robustness Series -> Invalid erase operation... PASSED 33 | Test 29: Basic Series -> size function testing... PASSED 34 | Test 30: Basic Series -> empty function testing... PASSED 35 | Test 31: Independence Series -> Copy constructor testing... PASSED 36 | Test 32: Independence Series -> Operator = testing... PASSED 37 | Test 33: Memory Series -> Memory leak testing... PASSED 38 | Test 34: Synthesis Series -> Comprehensive testing... PASSED 39 | --------------------------------------------------------------------------- 40 | -------------------------------------------------------------------------------- /deque/data/two.memcheck/answer.txt: -------------------------------------------------------------------------------- 1 | Testing push... Passed 2 | Testing pop... Passed 3 | Testing insert... Passed 4 | Testing iterator... Passed 5 | Testing erase... Passed 6 | Testing copy and clear... Passed 7 | Testing memory... Passed 8 | Final test without mercy... Passed 9 | 10 | Congratulations, your deque passed all the tests! 11 | -------------------------------------------------------------------------------- /deque/data/two.memcheck/code.cpp: -------------------------------------------------------------------------------- 1 | // provided by your new friend Mercy. Enjoy! 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "class-integer.hpp" 10 | #include "class-matrix.hpp" 11 | #include "class-bint.hpp" 12 | #include "deque.hpp" 13 | 14 | std::default_random_engine randnum(time(NULL)); 15 | 16 | static const int MAX_N = 15000; 17 | 18 | template 19 | bool isEqual(Ans &ans, Test &test) { 20 | if (ans.size() != test.size()) 21 | return false; 22 | 23 | if (ans.empty()) return true; 24 | 25 | for (int i = 0; i < ans.size(); i++) { 26 | if (randnum() % 2) { 27 | if (ans[i] != test[i]) return false; 28 | } else { 29 | if (ans.at(i) != test.at(i)) return false; 30 | } 31 | } 32 | 33 | if (ans.empty() != test.empty() || ans.front() != test.front() || 34 | ans.back() != test.back()) 35 | return false; 36 | 37 | return true; 38 | } 39 | 40 | template 41 | void randnumFill(Ans &ans, Test &test, int n = 2e5) { 42 | for (int i = 0; i < n; i++) { 43 | int x = randnum(); 44 | if (randnum() % 2) { 45 | ans.push_back(x); 46 | test.push_back(x); 47 | } else { 48 | ans.push_front(x); 49 | test.push_front(x); 50 | } 51 | } 52 | } 53 | 54 | bool pushTest() { 55 | std::deque ans; 56 | sjtu::deque deq; 57 | 58 | for (int i = 0; i < MAX_N; i++) { 59 | int x = randnum(); 60 | switch (randnum() % 2) { 61 | case 0: deq.push_front(x); ans.push_front(x); 62 | break; 63 | case 1: deq.push_back(x); ans.push_back(x); 64 | break; 65 | } 66 | } 67 | 68 | return isEqual(ans, deq); 69 | } 70 | 71 | bool popTest() { 72 | std::deque ans; 73 | sjtu::deque deq; 74 | 75 | randnumFill(ans, deq); 76 | 77 | for (int i = 0; i < MAX_N / 2; i++) { 78 | switch (randnum() % 2) { 79 | case 0: deq.pop_front(); ans.pop_front(); 80 | break; 81 | case 1: deq.pop_back(); ans.pop_back(); 82 | break; 83 | } 84 | } 85 | 86 | return isEqual(ans, deq); 87 | } 88 | 89 | bool insertTest() { 90 | std::deque ans, ans2, ans3; 91 | sjtu::deque deq, deq2, deq3; 92 | 93 | for (int i = 0; i < 100; i++) { 94 | int x = randnum(); 95 | int pos = (ans.size() == 0 ? 0 : randnum() % ans.size()); 96 | 97 | switch (randnum() % 2) { 98 | case 0: deq.insert(deq.begin() + pos, x); 99 | ans.insert(ans.begin() + pos, x); 100 | break; 101 | case 1: deq.insert(deq.end() - pos, x); 102 | ans.insert(ans.end() - pos, x); 103 | break; 104 | } 105 | } 106 | 107 | ans2.insert(ans2.begin(), 0x5d); ans3.insert(ans3.end(), 93); 108 | deq2.insert(deq2.begin(), 0x5d); deq3.insert(deq3.end(), 93); 109 | 110 | if (!isEqual(ans2, deq2) || !isEqual(ans3, deq3)) 111 | return false; 112 | 113 | return isEqual(ans, deq); 114 | } 115 | bool iteratorTest() { 116 | std::deque ans; 117 | sjtu::deque deq; 118 | 119 | randnumFill(ans, deq); 120 | 121 | auto ansIter = ans.begin() + ans.size() / 2; 122 | auto myIter = deq.begin() + deq.size() / 2; 123 | 124 | // iter++, iter-- 125 | for (int i = 0; i < MAX_N; i++) { 126 | switch(randnum() % 2) { 127 | case 0: ansIter++; myIter++; 128 | break; 129 | case 1: ansIter--; myIter--; 130 | break; 131 | } 132 | 133 | if (*ansIter != *myIter) 134 | return false; 135 | } 136 | 137 | // iter += n, iter -= n 138 | for (int i = 0; i < MAX_N; i++) { 139 | std::deque::iterator ansIter[] = { ans.begin(), ans.end() }; 140 | sjtu::deque::iterator myIter[] = { deq.begin(), deq.end() }; 141 | 142 | int offset = randnum() % (ans.size() / 3) + 1; 143 | 144 | ansIter[0] += offset; ansIter[1] -= offset; 145 | myIter[0] += offset; myIter[1] -= offset; 146 | 147 | for (int j = 0; j < 2; j++) 148 | if (*ansIter[j] != *myIter[j]) 149 | return false; 150 | 151 | if (ansIter[1] - ansIter[0] != myIter[1] - myIter[0]) 152 | return false; 153 | } 154 | 155 | // iter +=n, iter -= n, iter += -n, iter -= -n 156 | int index = ans.size() / 2; 157 | ansIter = ans.begin() + index; 158 | myIter = deq.begin() + index; 159 | for (int i = 0; i < MAX_N * 2; i++) { 160 | int offset = randnum() % (ans.size() / 2); 161 | switch (randnum() % 4) { 162 | case 0: // iter += n 163 | if (index + offset < ans.size()) { 164 | index += offset; 165 | ansIter += offset; myIter += offset; 166 | } 167 | break; 168 | case 1: // iter -= n 169 | if (index - offset >= 0) { 170 | index -= offset; 171 | ansIter -= offset; myIter -= offset; 172 | } 173 | break; 174 | case 2: // iter += -n 175 | if (index - offset >= 0) { 176 | index += -offset; 177 | ansIter += -offset; myIter += -offset; 178 | } 179 | break; 180 | case 3: // iter -= -n 181 | if (index + offset < ans.size()) { 182 | index -= -offset; 183 | ansIter -= -offset; myIter -= -offset; 184 | } 185 | break; 186 | } 187 | if (*ansIter != *myIter) 188 | return false; 189 | *ansIter = *myIter = randnum(); 190 | } 191 | 192 | // traverse 193 | ansIter = ans.begin(); myIter = deq.begin(); 194 | while (ansIter != ans.end()) { 195 | if (*ansIter++ != *myIter++) 196 | return false; 197 | } 198 | // reversal traverse 199 | ansIter = ans.end() - 1; myIter = deq.end() - 1; 200 | while (ansIter != ans.begin()) { 201 | if (*ansIter-- != *myIter--) 202 | return false; 203 | } 204 | 205 | return *ansIter == *myIter; 206 | } 207 | 208 | bool eraseTest() { 209 | std::deque ans; 210 | sjtu::deque deq; 211 | 212 | randnumFill(ans, deq); 213 | 214 | for (int i = 0; i < 100; i++) { 215 | int pos = randnum() % ans.size(); 216 | 217 | switch (randnum() % 2) { 218 | case 0: deq.erase(deq.begin() + pos); 219 | ans.erase(ans.begin() + pos); 220 | break; 221 | case 1: deq.erase(deq.end() - 1 - pos); 222 | ans.erase(ans.end() - 1 - pos); 223 | break; 224 | } 225 | } 226 | 227 | return isEqual(ans, deq); 228 | } 229 | 230 | int ansCounter = 0, myCounter = 0, noUseCounter = 0; 231 | // you should construct and deconstruct this class correctly 232 | class DynamicType { 233 | public: 234 | int *pct; 235 | double *data; 236 | DynamicType (int *p) : pct(p) , data(new double[2]) { 237 | (*pct)++; 238 | } 239 | DynamicType (const DynamicType &other) : pct(other.pct), data(new double[2]) { 240 | (*pct)++; 241 | } 242 | DynamicType &operator =(const DynamicType &other) { 243 | if (this == &other) return *this; 244 | (*pct)--; 245 | pct = other.pct; 246 | (*pct)++; 247 | delete [] data; 248 | data = new double[2]; 249 | return *this; 250 | } 251 | ~DynamicType() { 252 | delete [] data; 253 | (*pct)--; 254 | } 255 | bool operator != (const DynamicType &rhs) const { return false; } 256 | }; 257 | 258 | bool copyAndClearTest() { 259 | // you should call the constructor and deconstructor correctly 260 | { 261 | std::deque ans; 262 | sjtu::deque deq, deq2 = deq, deq3(deq2); 263 | 264 | // empty copy and clear 265 | deq.clear(); deq2.clear(); deq3.clear(); 266 | deq = deq = deq; deq2 = deq3; deq3 = deq = deq3 = deq2; 267 | 268 | for (int i = 0; i < MAX_N; i++) { 269 | ans.push_back(DynamicType(&ansCounter)); 270 | deq.push_back(DynamicType(&myCounter)); 271 | } 272 | if (myCounter != ansCounter) return false; 273 | 274 | deq = deq = deq = deq; 275 | if (myCounter != ansCounter) return false; 276 | 277 | deq = deq2 = deq2 = deq; 278 | if (myCounter != 2 * ansCounter) return false; 279 | if (!isEqual(deq, deq2)) return false; 280 | 281 | deq2 = deq = deq = deq2 = deq2 = deq3; 282 | if (myCounter != 0) return false; 283 | if (!isEqual(deq, deq2)) return false; 284 | 285 | for (int i = 0; i < MAX_N; i++) 286 | deq.push_back(DynamicType(&myCounter)); 287 | 288 | deq2 = deq3 = deq; 289 | if (myCounter != 3 * ansCounter) return false; 290 | 291 | deq.clear(); 292 | sjtu::deque deq4(deq), deq5(deq2); 293 | if (myCounter != 3 * ansCounter) return false; 294 | if (isEqual(deq, deq2)) return false; 295 | } 296 | 297 | return myCounter == ansCounter; 298 | } 299 | 300 | bool memoryTest() { 301 | // you should call the constructor and deconstructor correctly 302 | std::deque ans; 303 | sjtu::deque deq; 304 | 305 | for (int i = 0; i < MAX_N; i++) { 306 | ans.push_back(DynamicType(&ansCounter)); 307 | deq.push_back(DynamicType(&myCounter)); 308 | } 309 | 310 | for (int i = 0; i < MAX_N / 10; i++) { 311 | int index = randnum() % ans.size(); 312 | switch(randnum() % 6) { 313 | case 0: ans.push_back(DynamicType(&ansCounter)); 314 | deq.push_back(DynamicType(&myCounter)); 315 | break; 316 | case 1: ans.push_front(DynamicType(&ansCounter)); 317 | deq.push_front(DynamicType(&myCounter)); 318 | break; 319 | case 2: ans.pop_back(); deq.pop_back(); 320 | break; 321 | case 3: ans.pop_front(); deq.pop_front(); 322 | break; 323 | case 4: ans.insert(ans.begin() + index, DynamicType(&ansCounter)); 324 | deq.insert(deq.begin() + index, DynamicType(&myCounter)); 325 | break; 326 | case 5: ans.erase(ans.begin() + index); 327 | deq.erase(deq.begin() + index); 328 | break; 329 | default : break; 330 | } 331 | 332 | if (ansCounter != myCounter) 333 | return false; 334 | } 335 | 336 | return isEqual(ans, deq); 337 | } 338 | 339 | bool exceptionTest() { 340 | sjtu::deque deq, deq2; 341 | int ct = 0; 342 | 343 | try { deq.front(); } catch (...) { ct++; } 344 | try { deq.back(); } catch (...) { ct++; } 345 | try { deq[0]; } catch (...) { ct++; } 346 | 347 | deq.push_back(1); deq.push_back(2); 348 | deq2.push_back(1); deq2.push_back(2); 349 | 350 | try { deq.end() - deq.begin(); } catch (...) { ct--; } 351 | try { deq2.end() - deq.begin(); } catch (...) { ct++; } 352 | 353 | try { deq2[-1]; } catch (...) { ct++; } 354 | try { deq2[2]; } catch (...) { ct++; } 355 | try { deq2.at(-1); } catch (...) { ct++; } 356 | try { deq2.at(1); } catch (...) { ct--; } 357 | 358 | return ct == 7; 359 | } 360 | 361 | template 362 | bool dfs(int deep, std::deque ans, sjtu::deque deq) { 363 | if (deep == 0) 364 | return true; 365 | 366 | int x = randnum(); 367 | switch (randnum() % 5) { 368 | case 0: ans.insert(++ans.begin(), x); 369 | deq.insert(++deq.begin(), x); 370 | break; 371 | case 1: ans.erase(--ans.end()); 372 | deq.erase(--deq.end()); 373 | break; 374 | case 2: *(ans.begin() - (-5)) = x; 375 | *(deq.begin() - (-5)) = x; 376 | break; 377 | case 3: *(ans.end() + (-5)) = x; 378 | *(deq.end() + (-5)) = x; 379 | break; 380 | } 381 | 382 | if (isEqual(ans, deq) && ansCounter == myCounter) 383 | return dfs(deep / 2, ans, deq); 384 | else 385 | return false; 386 | } 387 | 388 | bool dfs2(int deep, std::deque ans, sjtu::deque deq) { 389 | if (deep == 0) 390 | return true; 391 | 392 | DynamicType tmp(&noUseCounter), tmp2(&noUseCounter); 393 | switch (randnum() % 6) { 394 | case 0: ans.insert(++ans.begin(), DynamicType(&ansCounter)); 395 | deq.insert(++deq.begin(), DynamicType(&myCounter)); 396 | break; 397 | case 1: ans.erase(--ans.end()); 398 | deq.erase(--deq.end()); 399 | break; 400 | case 2: *(ans.begin() - (-5)) = DynamicType(&ansCounter); 401 | *(deq.begin() - (-5)) = DynamicType(&myCounter); 402 | break; 403 | case 3: *(ans.end() + (-5)) = DynamicType(&ansCounter); 404 | *(deq.end() + (-5)) = DynamicType(&myCounter); 405 | break; 406 | case 4: { 407 | int a = randnum() % ans.size(), b = randnum() % ans.size(); 408 | tmp = deq[a]; deq[a] = deq[b]; deq[b] = tmp; 409 | tmp = ans[a]; ans[a] = ans[b]; ans[b] = tmp; 410 | tmp = tmp2; 411 | } 412 | break; 413 | case 5: (*ans.begin()->pct)++; 414 | (*deq.begin()->pct)++; 415 | break; 416 | } 417 | 418 | if (isEqual(ans, deq) && ansCounter == myCounter) 419 | return dfs2(deep / 2, ans, deq); 420 | else 421 | return false; 422 | } 423 | 424 | bool nomercyTest() { 425 | // it is an easy test with bluffing name... 426 | ansCounter = myCounter = 0; 427 | { 428 | std::deque ans; 429 | sjtu::deque deq; 430 | randnumFill(ans, deq, 10000); 431 | if (!dfs(19960904, ans, deq)) 432 | return false; 433 | 434 | std::deque ans2; 435 | sjtu::deque deq2; 436 | for (int i = 0; i < 10000; i++) { 437 | ans2.push_front(DynamicType(&ansCounter)); 438 | deq2.push_front(DynamicType(&myCounter)); 439 | } 440 | if (!dfs2(19960904, ans2, deq2)) 441 | return false; 442 | } 443 | return ansCounter == myCounter; 444 | } 445 | 446 | int main() { 447 | bool (*testFunc[])()= { 448 | pushTest, popTest, insertTest, iteratorTest, 449 | eraseTest, copyAndClearTest, memoryTest, 450 | nomercyTest, 451 | }; 452 | 453 | const char *testMessage[] = { 454 | "Testing push...", "Testing pop...", "Testing insert...", "Testing iterator...", 455 | "Testing erase...", "Testing copy and clear...", "Testing memory...", 456 | "Final test without mercy...", 457 | }; 458 | 459 | bool error = false; 460 | for (int i = 0; i < sizeof(testFunc) / sizeof(testFunc[0]); i++) { 461 | printf("%-40s", testMessage[i]); 462 | if (testFunc[i]()) 463 | printf("Passed\n"); 464 | else { 465 | error = true; 466 | printf("Failed !!!\n"); 467 | } 468 | } 469 | 470 | if (error) 471 | printf("\nUnfortunately, you failed in this test\n\a"); 472 | else 473 | printf("\nCongratulations, your deque passed all the tests!\n"); 474 | 475 | return 0; 476 | } 477 | 478 | -------------------------------------------------------------------------------- /deque/data/two/answer.txt: -------------------------------------------------------------------------------- 1 | Testing push... Passed 2 | Testing pop... Passed 3 | Testing insert... Passed 4 | Testing iterator... Passed 5 | Testing erase... Passed 6 | Testing copy and clear... Passed 7 | Testing memory... Passed 8 | Final test without mercy... Passed 9 | 10 | Congratulations, your deque passed all the tests! 11 | -------------------------------------------------------------------------------- /deque/data/two/code.cpp: -------------------------------------------------------------------------------- 1 | // provided by your new friend Mercy. Enjoy! 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "class-integer.hpp" 10 | #include "class-matrix.hpp" 11 | #include "class-bint.hpp" 12 | #include "deque.hpp" 13 | 14 | std::default_random_engine randnum(time(NULL)); 15 | 16 | static const int MAX_N = 15000; 17 | 18 | template 19 | bool isEqual(Ans &ans, Test &test) { 20 | if (ans.size() != test.size()) 21 | return false; 22 | 23 | if (ans.empty()) return true; 24 | 25 | for (int i = 0; i < ans.size(); i++) { 26 | if (randnum() % 2) { 27 | if (ans[i] != test[i]) return false; 28 | } else { 29 | if (ans.at(i) != test.at(i)) return false; 30 | } 31 | } 32 | 33 | if (ans.empty() != test.empty() || ans.front() != test.front() || 34 | ans.back() != test.back()) 35 | return false; 36 | 37 | return true; 38 | } 39 | 40 | template 41 | void randnumFill(Ans &ans, Test &test, int n = 2e5) { 42 | for (int i = 0; i < n; i++) { 43 | int x = randnum(); 44 | if (randnum() % 2) { 45 | ans.push_back(x); 46 | test.push_back(x); 47 | } else { 48 | ans.push_front(x); 49 | test.push_front(x); 50 | } 51 | } 52 | } 53 | 54 | bool pushTest() { 55 | std::deque ans; 56 | sjtu::deque deq; 57 | 58 | for (int i = 0; i < MAX_N; i++) { 59 | int x = randnum(); 60 | switch (randnum() % 2) { 61 | case 0: deq.push_front(x); ans.push_front(x); 62 | break; 63 | case 1: deq.push_back(x); ans.push_back(x); 64 | break; 65 | } 66 | } 67 | 68 | return isEqual(ans, deq); 69 | } 70 | 71 | bool popTest() { 72 | std::deque ans; 73 | sjtu::deque deq; 74 | 75 | randnumFill(ans, deq); 76 | 77 | for (int i = 0; i < MAX_N / 2; i++) { 78 | switch (randnum() % 2) { 79 | case 0: deq.pop_front(); ans.pop_front(); 80 | break; 81 | case 1: deq.pop_back(); ans.pop_back(); 82 | break; 83 | } 84 | } 85 | 86 | return isEqual(ans, deq); 87 | } 88 | 89 | bool insertTest() { 90 | std::deque ans, ans2, ans3; 91 | sjtu::deque deq, deq2, deq3; 92 | 93 | for (int i = 0; i < 100; i++) { 94 | int x = randnum(); 95 | int pos = (ans.size() == 0 ? 0 : randnum() % ans.size()); 96 | 97 | switch (randnum() % 2) { 98 | case 0: deq.insert(deq.begin() + pos, x); 99 | ans.insert(ans.begin() + pos, x); 100 | break; 101 | case 1: deq.insert(deq.end() - pos, x); 102 | ans.insert(ans.end() - pos, x); 103 | break; 104 | } 105 | } 106 | 107 | ans2.insert(ans2.begin(), 0x5d); ans3.insert(ans3.end(), 93); 108 | deq2.insert(deq2.begin(), 0x5d); deq3.insert(deq3.end(), 93); 109 | 110 | if (!isEqual(ans2, deq2) || !isEqual(ans3, deq3)) 111 | return false; 112 | 113 | return isEqual(ans, deq); 114 | } 115 | bool iteratorTest() { 116 | std::deque ans; 117 | sjtu::deque deq; 118 | 119 | randnumFill(ans, deq); 120 | 121 | auto ansIter = ans.begin() + ans.size() / 2; 122 | auto myIter = deq.begin() + deq.size() / 2; 123 | 124 | // iter++, iter-- 125 | for (int i = 0; i < MAX_N; i++) { 126 | switch(randnum() % 2) { 127 | case 0: ansIter++; myIter++; 128 | break; 129 | case 1: ansIter--; myIter--; 130 | break; 131 | } 132 | 133 | if (*ansIter != *myIter) 134 | return false; 135 | } 136 | 137 | // iter += n, iter -= n 138 | for (int i = 0; i < MAX_N; i++) { 139 | std::deque::iterator ansIter[] = { ans.begin(), ans.end() }; 140 | sjtu::deque::iterator myIter[] = { deq.begin(), deq.end() }; 141 | 142 | int offset = randnum() % (ans.size() / 3) + 1; 143 | 144 | ansIter[0] += offset; ansIter[1] -= offset; 145 | myIter[0] += offset; myIter[1] -= offset; 146 | 147 | for (int j = 0; j < 2; j++) 148 | if (*ansIter[j] != *myIter[j]) 149 | return false; 150 | 151 | if (ansIter[1] - ansIter[0] != myIter[1] - myIter[0]) 152 | return false; 153 | } 154 | 155 | // iter +=n, iter -= n, iter += -n, iter -= -n 156 | int index = ans.size() / 2; 157 | ansIter = ans.begin() + index; 158 | myIter = deq.begin() + index; 159 | for (int i = 0; i < MAX_N * 2; i++) { 160 | int offset = randnum() % (ans.size() / 2); 161 | switch (randnum() % 4) { 162 | case 0: // iter += n 163 | if (index + offset < ans.size()) { 164 | index += offset; 165 | ansIter += offset; myIter += offset; 166 | } 167 | break; 168 | case 1: // iter -= n 169 | if (index - offset >= 0) { 170 | index -= offset; 171 | ansIter -= offset; myIter -= offset; 172 | } 173 | break; 174 | case 2: // iter += -n 175 | if (index - offset >= 0) { 176 | index += -offset; 177 | ansIter += -offset; myIter += -offset; 178 | } 179 | break; 180 | case 3: // iter -= -n 181 | if (index + offset < ans.size()) { 182 | index -= -offset; 183 | ansIter -= -offset; myIter -= -offset; 184 | } 185 | break; 186 | } 187 | if (*ansIter != *myIter) 188 | return false; 189 | *ansIter = *myIter = randnum(); 190 | } 191 | 192 | // traverse 193 | ansIter = ans.begin(); myIter = deq.begin(); 194 | while (ansIter != ans.end()) { 195 | if (*ansIter++ != *myIter++) 196 | return false; 197 | } 198 | // reversal traverse 199 | ansIter = ans.end() - 1; myIter = deq.end() - 1; 200 | while (ansIter != ans.begin()) { 201 | if (*ansIter-- != *myIter--) 202 | return false; 203 | } 204 | 205 | return *ansIter == *myIter; 206 | } 207 | 208 | bool eraseTest() { 209 | std::deque ans; 210 | sjtu::deque deq; 211 | 212 | randnumFill(ans, deq); 213 | 214 | for (int i = 0; i < 100; i++) { 215 | int pos = randnum() % ans.size(); 216 | 217 | switch (randnum() % 2) { 218 | case 0: deq.erase(deq.begin() + pos); 219 | ans.erase(ans.begin() + pos); 220 | break; 221 | case 1: deq.erase(deq.end() - 1 - pos); 222 | ans.erase(ans.end() - 1 - pos); 223 | break; 224 | } 225 | } 226 | 227 | return isEqual(ans, deq); 228 | } 229 | 230 | int ansCounter = 0, myCounter = 0, noUseCounter = 0; 231 | // you should construct and deconstruct this class correctly 232 | class DynamicType { 233 | public: 234 | int *pct; 235 | double *data; 236 | DynamicType (int *p) : pct(p) , data(new double[2]) { 237 | (*pct)++; 238 | } 239 | DynamicType (const DynamicType &other) : pct(other.pct), data(new double[2]) { 240 | (*pct)++; 241 | } 242 | DynamicType &operator =(const DynamicType &other) { 243 | if (this == &other) return *this; 244 | (*pct)--; 245 | pct = other.pct; 246 | (*pct)++; 247 | delete [] data; 248 | data = new double[2]; 249 | return *this; 250 | } 251 | ~DynamicType() { 252 | delete [] data; 253 | (*pct)--; 254 | } 255 | bool operator != (const DynamicType &rhs) const { return false; } 256 | }; 257 | 258 | bool copyAndClearTest() { 259 | // you should call the constructor and deconstructor correctly 260 | { 261 | std::deque ans; 262 | sjtu::deque deq, deq2 = deq, deq3(deq2); 263 | 264 | // empty copy and clear 265 | deq.clear(); deq2.clear(); deq3.clear(); 266 | deq = deq = deq; deq2 = deq3; deq3 = deq = deq3 = deq2; 267 | 268 | for (int i = 0; i < MAX_N; i++) { 269 | ans.push_back(DynamicType(&ansCounter)); 270 | deq.push_back(DynamicType(&myCounter)); 271 | } 272 | if (myCounter != ansCounter) return false; 273 | 274 | deq = deq = deq = deq; 275 | if (myCounter != ansCounter) return false; 276 | 277 | deq = deq2 = deq2 = deq; 278 | if (myCounter != 2 * ansCounter) return false; 279 | if (!isEqual(deq, deq2)) return false; 280 | 281 | deq2 = deq = deq = deq2 = deq2 = deq3; 282 | if (myCounter != 0) return false; 283 | if (!isEqual(deq, deq2)) return false; 284 | 285 | for (int i = 0; i < MAX_N; i++) 286 | deq.push_back(DynamicType(&myCounter)); 287 | 288 | deq2 = deq3 = deq; 289 | if (myCounter != 3 * ansCounter) return false; 290 | 291 | deq.clear(); 292 | sjtu::deque deq4(deq), deq5(deq2); 293 | if (myCounter != 3 * ansCounter) return false; 294 | if (isEqual(deq, deq2)) return false; 295 | } 296 | 297 | return myCounter == ansCounter; 298 | } 299 | 300 | bool memoryTest() { 301 | // you should call the constructor and deconstructor correctly 302 | std::deque ans; 303 | sjtu::deque deq; 304 | 305 | for (int i = 0; i < MAX_N; i++) { 306 | ans.push_back(DynamicType(&ansCounter)); 307 | deq.push_back(DynamicType(&myCounter)); 308 | } 309 | 310 | for (int i = 0; i < MAX_N / 10; i++) { 311 | int index = randnum() % ans.size(); 312 | switch(randnum() % 6) { 313 | case 0: ans.push_back(DynamicType(&ansCounter)); 314 | deq.push_back(DynamicType(&myCounter)); 315 | break; 316 | case 1: ans.push_front(DynamicType(&ansCounter)); 317 | deq.push_front(DynamicType(&myCounter)); 318 | break; 319 | case 2: ans.pop_back(); deq.pop_back(); 320 | break; 321 | case 3: ans.pop_front(); deq.pop_front(); 322 | break; 323 | case 4: ans.insert(ans.begin() + index, DynamicType(&ansCounter)); 324 | deq.insert(deq.begin() + index, DynamicType(&myCounter)); 325 | break; 326 | case 5: ans.erase(ans.begin() + index); 327 | deq.erase(deq.begin() + index); 328 | break; 329 | default : break; 330 | } 331 | 332 | if (ansCounter != myCounter) 333 | return false; 334 | } 335 | 336 | return isEqual(ans, deq); 337 | } 338 | 339 | bool exceptionTest() { 340 | sjtu::deque deq, deq2; 341 | int ct = 0; 342 | 343 | try { deq.front(); } catch (...) { ct++; } 344 | try { deq.back(); } catch (...) { ct++; } 345 | try { deq[0]; } catch (...) { ct++; } 346 | 347 | deq.push_back(1); deq.push_back(2); 348 | deq2.push_back(1); deq2.push_back(2); 349 | 350 | try { deq.end() - deq.begin(); } catch (...) { ct--; } 351 | try { deq2.end() - deq.begin(); } catch (...) { ct++; } 352 | 353 | try { deq2[-1]; } catch (...) { ct++; } 354 | try { deq2[2]; } catch (...) { ct++; } 355 | try { deq2.at(-1); } catch (...) { ct++; } 356 | try { deq2.at(1); } catch (...) { ct--; } 357 | 358 | return ct == 7; 359 | } 360 | 361 | template 362 | bool dfs(int deep, std::deque ans, sjtu::deque deq) { 363 | if (deep == 0) 364 | return true; 365 | 366 | int x = randnum(); 367 | switch (randnum() % 5) { 368 | case 0: ans.insert(++ans.begin(), x); 369 | deq.insert(++deq.begin(), x); 370 | break; 371 | case 1: ans.erase(--ans.end()); 372 | deq.erase(--deq.end()); 373 | break; 374 | case 2: *(ans.begin() - (-5)) = x; 375 | *(deq.begin() - (-5)) = x; 376 | break; 377 | case 3: *(ans.end() + (-5)) = x; 378 | *(deq.end() + (-5)) = x; 379 | break; 380 | } 381 | 382 | if (isEqual(ans, deq) && ansCounter == myCounter) 383 | return dfs(deep / 2, ans, deq); 384 | else 385 | return false; 386 | } 387 | 388 | bool dfs2(int deep, std::deque ans, sjtu::deque deq) { 389 | if (deep == 0) 390 | return true; 391 | 392 | DynamicType tmp(&noUseCounter), tmp2(&noUseCounter); 393 | switch (randnum() % 6) { 394 | case 0: ans.insert(++ans.begin(), DynamicType(&ansCounter)); 395 | deq.insert(++deq.begin(), DynamicType(&myCounter)); 396 | break; 397 | case 1: ans.erase(--ans.end()); 398 | deq.erase(--deq.end()); 399 | break; 400 | case 2: *(ans.begin() - (-5)) = DynamicType(&ansCounter); 401 | *(deq.begin() - (-5)) = DynamicType(&myCounter); 402 | break; 403 | case 3: *(ans.end() + (-5)) = DynamicType(&ansCounter); 404 | *(deq.end() + (-5)) = DynamicType(&myCounter); 405 | break; 406 | case 4: { 407 | int a = randnum() % ans.size(), b = randnum() % ans.size(); 408 | tmp = deq[a]; deq[a] = deq[b]; deq[b] = tmp; 409 | tmp = ans[a]; ans[a] = ans[b]; ans[b] = tmp; 410 | tmp = tmp2; 411 | } 412 | break; 413 | case 5: (*ans.begin()->pct)++; 414 | (*deq.begin()->pct)++; 415 | break; 416 | } 417 | 418 | if (isEqual(ans, deq) && ansCounter == myCounter) 419 | return dfs2(deep / 2, ans, deq); 420 | else 421 | return false; 422 | } 423 | 424 | bool nomercyTest() { 425 | // it is an easy test with bluffing name... 426 | ansCounter = myCounter = 0; 427 | { 428 | std::deque ans; 429 | sjtu::deque deq; 430 | randnumFill(ans, deq, 100000); 431 | if (!dfs(19960904, ans, deq)) 432 | return false; 433 | 434 | std::deque ans2; 435 | sjtu::deque deq2; 436 | for (int i = 0; i < 10000; i++) { 437 | ans2.push_front(DynamicType(&ansCounter)); 438 | deq2.push_front(DynamicType(&myCounter)); 439 | } 440 | if (!dfs2(19960904, ans2, deq2)) 441 | return false; 442 | } 443 | return ansCounter == myCounter; 444 | } 445 | 446 | int main() { 447 | bool (*testFunc[])()= { 448 | pushTest, popTest, insertTest, iteratorTest, 449 | eraseTest, copyAndClearTest, memoryTest, 450 | nomercyTest, 451 | }; 452 | 453 | const char *testMessage[] = { 454 | "Testing push...", "Testing pop...", "Testing insert...", "Testing iterator...", 455 | "Testing erase...", "Testing copy and clear...", "Testing memory...", 456 | "Final test without mercy...", 457 | }; 458 | 459 | bool error = false; 460 | for (int i = 0; i < sizeof(testFunc) / sizeof(testFunc[0]); i++) { 461 | printf("%-40s", testMessage[i]); 462 | if (testFunc[i]()) 463 | printf("Passed\n"); 464 | else { 465 | error = true; 466 | printf("Failed !!!\n"); 467 | } 468 | } 469 | 470 | if (error) 471 | printf("\nUnfortunately, you failed in this test\n\a"); 472 | else 473 | printf("\nCongratulations, your deque passed all the tests!\n"); 474 | 475 | return 0; 476 | } 477 | 478 | -------------------------------------------------------------------------------- /deque/deque.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SJTU_DEQUE_HPP 2 | #define SJTU_DEQUE_HPP 3 | 4 | #include "exceptions.hpp" 5 | 6 | #include 7 | 8 | namespace sjtu { 9 | 10 | template 11 | class deque { 12 | public: 13 | class const_iterator; 14 | class iterator { 15 | private: 16 | /** 17 | * TODO add data members 18 | * just add whatever you want. 19 | */ 20 | public: 21 | /** 22 | * return a new iterator which pointer n-next elements 23 | * even if there are not enough elements, the behaviour is **undefined**. 24 | * as well as operator- 25 | */ 26 | iterator operator+(const int &n) const { 27 | //TODO 28 | } 29 | iterator operator-(const int &n) const { 30 | //TODO 31 | } 32 | // return th distance between two iterator, 33 | // if these two iterators points to different vectors, throw invaild_iterator. 34 | int operator-(const iterator &rhs) const { 35 | //TODO 36 | } 37 | iterator operator+=(const int &n) { 38 | //TODO 39 | } 40 | iterator operator-=(const int &n) { 41 | //TODO 42 | } 43 | /** 44 | * TODO iter++ 45 | */ 46 | iterator operator++(int) {} 47 | /** 48 | * TODO ++iter 49 | */ 50 | iterator& operator++() {} 51 | /** 52 | * TODO iter-- 53 | */ 54 | iterator operator--(int) {} 55 | /** 56 | * TODO --iter 57 | */ 58 | iterator& operator--() {} 59 | /** 60 | * TODO *it 61 | */ 62 | T& operator*() const {} 63 | /** 64 | * TODO it->field 65 | */ 66 | T* operator->() const noexcept {} 67 | /** 68 | * a operator to check whether two iterators are same (pointing to the same memory). 69 | */ 70 | bool operator==(const iterator &rhs) const {} 71 | bool operator==(const const_iterator &rhs) const {} 72 | /** 73 | * some other operator for iterator. 74 | */ 75 | bool operator!=(const iterator &rhs) const {} 76 | bool operator!=(const const_iterator &rhs) const {} 77 | }; 78 | class const_iterator { 79 | // it should has similar member method as iterator. 80 | // and it should be able to construct from an iterator. 81 | private: 82 | // data members. 83 | public: 84 | const_iterator() { 85 | // TODO 86 | } 87 | const_iterator(const const_iterator &other) { 88 | // TODO 89 | } 90 | const_iterator(const iterator &other) { 91 | // TODO 92 | } 93 | // And other methods in iterator. 94 | // And other methods in iterator. 95 | // And other methods in iterator. 96 | }; 97 | /** 98 | * TODO Constructors 99 | */ 100 | deque() {} 101 | deque(const deque &other) {} 102 | /** 103 | * TODO Deconstructor 104 | */ 105 | ~deque() {} 106 | /** 107 | * TODO assignment operator 108 | */ 109 | deque &operator=(const deque &other) {} 110 | /** 111 | * access specified element with bounds checking 112 | * throw index_out_of_bound if out of bound. 113 | */ 114 | T & at(const size_t &pos) {} 115 | const T & at(const size_t &pos) const {} 116 | T & operator[](const size_t &pos) {} 117 | const T & operator[](const size_t &pos) const {} 118 | /** 119 | * access the first element 120 | * throw container_is_empty when the container is empty. 121 | */ 122 | const T & front() const {} 123 | /** 124 | * access the last element 125 | * throw container_is_empty when the container is empty. 126 | */ 127 | const T & back() const {} 128 | /** 129 | * returns an iterator to the beginning. 130 | */ 131 | iterator begin() {} 132 | const_iterator cbegin() const {} 133 | /** 134 | * returns an iterator to the end. 135 | */ 136 | iterator end() {} 137 | const_iterator cend() const {} 138 | /** 139 | * checks whether the container is empty. 140 | */ 141 | bool empty() const {} 142 | /** 143 | * returns the number of elements 144 | */ 145 | size_t size() const {} 146 | /** 147 | * clears the contents 148 | */ 149 | void clear() {} 150 | /** 151 | * inserts elements at the specified locat on in the container. 152 | * inserts value before pos 153 | * returns an iterator pointing to the inserted value 154 | * throw if the iterator is invalid or it point to a wrong place. 155 | */ 156 | iterator insert(iterator pos, const T &value) {} 157 | /** 158 | * removes specified element at pos. 159 | * removes the element at pos. 160 | * returns an iterator pointing to the following element, if pos pointing to the last element, end() will be returned. 161 | * throw if the container is empty, the iterator is invalid or it points to a wrong place. 162 | */ 163 | iterator erase(iterator pos) {} 164 | /** 165 | * adds an element to the end 166 | */ 167 | void push_back(const T &value) {} 168 | /** 169 | * removes the last element 170 | * throw when the container is empty. 171 | */ 172 | void pop_back() {} 173 | /** 174 | * inserts an element to the beginning. 175 | */ 176 | void push_front(const T &value) {} 177 | /** 178 | * removes the first element. 179 | * throw when the container is empty. 180 | */ 181 | void pop_front() {} 182 | }; 183 | 184 | } 185 | 186 | #endif 187 | -------------------------------------------------------------------------------- /deque/exceptions.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SJTU_EXCEPTIONS_HPP 2 | #define SJTU_EXCEPTIONS_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace sjtu { 9 | 10 | class exception { 11 | protected: 12 | const std::string variant = ""; 13 | std::string detail = ""; 14 | public: 15 | exception() {} 16 | exception(const exception &ec) : variant(ec.variant), detail(ec.detail) {} 17 | virtual std::string what() { 18 | return variant + " " + detail; 19 | } 20 | }; 21 | 22 | /** 23 | * TODO 24 | * Please complete them. 25 | */ 26 | class index_out_of_bound : public exception { 27 | /* __________________________ */ 28 | }; 29 | 30 | class runtime_error : public exception { 31 | /* __________________________ */ 32 | }; 33 | 34 | class invalid_iterator : public exception { 35 | /* __________________________ */ 36 | }; 37 | 38 | class container_is_empty : public exception { 39 | /* __________________________ */ 40 | }; 41 | } 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /deque/utility.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SJTU_UTILITY_HPP 2 | #define SJTU_UTILITY_HPP 3 | 4 | #include 5 | 6 | namespace sjtu { 7 | 8 | template 9 | class pair { 10 | public: 11 | T1 first; 12 | T2 second; 13 | constexpr pair() : first(), second() {} 14 | pair(const pair &other) = default; 15 | pair(pair &&other) = default; 16 | pair(const T1 &x, const T2 &y) : first(x), second(y) {} 17 | template 18 | pair(U1 &&x, U2 &&y) : first(x), second(y) {} 19 | template 20 | pair(const pair &other) : first(other.first), second(other.second) {} 21 | template 22 | pair(pair &&other) : first(other.first), second(other.second) {} 23 | }; 24 | 25 | } 26 | 27 | #endif 28 | --------------------------------------------------------------------------------