阶段性的成果。
This commit is contained in:
209
大作业/.clang-format
Normal file
209
大作业/.clang-format
Normal file
@@ -0,0 +1,209 @@
|
||||
---
|
||||
Language: Cpp
|
||||
# BasedOnStyle: LLVM
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignArrayOfStructures: None
|
||||
AlignConsecutiveAssignments:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
PadOperators: true
|
||||
AlignConsecutiveBitFields:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
PadOperators: false
|
||||
AlignConsecutiveDeclarations:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
PadOperators: false
|
||||
AlignConsecutiveMacros:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
PadOperators: false
|
||||
AlignEscapedNewlines: Right
|
||||
AlignOperands: Align
|
||||
AlignTrailingComments: true
|
||||
AllowAllArgumentsOnNextLine: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortEnumsOnASingleLine: true
|
||||
AllowShortBlocksOnASingleLine: Never
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: false
|
||||
AllowShortLambdasOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: MultiLine
|
||||
AttributeMacros:
|
||||
- __capability
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterClass: false
|
||||
AfterControlStatement: Never
|
||||
AfterEnum: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
AfterExternBlock: false
|
||||
BeforeCatch: true
|
||||
BeforeElse: true
|
||||
BeforeLambdaBody: false
|
||||
BeforeWhile: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyRecord: true
|
||||
SplitEmptyNamespace: true
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeConceptDeclarations: Always
|
||||
BreakBeforeBraces: Custom
|
||||
BreakBeforeInheritanceComma: false
|
||||
BreakInheritanceList: BeforeColon
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakStringLiterals: true
|
||||
ColumnLimit: 80
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
QualifierAlignment: Leave
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DeriveLineEnding: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
EmptyLineAfterAccessModifier: Never
|
||||
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
PackConstructorInitializers: BinPack
|
||||
BasedOnStyle: ''
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
AllowAllConstructorInitializersOnNextLine: true
|
||||
FixNamespaceComments: true
|
||||
ForEachMacros:
|
||||
- foreach
|
||||
- Q_FOREACH
|
||||
- BOOST_FOREACH
|
||||
IfMacros:
|
||||
- KJ_IF_MAYBE
|
||||
IncludeBlocks: Preserve
|
||||
IncludeCategories:
|
||||
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||
Priority: 2
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||
Priority: 3
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
- Regex: '.*'
|
||||
Priority: 1
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
IncludeIsMainRegex: '(Test)?$'
|
||||
IncludeIsMainSourceRegex: ''
|
||||
IndentAccessModifiers: false
|
||||
IndentCaseLabels: false
|
||||
IndentCaseBlocks: false
|
||||
IndentGotoLabels: true
|
||||
IndentPPDirectives: None
|
||||
IndentExternBlock: AfterExternBlock
|
||||
IndentRequiresClause: true
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
InsertBraces: false
|
||||
InsertTrailingCommas: None
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
LambdaBodyIndentation: Signature
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCBinPackProtocolList: Auto
|
||||
ObjCBlockIndentWidth: 2
|
||||
ObjCBreakBeforeNestedBlockParam: true
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PenaltyBreakAssignment: 2
|
||||
PenaltyBreakBeforeFirstCallParameter: 19
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakOpenParenthesis: 0
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyBreakTemplateDeclaration: 10
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
PenaltyIndentedWhitespace: 0
|
||||
PointerAlignment: Right
|
||||
PPIndentWidth: -1
|
||||
ReferenceAlignment: Pointer
|
||||
ReflowComments: true
|
||||
RemoveBracesLLVM: false
|
||||
RequiresClausePosition: OwnLine
|
||||
SeparateDefinitionBlocks: Leave
|
||||
ShortNamespaceLines: 1
|
||||
SortIncludes: CaseSensitive
|
||||
SortJavaStaticImport: Before
|
||||
SortUsingDeclarations: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCaseColon: false
|
||||
SpaceBeforeCpp11BracedList: false
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceBeforeParensOptions:
|
||||
AfterControlStatements: true
|
||||
AfterForeachMacros: true
|
||||
AfterFunctionDefinitionName: false
|
||||
AfterFunctionDeclarationName: false
|
||||
AfterIfMacros: true
|
||||
AfterOverloadedOperator: false
|
||||
AfterRequiresInClause: false
|
||||
AfterRequiresInExpression: false
|
||||
BeforeNonEmptyParentheses: false
|
||||
SpaceAroundPointerQualifiers: Default
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceInEmptyBlock: false
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: Never
|
||||
SpacesInConditionalStatement: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInLineCommentPrefix:
|
||||
Minimum: 1
|
||||
Maximum: -1
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
SpaceBeforeSquareBrackets: false
|
||||
BitFieldColonSpacing: Both
|
||||
Standard: Latest
|
||||
StatementAttributeLikeMacros:
|
||||
- Q_EMIT
|
||||
StatementMacros:
|
||||
- Q_UNUSED
|
||||
- QT_REQUIRE_VERSION
|
||||
TabWidth: 4
|
||||
UseCRLF: false
|
||||
UseTab: Never
|
||||
|
||||
53
大作业/Date.cpp
Normal file
53
大作业/Date.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
#include "Date.hpp"
|
||||
|
||||
Date::Date() : time(0), isAny(true){};
|
||||
|
||||
Date::Date(const time_t &_time) : time(_time), isAny(false) {};
|
||||
|
||||
Date::Date(const tm &_time) : isAny(false) {
|
||||
tm temp = _time;
|
||||
this->time = mktime(&temp);
|
||||
}
|
||||
|
||||
void Date::setNewDate(const time_t &newTime) {
|
||||
this->time = newTime;
|
||||
}
|
||||
|
||||
void Date::setNewDate(const tm &newTime) {
|
||||
tm temp = newTime;
|
||||
this->time = mktime(&temp);
|
||||
}
|
||||
|
||||
void Date::setAny() {
|
||||
this->time = 0;
|
||||
this->isAny = true;
|
||||
}
|
||||
|
||||
time_t Date::getTime() const {
|
||||
return this->time;
|
||||
}
|
||||
|
||||
std::string Date::toString() const {
|
||||
char buffer[20];
|
||||
strftime(buffer, 20, "%F", localtime(&this->time));
|
||||
}
|
||||
|
||||
bool Date::operator<(const Date &otherDate) const {
|
||||
return this->isAny || this->time < otherDate.time;
|
||||
}
|
||||
|
||||
bool Date::operator>(const Date &otherDate) const {
|
||||
return this->isAny || this->time > otherDate.time;
|
||||
}
|
||||
|
||||
bool Date::operator<=(const Date &otherDate) const {
|
||||
return this->isAny || this->time <= otherDate.time;
|
||||
}
|
||||
|
||||
bool Date::operator>=(const Date &otherDate) const {
|
||||
return this->isAny || this->time >= otherDate.time;
|
||||
}
|
||||
|
||||
bool Date::operator==(const Date &otherDate) const {
|
||||
return this->isAny || this->time == otherDate.time;
|
||||
}
|
||||
33
大作业/Date.hpp
Normal file
33
大作业/Date.hpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
#include "Exceptions.hpp"
|
||||
#include <ctime>
|
||||
#include <string>
|
||||
|
||||
// Reference: https://cplusplus.com/reference/ctime
|
||||
|
||||
class Date {
|
||||
private:
|
||||
// The time stored.
|
||||
time_t time;
|
||||
// If this date represents "Any time".
|
||||
bool isAny;
|
||||
|
||||
public:
|
||||
Date();
|
||||
Date(const time_t &_time);
|
||||
Date(const tm &_time);
|
||||
// Set the stored date to the argument.
|
||||
void setNewDate(const time_t &newTime);
|
||||
void setNewDate(const tm &newTime);
|
||||
// Set the date to "any".
|
||||
void setAny();
|
||||
// returns the time.
|
||||
time_t getTime() const;
|
||||
// returns a human-readable string of the stored time.
|
||||
std::string toString() const;
|
||||
bool operator<(const Date &otherDate) const;
|
||||
bool operator>(const Date &otherDate) const;
|
||||
bool operator<=(const Date &otherDate) const;
|
||||
bool operator>=(const Date &otherDate) const;
|
||||
bool operator==(const Date &otherDate) const;
|
||||
};
|
||||
16
大作业/Exceptions.cpp
Normal file
16
大作业/Exceptions.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#include "Exceptions.hpp"
|
||||
#include <string>
|
||||
|
||||
BaseException::BaseException(const std::string msg) : message(msg) {};
|
||||
|
||||
BaseListException::BaseListException(const std::string msg) : BaseException(msg) {};
|
||||
|
||||
ValueError::ValueError(const std::string msg) : BaseListException(msg) {};
|
||||
|
||||
IndexError::IndexError(const std::string msg) : BaseListException(msg) {};
|
||||
|
||||
DuplicateError::DuplicateError(const std::string msg) : BaseListException(msg) {};
|
||||
|
||||
BaseDisplayException::BaseDisplayException(const std::string msg) : BaseException(msg) {};
|
||||
|
||||
PageIndexError::PageIndexError(const std::string msg) : BaseDisplayException(msg){};
|
||||
37
大作业/Exceptions.hpp
Normal file
37
大作业/Exceptions.hpp
Normal file
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
class BaseException {
|
||||
public:
|
||||
const std::string message;
|
||||
BaseException(const std::string msg);
|
||||
};
|
||||
|
||||
class BaseListException : public BaseException {
|
||||
public:
|
||||
BaseListException(const std::string msg);
|
||||
};
|
||||
|
||||
class ValueError : public BaseListException {
|
||||
public:
|
||||
ValueError(const std::string msg);
|
||||
};
|
||||
|
||||
class IndexError : public BaseListException {
|
||||
public:
|
||||
IndexError(const std::string msg);
|
||||
};
|
||||
|
||||
class DuplicateError : public BaseListException {
|
||||
public:
|
||||
DuplicateError(const std::string msg);
|
||||
};
|
||||
|
||||
class BaseDisplayException : public BaseException {
|
||||
public:
|
||||
BaseDisplayException(const std::string msg);
|
||||
};
|
||||
|
||||
class PageIndexError : public BaseDisplayException {
|
||||
public:
|
||||
PageIndexError(const std::string msg);
|
||||
};
|
||||
21
大作业/ListDisplay.cpp
Normal file
21
大作业/ListDisplay.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#include "ListDisplay.hpp"
|
||||
#include "Exceptions.hpp"
|
||||
|
||||
ListDisplay::ListDisplay(const List<BaseRecord> &_allRecords)
|
||||
: allRecords(_allRecords), fromDate(), toDate(), recordNumPerPage(20),
|
||||
currentPage(1), totalPage(allRecords.length() / recordNumPerPage + 1),
|
||||
sortOrder(ASCENT), sortByProp(RecordID){};
|
||||
|
||||
bool ListDisplay::hasNext() {
|
||||
return currentPage < totalPage;
|
||||
}
|
||||
|
||||
bool ListDisplay::hasPrev() {
|
||||
return currentPage > 1;
|
||||
}
|
||||
|
||||
void ListDisplay::displayNext() {
|
||||
if (!this->hasNext()) {
|
||||
throw(PageIndexError("No next Page!"));
|
||||
}
|
||||
}
|
||||
40
大作业/ListDisplay.hpp
Normal file
40
大作业/ListDisplay.hpp
Normal file
@@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
#include "ListE.hpp"
|
||||
#include "Record.hpp"
|
||||
#define ASCENT true
|
||||
#define DESCENT false
|
||||
|
||||
enum SortBy {
|
||||
RecordID,
|
||||
RecordDate,
|
||||
RecordCourseName,
|
||||
RecordStudentID,
|
||||
RecordStudentName,
|
||||
RecordType
|
||||
};
|
||||
|
||||
class ListDisplay {
|
||||
private:
|
||||
const List<BaseRecord> &allRecords;
|
||||
List<BaseRecord> filteredRecords;
|
||||
Date fromDate;
|
||||
Date toDate;
|
||||
int recordNumPerPage;
|
||||
int currentPage;
|
||||
int totalPage;
|
||||
bool sortOrder;
|
||||
SortBy sortByProp;
|
||||
|
||||
public:
|
||||
ListDisplay() = delete;
|
||||
ListDisplay(const List<BaseRecord> &_allRecords);
|
||||
bool hasNext();
|
||||
bool hasPrev();
|
||||
void displayNext();
|
||||
void displayPrev();
|
||||
void display();
|
||||
void setSortBy(SortBy _propName);
|
||||
void setSortOrder(bool newOrder);
|
||||
void reapplyFilter();
|
||||
void setRecordNumPerPage(int count);
|
||||
};
|
||||
365
大作业/ListE.hpp
Executable file
365
大作业/ListE.hpp
Executable file
@@ -0,0 +1,365 @@
|
||||
#pragma once
|
||||
#include "Exceptions.hpp"
|
||||
#include "Node.hpp"
|
||||
|
||||
template <class E> class List {
|
||||
private:
|
||||
Node<E> *head;
|
||||
int _length;
|
||||
int getIndexInRange(int index) const;
|
||||
void quickSort(
|
||||
int leftBound, int rightBound,
|
||||
std::function<bool(const E &, const E &)> const &isCorrentOrderFunc);
|
||||
|
||||
public:
|
||||
List();
|
||||
List(const E &newItem);
|
||||
List(const E *newItemList, const int itemCount);
|
||||
List(const List<E> &otherList);
|
||||
~List();
|
||||
// Append _newItem at last. Returns the List itself.
|
||||
List<E> &append(const E &_newItem);
|
||||
// Insert _newItem at index, and move all items at and after [index] 1 step.
|
||||
// Throws IndexError if index is not in the range of [-_length, _length -
|
||||
// 1]. Returns the List itself.
|
||||
List<E> &insert(const int index, const E &_newItem);
|
||||
// Pop the item at given index, default is the to pop the last one.
|
||||
E pop(int index = -1);
|
||||
// Remove the first occurance of target. Throws ValueError if target does
|
||||
// not exist. Returns the List itself.
|
||||
List<E> &remove(const E &target);
|
||||
// Clear all nodes.
|
||||
List<E> &clear();
|
||||
// Swap the element located at index a and b. Throws IndexError if the given
|
||||
// index is beyond length of the list.
|
||||
List<E> &swap(int index_a, int index_b);
|
||||
// Sort this list.
|
||||
List<E> &
|
||||
sort(std::function<bool(const E &, const E &)> const &isCorrectOrderFunc);
|
||||
E &operator[](const int index);
|
||||
const E &operator[](const int index) const;
|
||||
List<E> &operator=(const List<E> &otherList);
|
||||
|
||||
int length() const;
|
||||
bool contains(const E &target) const;
|
||||
// Give the index of target in the list on its first appearance. Throws
|
||||
// ValueError if target does not exist.
|
||||
int index(const E &target) const;
|
||||
// Give the reference to the target in the list on its first appearance.
|
||||
E &search(const E &target);
|
||||
E &search(std::function<bool(const E &)> const &isTargetFunc);
|
||||
// Only retain item that matches the isTargetFunc
|
||||
List<E> &filter(std::function<bool(const E &)> const &isTargetFunc);
|
||||
// Returns a new filtered list.
|
||||
List<E> filtered(std::function<bool(const E &)> const &isTargetFunc);
|
||||
// Returns a sorted NEW list.
|
||||
const List<E> sorted(std::function<bool(const E &, const E &)> const
|
||||
&isCorrectOrderFunc) const;
|
||||
};
|
||||
|
||||
template <class E> int List<E>::getIndexInRange(int index) const {
|
||||
if (index < 0) {
|
||||
index += this->_length;
|
||||
}
|
||||
if (index < 0 || index >= _length) {
|
||||
throw(IndexError("Index not in range!"));
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
template <class E>
|
||||
void List<E>::quickSort(
|
||||
int leftBound, int rightBound,
|
||||
std::function<bool(const E &, const E &)> const &isCorrentOrderFunc) {
|
||||
if (leftBound >= rightBound) {
|
||||
return;
|
||||
}
|
||||
|
||||
int pivot = leftBound;
|
||||
int left = leftBound;
|
||||
int right = rightBound;
|
||||
|
||||
while (left < right) {
|
||||
while (isCorrentOrderFunc((*this)[pivot], (*this)[right]) &&
|
||||
right > left) {
|
||||
right--;
|
||||
}
|
||||
this->swap(pivot, right);
|
||||
pivot = right;
|
||||
|
||||
while (isCorrentOrderFunc((*this)[left], (*this)[pivot]) &&
|
||||
right > left) {
|
||||
left++;
|
||||
}
|
||||
this->swap(left, pivot);
|
||||
pivot = left;
|
||||
}
|
||||
|
||||
quickSort(leftBound, pivot - 1, isCorrentOrderFunc);
|
||||
quickSort(pivot + 1, rightBound, isCorrentOrderFunc);
|
||||
}
|
||||
|
||||
template <class E> List<E>::List() : head(NULL), _length(0){};
|
||||
|
||||
template <class E>
|
||||
List<E>::List(const E &newItem) : head(new Node<E>(newItem)), _length(1){};
|
||||
|
||||
template <class E> List<E>::List(const E *newItemList, const int itemCount) {
|
||||
for (int i = 0; i < itemCount; i++) {
|
||||
this->append(newItemList[i]);
|
||||
}
|
||||
};
|
||||
|
||||
template <class E> List<E>::List(const List<E> &otherList) {
|
||||
if (otherList.length() > 0) {
|
||||
this->head = new Node<E>(otherList[0]);
|
||||
this->_length = 1;
|
||||
Node<E> *nextPtr = otherList.head->getNextPtr();
|
||||
while (nextPtr != NULL) {
|
||||
this->append((*nextPtr).getContent());
|
||||
nextPtr = (*nextPtr).getNextPtr();
|
||||
}
|
||||
}
|
||||
else {
|
||||
this->head = NULL;
|
||||
this->_length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template <class E> List<E>::~List() {
|
||||
if (this->head != NULL) {
|
||||
this->head->destruct();
|
||||
}
|
||||
head = NULL;
|
||||
}
|
||||
|
||||
template <class E> List<E> &List<E>::append(const E &_newItem) {
|
||||
if (this->head == NULL) {
|
||||
this->head = new Node<E>(_newItem);
|
||||
}
|
||||
else {
|
||||
this->head->getTail().setNext(new Node<E>(_newItem));
|
||||
}
|
||||
this->_length++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class E> List<E> &List<E>::insert(int index, const E &_newItem) {
|
||||
index = this->getIndexInRange(index);
|
||||
if (index == 0) {
|
||||
this->head = new Node<E>(_newItem, this->head);
|
||||
}
|
||||
else {
|
||||
Node<E> &prev = this->head->getByIndex(index - 1);
|
||||
prev.setNext(new Node<E>(_newItem, prev.getNextPtr()));
|
||||
}
|
||||
this->_length++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class E> List<E> &List<E>::remove(const E &target) {
|
||||
this->pop(this->index(target));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class E> E List<E>::pop(int index) {
|
||||
index = this->getIndexInRange(index);
|
||||
|
||||
Node<E> removed = this->head->getByIndex(index);
|
||||
|
||||
this->_length--;
|
||||
if (index == 0) {
|
||||
Node<E> *newHead = this->head->getNextPtr();
|
||||
delete this->head;
|
||||
this->head = newHead;
|
||||
}
|
||||
else {
|
||||
Node<E> &prev = this->head->getByIndex(index - 1);
|
||||
delete prev.getNextPtr();
|
||||
prev.setNext(removed.getNextPtr());
|
||||
}
|
||||
return removed.getContent();
|
||||
}
|
||||
|
||||
template <class E> List<E> &List<E>::clear() {
|
||||
this->head->destruct();
|
||||
this->head = NULL;
|
||||
this->_length = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class E> List<E> &List<E>::swap(int index_a, int index_b) {
|
||||
index_a = this->getIndexInRange(index_a);
|
||||
index_b = this->getIndexInRange(index_b);
|
||||
if (index_a == index_b) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
Node<E> *tempPtr;
|
||||
|
||||
if (index_a == 0) {
|
||||
if (index_b == 1) {
|
||||
Node<E> &A = this->head->getByIndex(0);
|
||||
Node<E> &B = this->head->getByIndex(1);
|
||||
Node<E> *afterB = B.getNextPtr();
|
||||
this->head = &B;
|
||||
B.setNext(&A);
|
||||
A.setNext(afterB);
|
||||
}
|
||||
else {
|
||||
Node<E> &A = this->head->getByIndex(index_a);
|
||||
Node<E> *afterA = A.getNextPtr();
|
||||
Node<E> &beforeB = this->head->getByIndex(index_b - 1);
|
||||
Node<E> &B = this->head->getByIndex(index_b);
|
||||
Node<E> *afterB = B.getNextPtr();
|
||||
|
||||
this->head = &B;
|
||||
beforeB.setNext(&A);
|
||||
A.setNext(afterB);
|
||||
B.setNext(afterA);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (index_b == index_a + 1) {
|
||||
Node<E> &beforeA = this->head->getByIndex(index_a - 1);
|
||||
Node<E> &A = beforeA.getByIndex(1);
|
||||
Node<E> &B = A.getByIndex(1);
|
||||
Node<E> *afterB = B.getNextPtr();
|
||||
beforeA.setNext(&B);
|
||||
B.setNext(&A);
|
||||
A.setNext(afterB);
|
||||
}
|
||||
else {
|
||||
Node<E> &beforeA = this->head->getByIndex(index_a - 1);
|
||||
Node<E> &A = this->head->getByIndex(index_a);
|
||||
Node<E> *afterA = A.getNextPtr();
|
||||
Node<E> &beforeB = this->head->getByIndex(index_b - 1);
|
||||
Node<E> &B = this->head->getByIndex(index_b);
|
||||
Node<E> *afterB = B.getNextPtr();
|
||||
|
||||
beforeA.setNext(&B);
|
||||
B.setNext(afterA);
|
||||
beforeB.setNext(&A);
|
||||
A.setNext(afterB);
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class E>
|
||||
List<E> &List<E>::sort(
|
||||
std::function<bool(const E &, const E &)> const &isCorrectOrderFunc) {
|
||||
this->quickSort(0, this->_length - 1, isCorrectOrderFunc);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class E> E &List<E>::operator[](const int index) {
|
||||
return this->head->getByIndex(getIndexInRange(index)).getContent();
|
||||
}
|
||||
|
||||
template <class E> const E &List<E>::operator[](const int index) const {
|
||||
return this->head->getByIndex(getIndexInRange(index)).getContent();
|
||||
}
|
||||
|
||||
template <class E> List<E> &List<E>::operator=(const List<E> &otherList) {
|
||||
this->clear();
|
||||
if (otherList.length() > 0) {
|
||||
this->head = new Node<E>(otherList[0]);
|
||||
this->_length = 1;
|
||||
Node<E> *nextPtr = otherList->head->getNextPtr();
|
||||
while (nextPtr != NULL) {
|
||||
this->append((*nextPtr).getContent());
|
||||
nextPtr = (*nextPtr).getNextPtr();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class E> int List<E>::length() const {
|
||||
return this->_length;
|
||||
}
|
||||
|
||||
template <class E> bool List<E>::contains(const E &target) const {
|
||||
if (this->_length == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Node<E> *current = this->head;
|
||||
do {
|
||||
if (current->getContent() == target) {
|
||||
return true;
|
||||
}
|
||||
current = current->getNextPtr();
|
||||
} while (current != NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class E> int List<E>::index(const E &target) const {
|
||||
Node<E> *nextPtr = this->head;
|
||||
int pos = 0;
|
||||
while (nextPtr != NULL) {
|
||||
if (nextPtr->getContent() == target) {
|
||||
return pos;
|
||||
}
|
||||
pos++;
|
||||
nextPtr = nextPtr->getNextPtr();
|
||||
}
|
||||
throw(ValueError("Target not found!"));
|
||||
}
|
||||
|
||||
template <class E> E &List<E>::search(const E &target) {
|
||||
Node<E> *nextPtr = this->head;
|
||||
while (nextPtr != NULL) {
|
||||
if (nextPtr->getContent() == target) {
|
||||
return nextPtr->getContent();
|
||||
}
|
||||
nextPtr = nextPtr->getNextPtr();
|
||||
}
|
||||
throw(ValueError("Target not found!"));
|
||||
}
|
||||
|
||||
template <class E>
|
||||
E &List<E>::search(std::function<bool(const E &)> const &isTargetFunc) {
|
||||
Node<E> *nextPtr = this->head;
|
||||
while (nextPtr != NULL) {
|
||||
if (isTargetFunc(nextPtr->getContent())) {
|
||||
return nextPtr->getContent();
|
||||
}
|
||||
nextPtr = nextPtr->getNextPtr();
|
||||
}
|
||||
throw(ValueError("Target not found!"));
|
||||
}
|
||||
|
||||
template <class E>
|
||||
List<E> &List<E>::filter(std::function<bool(const E &)> const &isTargetFunc) {
|
||||
if (this->_length == 0) {
|
||||
return *this;
|
||||
}
|
||||
while (this->_length > 0 && !isTargetFunc(this->head->getContent())) {
|
||||
Node<E> *newHead = this->head->getNextPtr();
|
||||
delete this->head;
|
||||
this->head = newHead;
|
||||
this->_length--;
|
||||
}
|
||||
|
||||
Node<E> *current = this->head;
|
||||
while(current->getNextPtr() != NULL) {
|
||||
if (!isTargetFunc(current->getNextPtr()->getContent())) {
|
||||
Node<E> *newNext = current->getNextPtr()->getNextPtr();
|
||||
delete current->getNextPtr();
|
||||
current->setNext(newNext);
|
||||
continue;
|
||||
}
|
||||
current = current->getNextPtr();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class E> List<E> List<E>::filtered(std::function<bool(const E&)> const &isTargetFunc) {
|
||||
return List<E>(*this).filter(isTargetFunc);
|
||||
}
|
||||
|
||||
template <class E>
|
||||
const List<E> List<E>::sorted(
|
||||
std::function<bool(const E &, const E &)> const &isCorrectOrderFunc) const {
|
||||
return List<E>(*this).sort(isCorrectOrderFunc);
|
||||
}
|
||||
19
大作业/Makefile
Normal file
19
大作业/Makefile
Normal file
@@ -0,0 +1,19 @@
|
||||
generalArguments = -std=c++11
|
||||
|
||||
main.out: main.o Tools.o Exceptions.o
|
||||
clang++ $(generalArguments) -g $^ -o main.out
|
||||
|
||||
main.o: main.cpp
|
||||
clang++ $(generalArguments) -g -c main.cpp -o main.o
|
||||
|
||||
Exceptions.o: Exceptions.cpp
|
||||
clang++ $(generalArguments) -g -c Exceptions.cpp -o Exceptions.o
|
||||
|
||||
Record.o: Record.cpp
|
||||
clang++ $(generalArguments) -g -c Record.cpp -o Record.o
|
||||
|
||||
Date.o: Date.cpp
|
||||
clang++ $(generalArguments) -g -c Date.cpp -o Date.o
|
||||
|
||||
Tools.o: Tools.cpp
|
||||
clang++ $(generalArguments) -g -c Tools.cpp -o Tools.o
|
||||
75
大作业/Node.hpp
Executable file
75
大作业/Node.hpp
Executable file
@@ -0,0 +1,75 @@
|
||||
#pragma once
|
||||
#include <iostream>
|
||||
|
||||
template <class E> class Node {
|
||||
private:
|
||||
E content;
|
||||
Node *nextNode;
|
||||
|
||||
public:
|
||||
Node();
|
||||
Node(E _content, Node<E> *_nextNode = NULL);
|
||||
~Node();
|
||||
// Returns a reference to the content.
|
||||
E &getContent();
|
||||
// Returns a reference to the next Node. May return NULL if this Node is the
|
||||
// last one.
|
||||
Node<E> *getNextPtr();
|
||||
// Set the next Node _nextNode. Returns original pointer.
|
||||
Node<E> *setNext(Node<E> *_nextNode);
|
||||
// Returns a reference to the Tail.
|
||||
Node<E> &getTail();
|
||||
// Returns a reference to the Node of given index.
|
||||
Node<E> &getByIndex(const int index);
|
||||
// Compare the content with the argument.
|
||||
bool operator==(const E &other);
|
||||
// Destructs the Node itself and all the node behind it.
|
||||
void destruct();
|
||||
};
|
||||
|
||||
template <class E> Node<E>::Node() : content(0), nextNode(NULL){};
|
||||
|
||||
template <class E>
|
||||
Node<E>::Node(E _content, Node *_nextNode)
|
||||
: content(_content), nextNode(_nextNode){};
|
||||
|
||||
template <class E> Node<E>::~Node(){};
|
||||
|
||||
template <class E> E &Node<E>::getContent() {
|
||||
return this->content;
|
||||
}
|
||||
|
||||
template <class E> Node<E> *Node<E>::getNextPtr() {
|
||||
return this->nextNode;
|
||||
}
|
||||
|
||||
template <class E> Node<E> *Node<E>::setNext(Node<E> *_nextNode) {
|
||||
Node<E> *temp = this->nextNode;
|
||||
this->nextNode = _nextNode;
|
||||
return temp;
|
||||
}
|
||||
|
||||
template <class E> Node<E> &Node<E>::getTail() {
|
||||
if (this->nextNode == NULL) {
|
||||
return *this;
|
||||
}
|
||||
return this->nextNode->getTail();
|
||||
}
|
||||
|
||||
template <class E> Node<E> &Node<E>::getByIndex(const int index) {
|
||||
if (index == 0) {
|
||||
return *this;
|
||||
}
|
||||
return this->nextNode->getByIndex(index - 1);
|
||||
}
|
||||
|
||||
template <class E> bool Node<E>::operator==(const E &other) {
|
||||
return this->content == other;
|
||||
}
|
||||
|
||||
template <class E> void Node<E>::destruct() {
|
||||
if (this->nextNode != NULL) {
|
||||
this->nextNode->destruct();
|
||||
}
|
||||
delete this;
|
||||
}
|
||||
216
大作业/Record.cpp
Normal file
216
大作业/Record.cpp
Normal file
@@ -0,0 +1,216 @@
|
||||
#include "Record.hpp"
|
||||
#include "Tools.hpp"
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
unsigned BaseRecord::nextRecordID = 0;
|
||||
|
||||
std::string BaseRecord::cutToLength(std::string str, int length) const {
|
||||
if (str.length() <= length) {
|
||||
return str;
|
||||
}
|
||||
else {
|
||||
return str.substr(length) + "+";
|
||||
}
|
||||
}
|
||||
|
||||
BaseRecord::BaseRecord(const time_t _date, const std::string _courseName,
|
||||
const int _studentNumber, const std::string _studentName)
|
||||
: recordID(nextRecordID++), date(_date), courseName(_courseName),
|
||||
studentNumber(_studentNumber), studentName(_studentName){};
|
||||
|
||||
BaseRecord::BaseRecord(const unsigned _recordID, const time_t _date,
|
||||
const std::string _courseName, const int _studentNumber,
|
||||
const std::string _studentName)
|
||||
: recordID(_recordID), date(_date), courseName(_courseName),
|
||||
studentNumber(_studentNumber), studentName(_studentName){};
|
||||
|
||||
const unsigned BaseRecord::getRecordID() const {
|
||||
return this->recordID;
|
||||
}
|
||||
|
||||
const Date &BaseRecord::getDate() const {
|
||||
return this->date;
|
||||
}
|
||||
|
||||
const std::string BaseRecord::getCourseName() const {
|
||||
return this->courseName;
|
||||
}
|
||||
|
||||
const int BaseRecord::getStudentNumber() const {
|
||||
return this->studentNumber;
|
||||
}
|
||||
|
||||
const std::string BaseRecord::getStudentName() const {
|
||||
return this->studentName;
|
||||
}
|
||||
|
||||
void BaseRecord::promptForNewDate(bool showOriginal = true) {
|
||||
time_t originTime = this->date.getTime();
|
||||
tm *curDate = localtime(&originTime);
|
||||
int tempInput;
|
||||
if (showOriginal) {
|
||||
char buffer[20];
|
||||
strftime(buffer, 20, "%F", curDate);
|
||||
std::cout << setoutputcolor(green) << "Current date: " << buffer
|
||||
<< ". Enter 0 to retain original value." << resetOutputColor
|
||||
<< std::endl;
|
||||
std::cout << setoutputcolor(blue) << "Year: " << resetOutputColor
|
||||
<< std::flush;
|
||||
std::cin >> tempInput;
|
||||
curDate->tm_year =
|
||||
(tempInput == 0 ? curDate->tm_year : tempInput - 1900);
|
||||
std::cout << setoutputcolor(blue) << "Month: " << resetOutputColor
|
||||
<< std::flush;
|
||||
std::cin >> tempInput;
|
||||
curDate->tm_mon = (tempInput == 0 ? curDate->tm_mon : tempInput - 1);
|
||||
std::cout << setoutputcolor(blue) << "Day: " << resetOutputColor
|
||||
<< std::flush;
|
||||
std::cin >> tempInput;
|
||||
curDate->tm_mday = (tempInput == 0 ? curDate->tm_mday : tempInput);
|
||||
}
|
||||
else {
|
||||
std::cout << setoutputcolor(blue) << "Year: " << resetOutputColor
|
||||
<< std::flush;
|
||||
std::cin >> tempInput;
|
||||
curDate->tm_year = tempInput - 1900;
|
||||
std::cout << setoutputcolor(blue) << "Month: " << resetOutputColor
|
||||
<< std::flush;
|
||||
std::cin >> tempInput;
|
||||
curDate->tm_mon = tempInput - 1;
|
||||
std::cout << setoutputcolor(blue) << "Day: " << resetOutputColor
|
||||
<< std::flush;
|
||||
std::cin >> tempInput;
|
||||
curDate->tm_mday = tempInput;
|
||||
}
|
||||
this->date = mktime(curDate);
|
||||
}
|
||||
|
||||
void BaseRecord::promptForNewCourseName(bool showOriginal = true) {
|
||||
if (showOriginal) {
|
||||
std::cout << setoutputcolor(green)
|
||||
<< "Original course name: " << resetOutputColor
|
||||
<< this->courseName << std::endl;
|
||||
}
|
||||
std::cout << "Course name: " << std::flush;
|
||||
std::cin >> this->courseName;
|
||||
}
|
||||
|
||||
void BaseRecord::promptForNewStudentInfo(bool showOriginal = true) {
|
||||
if (showOriginal) {
|
||||
int tempStuID;
|
||||
std::string tempStuName;
|
||||
std::cout << setoutputcolor(green) << "Current student info: \n"
|
||||
<< setoutputcolor(blue) << "Student ID: " << resetOutputColor
|
||||
<< this->studentNumber << "\n"
|
||||
<< setoutputcolor(blue)
|
||||
<< "Student Name: " << resetOutputColor << this->studentName
|
||||
<< "\n"
|
||||
<< setoutputcolor(green)
|
||||
<< "Enter 0 to retain original value." << std::endl;
|
||||
std::cout << setoutputcolor(blue) << "Student ID: " << resetOutputColor
|
||||
<< std::flush;
|
||||
std::cin >> tempStuID;
|
||||
this->studentNumber =
|
||||
(tempStuID == 0 ? this->studentNumber : tempStuID);
|
||||
std::cout << setoutputcolor(blue)
|
||||
<< "Studnet Name: " << resetOutputColor << std::flush;
|
||||
std::cin >> tempStuName;
|
||||
this->studentName =
|
||||
(tempStuName == "0" ? this->studentName : tempStuName);
|
||||
}
|
||||
else {
|
||||
std::cout << setoutputcolor(blue) << "Student ID: " << resetOutputColor
|
||||
<< std::flush;
|
||||
std::cin >> this->studentNumber;
|
||||
std::cout << setoutputcolor(blue)
|
||||
<< "Studnet Name: " << resetOutputColor << std::flush;
|
||||
std::cin >> this->studentName;
|
||||
}
|
||||
}
|
||||
|
||||
void BaseRecord::display() const {
|
||||
std::cout << std::setfill('0') << std::setw(8) << this->recordID;
|
||||
std::cout << " ";
|
||||
std::cout << std::setfill(' ') << std::setw(8)
|
||||
<< this->cutToLength(this->date.toString(), 8);
|
||||
std::cout << " ";
|
||||
std::cout << std::setfill(' ') << std::setw(15)
|
||||
<< this->cutToLength(this->courseName, 15);
|
||||
std::cout << " ";
|
||||
std::cout << std::setfill(' ') << std::setw(8) << this->studentNumber;
|
||||
std::cout << " ";
|
||||
std::cout << std::setfill(' ') << std::setw(15)
|
||||
<< this->cutToLength(this->studentName, 15);
|
||||
std::cout << std::setfill(' ') << std::setw(10) << this->getRecordType();
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
LateRecord::LateRecord(const time_t _date, const std::string _courseName,
|
||||
const int _studentNumber, const std::string _studentName)
|
||||
: BaseRecord(_date, _courseName, _studentNumber, _studentName){};
|
||||
|
||||
LateRecord::LateRecord(const unsigned _recordID, const time_t _date,
|
||||
const std::string _courseName, const int _studentNumber,
|
||||
const std::string _studentName)
|
||||
: BaseRecord(_recordID, _date, _courseName, _studentNumber, _studentName){};
|
||||
|
||||
std::string LateRecord::getRecordType() const {
|
||||
return "Late";
|
||||
}
|
||||
|
||||
AbsentRecord::AbsentRecord(const time_t _date, const std::string _courseName,
|
||||
const int _studentNumber,
|
||||
const std::string _studentName)
|
||||
: BaseRecord(_date, _courseName, _studentNumber, _studentName){};
|
||||
|
||||
AbsentRecord::AbsentRecord(const unsigned _recordID, const time_t _date,
|
||||
const std::string _courseName,
|
||||
const int _studentNumber,
|
||||
const std::string _studentName)
|
||||
: BaseRecord(_recordID, _date, _courseName, _studentNumber, _studentName){};
|
||||
|
||||
std::string AbsentRecord::getRecordType() const {
|
||||
return "Absent";
|
||||
}
|
||||
|
||||
PersonalLeaveRecord::PersonalLeaveRecord(const time_t _date,
|
||||
const std::string _courseName,
|
||||
const int _studentNumber,
|
||||
const std::string _studentName)
|
||||
: BaseRecord(_date, _courseName, _studentNumber, _studentName){};
|
||||
|
||||
PersonalLeaveRecord::PersonalLeaveRecord(const unsigned _recordID,
|
||||
const time_t _date,
|
||||
const std::string _courseName,
|
||||
const int _studentNumber,
|
||||
const std::string _studentName)
|
||||
: BaseRecord(_recordID, _date, _courseName, _studentNumber, _studentName){};
|
||||
|
||||
std::string PersonalLeaveRecord::getRecordType() const {
|
||||
return "Personal";
|
||||
}
|
||||
|
||||
SaveRecord::SaveRecord(const unsigned _recordID, const time_t _date,
|
||||
const std::string &courseName, const int _studentNumber,
|
||||
const std::string &studentName, RecordType _recordType)
|
||||
: recordID(_recordID), date(_date), courseNameLength(courseName.length()),
|
||||
studentNumber(_studentNumber), studentNameLength(studentName.length()),
|
||||
recordType(_recordType){};
|
||||
|
||||
BaseRecord &&SaveRecord::convertToRecord(const char *_courseName,
|
||||
const char *_name) const {
|
||||
switch (this->recordType) {
|
||||
case Late:
|
||||
return LateRecord(this->recordID, this->date, std::string(_courseName),
|
||||
this->studentNumber, std::string(_name));
|
||||
case Absent:
|
||||
return AbsentRecord(this->recordID, this->date,
|
||||
std::string(_courseName), this->studentNumber,
|
||||
std::string(_name));
|
||||
case PersonalLeave:
|
||||
return PersonalLeaveRecord(this->recordID, this->date,
|
||||
std::string(_courseName),
|
||||
this->studentNumber, std::string(_name));
|
||||
}
|
||||
}
|
||||
102
大作业/Record.hpp
Normal file
102
大作业/Record.hpp
Normal file
@@ -0,0 +1,102 @@
|
||||
#pragma once
|
||||
#include "Date.hpp"
|
||||
#include <ctime>
|
||||
|
||||
/*
|
||||
The file should be in this stucture:
|
||||
int totalRecordNum
|
||||
unsigned nextRecordID
|
||||
|
||||
SaveRecord
|
||||
courseName char[]
|
||||
stduentName char[]
|
||||
|
||||
SaveRecord
|
||||
courseName char[]
|
||||
*/
|
||||
|
||||
enum RecordType { Late, Absent, PersonalLeave };
|
||||
|
||||
class BaseRecord {
|
||||
private:
|
||||
unsigned recordID;
|
||||
Date date;
|
||||
std::string courseName;
|
||||
int studentNumber;
|
||||
std::string studentName;
|
||||
// If the string is shorter than length, returns the string; if the string
|
||||
// is longer than length, takes the first lenght - 1 letters and add a "+".
|
||||
std::string cutToLength(std::string str, int length) const;
|
||||
|
||||
public:
|
||||
static unsigned nextRecordID;
|
||||
BaseRecord() = delete;
|
||||
// Create new record
|
||||
BaseRecord(const time_t _date, const std::string _courseName,
|
||||
const int _studentNumber, const std::string _studentName);
|
||||
// Read from file
|
||||
BaseRecord(const unsigned _recordID, const time_t _date,
|
||||
const std::string _courseName, const int _studentNumber,
|
||||
const std::string _studentName);
|
||||
const unsigned getRecordID() const;
|
||||
const Date &getDate() const;
|
||||
const std::string getCourseName() const;
|
||||
const int getStudentNumber() const;
|
||||
const std::string getStudentName() const;
|
||||
void promptForNewDate(bool showOriginal = true);
|
||||
void promptForNewCourseName(bool showOriginal = true);
|
||||
void promptForNewStudentInfo(bool showOriginal = true);
|
||||
void display() const;
|
||||
const char *getCourseNameChar() const;
|
||||
const char *getStudentNameChar() const;
|
||||
virtual std::string getRecordType() const = 0;
|
||||
};
|
||||
|
||||
class LateRecord : public BaseRecord {
|
||||
public:
|
||||
LateRecord(const time_t _date, const std::string _courseName,
|
||||
const int _studentNumber, const std::string _studentName);
|
||||
LateRecord(const unsigned _recordID, const time_t _date,
|
||||
const std::string _courseName, const int _studentNumber,
|
||||
const std::string _studentName);
|
||||
virtual std::string getRecordType() const;
|
||||
};
|
||||
|
||||
class AbsentRecord : public BaseRecord {
|
||||
public:
|
||||
AbsentRecord(const time_t _date, const std::string _courseName,
|
||||
const int _studentNumber, const std::string _studentName);
|
||||
AbsentRecord(const unsigned _recordID, const time_t _date,
|
||||
const std::string _courseName, const int _studentNumber,
|
||||
const std::string _studentName);
|
||||
virtual std::string getRecordType() const;
|
||||
};
|
||||
|
||||
class PersonalLeaveRecord : public BaseRecord {
|
||||
public:
|
||||
PersonalLeaveRecord(const time_t _date, const std::string _courseName,
|
||||
const int _studentNumber,
|
||||
const std::string _studentName);
|
||||
PersonalLeaveRecord(const unsigned _recordID, const time_t _date,
|
||||
const std::string _courseName, const int _studentNumber,
|
||||
const std::string _studentName);
|
||||
virtual std::string getRecordType() const;
|
||||
};
|
||||
|
||||
class SaveRecord {
|
||||
private:
|
||||
unsigned recordID;
|
||||
time_t date;
|
||||
int courseNameLength;
|
||||
int studentNumber;
|
||||
int studentNameLength;
|
||||
RecordType recordType;
|
||||
|
||||
public:
|
||||
SaveRecord() = delete;
|
||||
SaveRecord(const unsigned _recordID, const time_t _date,
|
||||
const std::string &courseName, const int _studentNumber,
|
||||
const std::string &studentName, RecordType _recordType);
|
||||
BaseRecord &&convertToRecord(const char *_courseName,
|
||||
const char *_name) const;
|
||||
};
|
||||
22
大作业/Student.hpp
Normal file
22
大作业/Student.hpp
Normal file
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
class Student {
|
||||
private:
|
||||
int number;
|
||||
std::string name;
|
||||
|
||||
public:
|
||||
Student();
|
||||
Student(const int _number, const std::string _name);
|
||||
Student(const Student &otherStudent);
|
||||
// Return the student in format 'number name'.
|
||||
std::string toString();
|
||||
// Returns student number.
|
||||
int getNumber();
|
||||
// Returns student name.
|
||||
std::string getName();
|
||||
// Set the new name (especially when reading from file)
|
||||
void setName(const std::string newName);
|
||||
void setName(const char *newName);
|
||||
};
|
||||
|
||||
14
大作业/StudentInfoManager.hpp
Normal file
14
大作业/StudentInfoManager.hpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
#include "Date.hpp"
|
||||
#include <ctime>
|
||||
#include <string>
|
||||
|
||||
|
||||
class StudentInfoManager {
|
||||
private:
|
||||
|
||||
|
||||
public:
|
||||
StudentInfoManager();
|
||||
StudentInfoManager(std::string fileName);
|
||||
};
|
||||
42
大作业/Tools.cpp
Normal file
42
大作业/Tools.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#include "Tools.hpp"
|
||||
setoutputcolor::setoutputcolor() : color(clear), bold(false) {};
|
||||
|
||||
setoutputcolor::setoutputcolor(ConsoleColors _color) : color(_color), bold(false) {};
|
||||
|
||||
setoutputcolor::setoutputcolor(bool _bold) : color(clear), bold(_bold) {};
|
||||
|
||||
setoutputcolor::setoutputcolor(ConsoleColors _color, bool _bold) : color(_color), bold(_bold) {};
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, setoutputcolor setOutput) {
|
||||
out << "\033[";
|
||||
if (setOutput.color == clear) {
|
||||
out << "0m";
|
||||
return out;
|
||||
}
|
||||
if (setOutput.bold) {
|
||||
out << "1";
|
||||
}
|
||||
else {
|
||||
out << "0";
|
||||
}
|
||||
switch (setOutput.color) {
|
||||
case red:
|
||||
out << ";31m";
|
||||
break;
|
||||
case green:
|
||||
out << ";32m";
|
||||
break;
|
||||
case blue:
|
||||
out << ";34m";
|
||||
break;
|
||||
default:
|
||||
out << ";0m";
|
||||
break;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostream &resetOutputColor(std::ostream &out) {
|
||||
out << setoutputcolor();
|
||||
return out;
|
||||
}
|
||||
22
大作业/Tools.hpp
Normal file
22
大作业/Tools.hpp
Normal file
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
#include <iostream>
|
||||
|
||||
// Reference: https://cplusplus.com/forum/unices/36461/
|
||||
|
||||
enum ConsoleColors { red, green, blue, clear };
|
||||
|
||||
class setoutputcolor {
|
||||
private:
|
||||
ConsoleColors color;
|
||||
bool bold;
|
||||
friend std::ostream &operator<<(std::ostream &out,
|
||||
setoutputcolor setOutput);
|
||||
|
||||
public:
|
||||
setoutputcolor();
|
||||
setoutputcolor(ConsoleColors _color);
|
||||
setoutputcolor(bool bold);
|
||||
setoutputcolor(ConsoleColors _color, bool bold);
|
||||
};
|
||||
|
||||
std::ostream &resetOutputColor(std::ostream &out);
|
||||
44
大作业/main.cpp
Normal file
44
大作业/main.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#include "ListE.hpp"
|
||||
#include "Tools.hpp"
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
template <class E> void display(List<E> list) {
|
||||
for (int i = 0; i < list.length(); i++) {
|
||||
std::cout << list[i] << ' ';
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
int main() {
|
||||
List<int> aList;
|
||||
aList.append(4);
|
||||
aList.append(5);
|
||||
aList.append(6);
|
||||
aList.append(7);
|
||||
display(aList);
|
||||
aList.append(8);
|
||||
aList.pop(0);
|
||||
display(aList);
|
||||
|
||||
aList.swap(0, 3);
|
||||
display(aList);
|
||||
|
||||
// aList.sort([=](const int &a, const int &b) { return a > b; });
|
||||
|
||||
// display(aList);
|
||||
|
||||
List<int> bList =
|
||||
aList.sorted([=](const int &a, const int &b) { return a > b; });
|
||||
|
||||
display(bList);
|
||||
|
||||
bList.append(5);
|
||||
|
||||
display(bList);
|
||||
|
||||
bList.filter([=](const int &a) { return a > 6; });
|
||||
display(bList);
|
||||
std::cout << "hhh" << setoutputcolor(blue, true) << "aaa" << setoutputcolor(blue, false) << "bbb" << setoutputcolor() << std::endl;
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user