├── Face_Recognize ├── C++ │ ├── src │ │ ├── CamerCapturemodel.h │ │ ├── DatabaseModel.h │ │ ├── PredictModel.h │ │ ├── TrainningModel.h │ │ └── UserCenterModel.h │ └── tools │ │ ├── camera.cpp │ │ └── create_csv_file.cpp └── Python │ └── tools │ ├── camera.py │ └── createFile.py ├── MachineLearning └── decision_tree │ ├── C4.5 │ ├── C4.5.cpp │ ├── decisionstructure.h │ ├── require.h │ └── watermelondatas.txt │ └── ID3 │ ├── ID3.cpp │ ├── decisionstructure.h │ ├── require.h │ └── watermelondatas.txt ├── QQ ├── QQ.pro ├── Resource.qrc ├── basewindow.cpp ├── basewindow.h ├── config.h ├── css │ ├── BaseWindowCss.css │ ├── LoginWindowCss.css │ └── LoginWindowCss.qss ├── images │ ├── HeadImage.png │ ├── LoginImages │ │ ├── HeadImage.png │ │ ├── arrowback.png │ │ ├── back.gif │ │ ├── checkbox.png │ │ ├── closeback.png │ │ ├── drop_down_Button.png │ │ ├── flicker.png │ │ ├── keyboard.png │ │ ├── minback.png │ │ └── more_accountlogin.png │ ├── LoginState │ │ ├── state_Qme.png │ │ ├── state_away.png │ │ ├── state_busy.png │ │ ├── state_hide.png │ │ ├── state_notdisturb.png │ │ └── state_online.png │ ├── TitleBar │ │ ├── arrow.png │ │ ├── arrow_hover.png │ │ ├── arrow_press.png │ │ ├── close.png │ │ ├── close_hover.png │ │ ├── close_press.png │ │ ├── max.png │ │ ├── min_.png │ │ ├── min_hover.bmp │ │ ├── min_press.bmp │ │ └── restore.png │ ├── arrowback.png │ ├── back.gif │ ├── checkbox.png │ ├── closeback.png │ ├── drop_down_Button.png │ ├── flicker.png │ ├── headBack.gif │ ├── keyboard.png │ ├── menu_border.png │ ├── minback.png │ ├── more_accountlogin.png │ ├── shadow.png │ ├── state_Qme.png │ ├── state_away.png │ ├── state_busy.png │ ├── state_hide.png │ ├── state_notdisturb.png │ └── state_online.png ├── logininterface.cpp ├── logininterface.h ├── logininterface.ui ├── main.cpp ├── qrcodedialog.cpp ├── qrcodedialog.h ├── qrcodedialog.ui ├── windowtoptitle.cpp └── windowtoptitle.h ├── README.md ├── STL_re ├── docs │ ├── allocator.md │ ├── string.mdown │ └── vector.md ├── library │ ├── xstl_algo_copy.h │ ├── xstl_algo_equal.h │ ├── xstl_algo_fill.h │ ├── xstl_algo_find.h │ ├── xstl_algo_for_each.h │ ├── xstl_algo_unique.h │ ├── xstl_algorithm.h │ ├── xstl_allocator.h │ ├── xstl_string.h │ └── xstl_vector.h └── test │ ├── algorithm_test.cpp │ ├── allocator_test.cpp │ ├── string_test.cpp │ └── vector_test.cpp └── Spider └── Taobao └── login_taobao.py /Face_Recognize/C++/src/CamerCapturemodel.h: -------------------------------------------------------------------------------- 1 | #ifndef CAMERACAPTUREMODEL_H__ 2 | #define CAMERACAPTUREMODEL_H__ 3 | 4 | #include "PredictModel.h" 5 | #include 6 | 7 | class CameraCaptureModel 8 | { 9 | public: 10 | // Use the default constructor (PredictModel) 11 | CameraCaptureModel() 12 | : m_vCapture(0) 13 | { 14 | // empty 15 | } 16 | 17 | CameraCaptureModel(const std::string src_) 18 | : m_vCapture(0), 19 | m_Predict(src_) 20 | { 21 | // empty 22 | } 23 | 24 | void openCamera() 25 | { 26 | if (!m_vCapture.isOpened()) { 27 | std::cerr << "VideoCapture construct error!" << std::endl; 28 | exit(1); 29 | } 30 | 31 | while (1) { 32 | m_vCapture >> m_mFrame; 33 | if (m_mFrame.empty()) { 34 | std::cerr << "New frame is empty" << std::endl; 35 | exit(1); 36 | } 37 | 38 | imshow("MyPicture", m_mFrame); 39 | 40 | cv::cvtColor(m_mFrame, m_mGray, CV_BGR2GRAY); 41 | 42 | cv::resize(m_mGray, m_mEdge, cv::Size(92, 112), 0, 0, CV_INTER_LINEAR); 43 | 44 | m_Predict.prediction(m_mEdge); 45 | 46 | char c = cv::waitKey(100); 47 | if (c == 27) { // Esc推出程序 48 | break; 49 | } 50 | } 51 | } 52 | 53 | private: 54 | cv::VideoCapture m_vCapture; 55 | cv::Mat m_mFrame; 56 | cv::Mat m_mEdge; 57 | cv::Mat m_mGray; 58 | PredictModel m_Predict; 59 | }; 60 | 61 | #endif // !CAMERACAPTUREMODEL_H__ 62 | -------------------------------------------------------------------------------- /Face_Recognize/C++/src/DatabaseModel.h: -------------------------------------------------------------------------------- 1 | #ifndef SRC_DATABASE_DATABASEMODEL_H__ 2 | #define SRC_DATABASE_DATABASEMODEL_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | class DataBaseModel : boost::noncopyable 10 | { 11 | public: 12 | explicit DataBaseModel( 13 | const std::string& host_, 14 | const std::string& user_, 15 | const std::string& pwd_, 16 | const std::string& database_, 17 | unsigned int port_ = 3306) 18 | : m_sHost(host_), m_sUser(user_), m_sPasswd(pwd_), m_sDatabase(database_), m_uiPort(port_) 19 | { 20 | initConnect(); 21 | } 22 | 23 | // 由于专门针对的数据库,所以这里做了特别处理 24 | MYSQL_ROW query(const std::string& query_string) 25 | { 26 | MYSQL_RES* result; 27 | MYSQL_ROW sql_row; 28 | 29 | unsigned int num_fields; 30 | unsigned int num_rows; 31 | 32 | if (!mysql_query(&m_Mysql, query_string.c_str())) { 33 | // Call mysql_store_result() and gotten back a result that is not a null pointer 34 | // 35 | result = mysql_store_result(&m_Mysql); 36 | num_rows = mysql_num_rows(result); 37 | 38 | if (result && num_rows >= 1) { 39 | // Find out how many rows are in the result set. 40 | // 41 | num_fields = mysql_num_fields(result); 42 | 43 | if ((sql_row = mysql_fetch_row(result))) { 44 | mysql_free_result(result); 45 | return sql_row; 46 | } 47 | } 48 | else { 49 | if (mysql_errno(&m_Mysql)) { 50 | std::cerr << "Error: " << mysql_error(&m_Mysql) << std::endl; 51 | } 52 | else if (mysql_field_count(&m_Mysql) == 0) { 53 | // query does not return data 54 | // (it was not a SELECT) 55 | num_rows = mysql_affected_rows(&m_Mysql); 56 | // ... 57 | } 58 | else if (num_rows == 0) { 59 | std::cout << "No data!" << std::endl; 60 | } 61 | } 62 | } 63 | else { 64 | std::cout << "query sql failed!" << std::endl; 65 | return NULL; 66 | } 67 | } 68 | 69 | 70 | private: 71 | void initConnect() 72 | { 73 | mysql_init(&m_Mysql); 74 | 75 | //mysql_options() 76 | 77 | if (!mysql_real_connect( 78 | &m_Mysql, 79 | m_sHost.c_str(), m_sUser.c_str(), m_sPasswd.c_str(), m_sDatabase.c_str(), 80 | m_uiPort, nullptr, 0)) 81 | { 82 | std::cerr << "Failed to connect to database: Error: " << mysql_error(&m_Mysql) << std::endl; 83 | // exception handler 84 | } 85 | else { 86 | // zero for success. Nonzero if an error eccurred. 87 | if (mysql_query(&m_Mysql, "SET NAMES GBK")) { 88 | std::cerr << "Failed to query: Error: " << mysql_error(&m_Mysql) << std::endl; 89 | // exception handler 90 | } 91 | } 92 | } 93 | 94 | private: 95 | MYSQL m_Mysql; 96 | std::string m_sHost; 97 | std::string m_sUser; 98 | std::string m_sPasswd; 99 | std::string m_sDatabase; 100 | unsigned int m_uiPort; 101 | }; 102 | 103 | #endif // !SRC_DATABASE_DATABASEMODEL_H__ 104 | -------------------------------------------------------------------------------- /Face_Recognize/C++/src/PredictModel.h: -------------------------------------------------------------------------------- 1 | #ifndef SRC_PREDICTMODEL_H__ 2 | #define SRC_PREDICTMODEL_H__ 3 | 4 | #include "UserCenterModel.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | using namespace cv::face; 14 | 15 | class PredictModel : boost::noncopyable 16 | { 17 | public: 18 | PredictModel( 19 | const std::string& src = "", 20 | const std::string& mapfile = "information.txt", 21 | const std::string& xml = "MyFaceEigen.xml") 22 | : m_sFilename(src), m_pfModel(createEigenFaceRecognizer()) 23 | { 24 | if (m_mMap.empty()) { 25 | initMap(mapfile); 26 | } 27 | 28 | m_pfModel->load(xml); 29 | 30 | } 31 | 32 | void initMap(const std::string& information, const std::string& pattern_ = ";") 33 | { 34 | // Open csv file and put the data into the relevent container. 35 | // 36 | FILE* fp = fopen(information.c_str(), "r"); 37 | char szTest[100] = { 0 }; 38 | while (fgets(szTest, sizeof(szTest), fp)) { 39 | char* label = strtok(szTest, pattern_.c_str()); 40 | char* name = strtok(NULL, pattern_.c_str()); 41 | if (sizeof(label) != 0 && sizeof(name) != 00) { 42 | m_mMap.insert( 43 | std::make_pair( 44 | atoi(label), 45 | name 46 | ) 47 | ); 48 | } 49 | } 50 | } 51 | 52 | void loadXml(const std::string& xml_) 53 | { 54 | m_pfModel->load(xml_); 55 | } 56 | 57 | void loadImage(const std::string& filename_) 58 | { 59 | m_sFilename = filename_; 60 | } 61 | 62 | void prediction() 63 | { 64 | if (m_sFilename.empty()) { 65 | std::cout << "No images loaded" << std::endl; 66 | } 67 | else { 68 | cv::Mat img = cv::imread(m_sFilename, CV_LOAD_IMAGE_GRAYSCALE); 69 | int predicted = m_pfModel->predict(img); 70 | try 71 | { 72 | m_upUser = std::make_unique(); 73 | m_upUser->setUsername(m_mMap[predicted]); 74 | m_upUser->queryUser(); 75 | m_upUser->showUser(); 76 | } 77 | catch (const std::exception& e) 78 | { 79 | std::cerr << e.what() << std::endl; 80 | } 81 | 82 | } 83 | } 84 | 85 | void prediction(cv::Mat& img_) 86 | { 87 | int predicted = m_pfModel->predict(img_); 88 | 89 | try 90 | { 91 | m_upUser = std::make_unique(); 92 | m_upUser->setUsername(m_mMap[predicted]); 93 | m_upUser->queryUser(); 94 | m_upUser->showUser(); 95 | } 96 | catch (const std::exception& e) 97 | { 98 | std::cerr << e.what() << std::endl; 99 | } 100 | 101 | } 102 | 103 | private: 104 | std::string m_sFilename; 105 | cv::Ptr m_pfModel; 106 | std::map m_mMap; 107 | std::unique_ptr m_upUser; 108 | }; 109 | 110 | #endif // !SRC_PREDICTMODEL_H__ 111 | -------------------------------------------------------------------------------- /Face_Recognize/C++/src/TrainningModel.h: -------------------------------------------------------------------------------- 1 | #ifndef SRC_TRAININGMODEL_H__ 2 | #define SRC_TRAININGMODEL_H__ 3 | 4 | //#include "PredictModel.h" 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | using namespace cv::face; 15 | 16 | class TrainningModel : boost::noncopyable/*, public Predict*/ 17 | { 18 | public: 19 | explicit TrainningModel( 20 | const std::string& filename_, 21 | const std::string& mapfile = "information.txt") : m_sFilename(filename_) 22 | { 23 | initMap(mapfile); 24 | } 25 | 26 | /* 27 | TrainningModel() = delete; 28 | TrainningModel(const TrainningModel&) = delete; 29 | TrainningModel& operator=(const TrainningModel&) = delete; 30 | */ 31 | 32 | void read_csv(const std::string& pattern_ = ";") 33 | { 34 | // Open csv file and put the data into the relevent container. 35 | // 36 | std::fstream fstrm(m_sFilename, std::ios::in | std::ios::binary | std::ios::ate); 37 | if (!fstrm.is_open()) { 38 | std::string error_message = "File read failed (One param): No file named " + m_sFilename; 39 | CV_Error(CV_StsInternal, error_message); 40 | } 41 | else { 42 | auto size = fstrm.tellg(); 43 | std::string allStr(size, '\0'); 44 | // Read back to the beginning 45 | // 46 | fstrm.seekg(0); 47 | if (fstrm.read(&allStr[0], size)) { 48 | std::istringstream toReadOL(allStr); 49 | // Read every line 50 | // 51 | for(std::array a; toReadOL.getline(&a[0], 100, '\n'); ) { 52 | // Being String split by pattern_ 53 | std::string tmpStr = &a[0]; 54 | size_t pos = tmpStr.find(pattern_); 55 | size_t size = tmpStr.size(); 56 | 57 | // Cutting is done. Check if get to the end of file. 58 | if (pos != std::string::npos) { 59 | // holds images and labels 60 | m_vMImages.push_back(cv::imread(tmpStr.substr(0, pos), 0)); 61 | m_vILabels.push_back(std::stoi(tmpStr.substr(pos + 1, size))); 62 | } 63 | } 64 | } 65 | 66 | // End read 67 | } 68 | 69 | if (m_vMImages.size() <= 1) { 70 | std::string error_message = "The number of images is insufficient"; 71 | CV_Error(CV_BadImageSize, error_message); 72 | } 73 | } 74 | 75 | void read_csv(const std::string& filename_, const std::string& pattern_ = ";") 76 | { 77 | // Update the filename 78 | m_sFilename = filename_; 79 | 80 | // Open csv file and put the data into the relevent container. 81 | // 82 | std::fstream fstrm(m_sFilename, std::ios::in | std::ios::binary | std::ios::ate); 83 | if (!fstrm.is_open()) { 84 | std::string error_message = "File read failed (One param): No file named " + m_sFilename; 85 | CV_Error(CV_StsInternal, error_message); 86 | } 87 | else { 88 | auto size = fstrm.tellg(); 89 | std::string allStr(size, '\0'); 90 | // Read back to the beginning 91 | // 92 | fstrm.seekg(0); 93 | if (fstrm.read(&allStr[0], size)) { 94 | std::istringstream toReadOL(allStr); 95 | // Read every line 96 | // 97 | for (std::array a; toReadOL.getline(&a[0], 100, '\n'); ) { 98 | // Being String split by pattern_ 99 | std::string tmpStr = &a[0]; 100 | size_t pos = tmpStr.find(pattern_); 101 | size_t size = tmpStr.size(); 102 | 103 | // Cutting is done. Check if get to the end of file. 104 | if (pos != std::string::npos) { 105 | // holds images and labels 106 | m_vMImages.push_back(cv::imread(tmpStr.substr(0, pos), 0)); 107 | m_vILabels.push_back(std::stoi(tmpStr.substr(pos + 1, size))); 108 | } 109 | } 110 | } 111 | 112 | // End read 113 | } 114 | 115 | if (m_vMImages.size() <= 1) { 116 | std::string error_message = "The number of images is insufficient"; 117 | CV_Error(CV_BadImageSize, error_message); 118 | } 119 | } 120 | 121 | std::pair, std::vector> read_csv_p( 122 | const std::string& filename_, const std::string& pattern_ = ";") 123 | { 124 | std::vector newImages; 125 | std::vector newLabels; 126 | // Open csv file and put the data into the relevent container. 127 | // 128 | std::fstream fstrm(m_sFilename, std::ios::in | std::ios::binary | std::ios::ate); 129 | if (!fstrm.is_open()) { 130 | std::string error_message = "File read failed (One param): No file named " + m_sFilename; 131 | CV_Error(CV_StsInternal, error_message); 132 | } 133 | else { 134 | auto size = fstrm.tellg(); 135 | std::string allStr(size, '\0'); 136 | // Read back to the beginning 137 | // 138 | fstrm.seekg(0); 139 | if (fstrm.read(&allStr[0], size)) { 140 | std::istringstream toReadOL(allStr); 141 | // Read every line 142 | // 143 | for (std::array a; toReadOL.getline(&a[0], 100, '\n'); ) { 144 | // Being String split by pattern_ 145 | std::string tmpStr = &a[0]; 146 | size_t pos = tmpStr.find(pattern_); 147 | size_t size = tmpStr.size(); 148 | 149 | // Cutting is done. Check if get to the end of file. 150 | if (pos != std::string::npos) { 151 | // holds images and labels 152 | newImages.push_back(cv::imread(tmpStr.substr(0, pos), 0)); 153 | newLabels.push_back(std::stoi(tmpStr.substr(pos + 1, size))); 154 | } 155 | } 156 | } 157 | 158 | // End read 159 | } 160 | 161 | if (newImages.size() <= 1) { 162 | std::string error_message = "The number of images is insufficient"; 163 | CV_Error(CV_BadImageSize, error_message); 164 | } 165 | 166 | return std::make_pair(newImages, newLabels); 167 | } 168 | 169 | void train() 170 | { 171 | trainEigen(); 172 | trainFisher(); 173 | trainLBPH(); 174 | } 175 | 176 | void trainEigen(const std::string& savefilename_ = "MyFaceEigen.xml") 177 | { 178 | if (m_pfEigenModel.empty()) { 179 | m_pfEigenModel = createEigenFaceRecognizer(); 180 | m_pfEigenModel->train(m_vMImages, m_vILabels); 181 | //m_pfEigenModel->save(savefilename_); 182 | save(m_pfEigenModel, savefilename_); 183 | } 184 | } 185 | 186 | void trainFisher(const std::string& savefilename_ = "MyFaceFisher.xml") 187 | { 188 | if (m_pfFisherModel.empty()) { 189 | m_pfFisherModel = createFisherFaceRecognizer(); 190 | m_pfFisherModel->train(m_vMImages, m_vILabels); 191 | //m_pfFisherModel->save(savefilename_); 192 | save(m_pfFisherModel, savefilename_); 193 | } 194 | } 195 | 196 | void trainLBPH(const std::string& savefilename_ = "MyFaceLBPH.xml") 197 | { 198 | if (m_pfLBPHModel.empty()) { 199 | m_pfLBPHModel = createLBPHFaceRecognizer(); 200 | m_pfLBPHModel->train(m_vMImages, m_vILabels); 201 | //m_pfLBPHModel->save(savefilename_); 202 | save(m_pfLBPHModel, savefilename_); 203 | } 204 | } 205 | 206 | // Only createLBPHFaceRecognizer model supports updating 207 | // 208 | //void update(const std::string& filename_, const std::string& savefilename_ = "MyFaceLBPH.xml", const std::string& pattern_ = ";") 209 | //{ 210 | // if (m_pfLBPHModel.empty()) { 211 | // m_pfLBPHModel = createLBPHFaceRecognizer(); 212 | // } 213 | // auto new_container = read_csv_p(filename_, pattern_); 214 | // m_pfLBPHModel->update(new_container.first, new_container.second); 215 | // //m_pfLBPHModel->save(savefilename_); 216 | // save(m_pfLBPHModel, savefilename_); 217 | //} 218 | 219 | // 暂时只提供Eigen预测,等我想到如何解决不同算法参数的设置的时候在回来改这段代码 220 | void predict(const std::string& src) 221 | { 222 | // Read in a sample image: 223 | cv::Mat img = cv::imread(src, CV_LOAD_IMAGE_GRAYSCALE); 224 | 225 | // And get a prediction from cv::FaceRecognizer 226 | predicted = m_pfEigenModel->predict(img); 227 | /*std::cout << predicted << std::endl;*/ 228 | } 229 | 230 | // If predicted is already trained. 231 | const std::string predictToName() 232 | { 233 | return m_mMap[predicted]; 234 | } 235 | 236 | const std::string predictToName(const std::string& src) 237 | { 238 | // Read in a sample image: 239 | cv::Mat img = cv::imread(src, CV_LOAD_IMAGE_GRAYSCALE); 240 | 241 | // And get a prediction from cv::FaceRecognizer 242 | predicted = m_pfEigenModel->predict(img); 243 | return m_mMap[predicted]; 244 | } 245 | 246 | void predict(const std::string& src, int& label, double& confidence) 247 | { 248 | // Read in a sample image: 249 | cv::Mat img = cv::imread(src, CV_LOAD_IMAGE_GRAYSCALE); 250 | 251 | // Get the prediction and associated confidence from the model 252 | m_pfEigenModel->predict(img, label, confidence); 253 | } 254 | 255 | inline void save(cv::Ptr& ptrFR_, const std::string& savefilename_) 256 | { 257 | ptrFR_->save(savefilename_); 258 | } 259 | 260 | void initMap(const std::string& information, const std::string& pattern_ = ";") 261 | { 262 | // Open csv file and put the data into the relevent container. 263 | // 264 | FILE* fp = fopen(information.c_str(), "r"); 265 | char szTest[100] = { 0 }; 266 | while (fgets(szTest, sizeof(szTest), fp)) { 267 | char* label = strtok(szTest, pattern_.c_str()); 268 | char* name = strtok(NULL, pattern_.c_str()); 269 | if (sizeof(label) != 0 && sizeof(name) != 00) { 270 | m_mMap.insert( 271 | std::make_pair( 272 | atoi(label), 273 | name 274 | ) 275 | ); 276 | } 277 | } 278 | } 279 | 280 | private: 281 | int predicted; // predictive value 282 | std::string m_sFilename; // csv file 283 | std::vector m_vMImages; // relevant container 284 | std::vector m_vILabels; 285 | cv::Ptr m_pfEigenModel; 286 | cv::Ptr m_pfFisherModel; 287 | cv::Ptr m_pfLBPHModel; 288 | std::map m_mMap; 289 | }; 290 | 291 | #endif // !SRC_TRAININGMODEL_H__ 292 | -------------------------------------------------------------------------------- /Face_Recognize/C++/src/UserCenterModel.h: -------------------------------------------------------------------------------- 1 | #ifndef SRC_USERCENTERMODEL_H__ 2 | #define SRC_USERCENTERMODEL_H__ 3 | 4 | #include "DatabaseModel.h" 5 | #include 6 | #include 7 | 8 | template 9 | auto CheckIfNull(T t) 10 | { 11 | return t == nullptr ? "" : t; 12 | } 13 | 14 | class UserCenterModel 15 | { 16 | public: 17 | UserCenterModel(const std::string& name_ = "") : 18 | m_sUsername(name_), 19 | m_dbMysql("数据库地址", "数据库用户名", "数据库密码", "数据库表"), 20 | fmt("SQL语句") 21 | { 22 | // empty 23 | } 24 | 25 | void queryUser() 26 | { 27 | if (!m_sUsername.empty()) { 28 | fmt % m_sUsername; 29 | 30 | m_mSql_row = m_dbMysql.query(fmt.str()); 31 | 32 | m_sStudentId = CheckIfNull(m_mSql_row[0]); 33 | m_sName = CheckIfNull(m_mSql_row[1]); 34 | m_sType = CheckIfNull(m_mSql_row[2]); 35 | m_sAdmissionTime = CheckIfNull(m_mSql_row[3]); 36 | m_sIDcard = CheckIfNull(m_mSql_row[4]); 37 | m_sSex = CheckIfNull(m_mSql_row[5]); 38 | m_sBirthday = CheckIfNull(m_mSql_row[6]); 39 | m_sNativeplace = CheckIfNull(m_mSql_row[7]); 40 | m_sTelephone = CheckIfNull(m_mSql_row[8]); 41 | m_sBedroom = CheckIfNull(m_mSql_row[9]); 42 | m_sQQ = CheckIfNull(m_mSql_row[10]); 43 | } 44 | } 45 | 46 | void showUser() 47 | { 48 | if (!m_sUsername.empty()) { 49 | std::cout << "m_sStudentId :" << m_sStudentId << std::endl; 50 | std::cout << "m_sName :" << m_sName << std::endl; 51 | std::cout << "m_sType :" << m_sType << std::endl; 52 | std::cout << "m_sAdmissionTime :" << m_sAdmissionTime << std::endl; 53 | std::cout << "m_sIDcard :" << m_sIDcard << std::endl; 54 | std::cout << "m_sSex :" << m_sSex << std::endl; 55 | std::cout << "m_sBirthday :" << m_sBirthday << std::endl; 56 | std::cout << "m_sNativeplace :" << m_sNativeplace << std::endl; 57 | std::cout << "m_sTelephone :" << m_sTelephone << std::endl; 58 | std::cout << "m_sBedroom :" << m_sBedroom << std::endl; 59 | std::cout << "m_sQQ :" << m_sQQ << std::endl; 60 | std::cout << std::endl; 61 | } 62 | } 63 | 64 | void setUsername(const std::string& username_) 65 | { 66 | m_sUsername = username_; 67 | } 68 | 69 | const std::string Id() const 70 | { 71 | return m_sStudentId; 72 | } 73 | 74 | const std::string Name() const 75 | { 76 | return m_sName; 77 | } 78 | 79 | const std::string Type() const 80 | { 81 | return m_sType; 82 | } 83 | 84 | const std::string Admission() const 85 | { 86 | return m_sAdmissionTime; 87 | } 88 | 89 | const std::string Idcard() const 90 | { 91 | return m_sIDcard; 92 | } 93 | 94 | const std::string Sex() const 95 | { 96 | return m_sSex; 97 | } 98 | 99 | const std::string Birthday() const 100 | { 101 | return m_sBirthday; 102 | } 103 | 104 | const std::string Native() const 105 | { 106 | return m_sNativeplace; 107 | } 108 | 109 | const std::string Telephone() const 110 | { 111 | return m_sTelephone; 112 | } 113 | 114 | const std::string Bedroom() const 115 | { 116 | return m_sBedroom; 117 | } 118 | 119 | const std::string QQ() const 120 | { 121 | return m_sQQ; 122 | } 123 | 124 | private: 125 | std::string m_sUsername; 126 | 127 | std::string m_sStudentId; // 学号 128 | std::string m_sName; // 姓名 129 | std::string m_sType; // 学生类别 130 | std::string m_sAdmissionTime; // 入学年月 131 | std::string m_sIDcard; // 身份号 132 | std::string m_sSex; // 性别 133 | std::string m_sBirthday; // 出生年月 134 | std::string m_sNativeplace; // 籍贯 135 | std::string m_sTelephone; // 手机号码 136 | std::string m_sBedroom; // 寝室号 137 | std::string m_sQQ; // qq号 138 | DataBaseModel m_dbMysql; // 数据库 139 | boost::format fmt; // 搜索匹配字符 140 | MYSQL_ROW m_mSql_row; 141 | 142 | }; 143 | 144 | #endif // !SRC_USERCENTERMODEL_H__ 145 | -------------------------------------------------------------------------------- /Face_Recognize/C++/tools/camera.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace cv; 4 | using namespace std; 5 | 6 | int main(int argc, char const *argv[]) 7 | { 8 | // 创建VideoCapture对象,打开默认摄像机 9 | VideoCapture capture(0); 10 | // 检查是否打开摄像头 11 | if (!capture.isOpened()) { 12 | cerr << "VideoCapture construct error!" << endl; 13 | exit(1); 14 | } 15 | 16 | Mat dst; 17 | Mat frame; 18 | Mat changeframe; 19 | int i = 1; 20 | while (1) { 21 | // 从摄像机中获取一个新的框架 22 | capture >> frame; 23 | if (frame.empty()) { 24 | cerr << "New frame is empty" << endl; 25 | exit(1); 26 | } 27 | 28 | // 显示灰度图 29 | imshow("MyPicture", frame); 30 | 31 | // 转为灰度图 32 | cvtColor(frame, changeframe, CV_BGR2GRAY); 33 | 34 | // 改变图片大小 35 | resize(changeframe, dst, Size(92, 112), 0, 0, INTER_LINEAR); 36 | char c = waitKey(100); 37 | if (c == 97) { // 'a'开始拍照 38 | ++i; 39 | string filename = format("%d.jpg", i); // 定义图片存储的位置 40 | imwrite(filename, dst); // 保存灰度图 41 | } 42 | else if (c == 27) { // Esc推出程序 43 | break; 44 | } 45 | } 46 | 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /Face_Recognize/C++/tools/create_csv_file.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | using namespace boost; 6 | 7 | int main(int argc, char const *argv[]) 8 | { 9 | cout << "Please input filename: "; 10 | string filename; 11 | cin >> filename; 12 | fstream s(filename, ios::out | ios::trunc); 13 | 14 | if (!s.is_open()) { 15 | cout << "failed to open " << filename << endl; 16 | } 17 | else { 18 | format fmt("E:/WorkFor2017/ML/test_image/att_faces/s%d/%d.pgm;%d\n"); 19 | for(int i = 1; i <= 41; ++i) { 20 | for(int j = 1; j <= 10; ++j) { 21 | fmt %i %j %(i-1); 22 | s << fmt; 23 | } 24 | } 25 | } 26 | s.close(); 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /Face_Recognize/Python/tools/camera.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: UTF-8 -*- 3 | 4 | import cv2 5 | 6 | def camera(): 7 | capture = cv2.VideoCapture(0) 8 | index = 1 9 | while capture.isOpened(): 10 | # 返回一个元组,value和image,value用来检查是否读入成功 11 | ok, frame = capture.read() 12 | if not ok: 13 | break; 14 | else: 15 | cv2.imshow("MyPicture", frame) 16 | gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) 17 | # cv2.imshow("MyPicture", gray) 18 | dst = cv2.resize(gray, (92, 112)); 19 | c = cv2.waitKey(100) 20 | if c & 0xFF == ord('q'): # q退出 21 | break; 22 | elif c & 0xFF == ord('a'): # a拍照 23 | filename = '%d.pgm' % index 24 | index += 1 25 | cv2.imwrite(filename, dst) 26 | else: 27 | continue 28 | capture.release() 29 | cv2.destroyAllWindows() 30 | 31 | if __name__ == '__main__': 32 | camera() 33 | -------------------------------------------------------------------------------- /Face_Recognize/Python/tools/createFile.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: UTF-8 -*- 3 | 4 | def createFile(): 5 | # Information 6 | info = 'E:/WorkFor2017/ML/test_image/att_faces/s{0}/{1}.pgm;{2}\n' 7 | 8 | # Input filename 9 | filename = input('Enter file name: ') 10 | 11 | fp = open(filename, 'w') 12 | 13 | for i in range(1, 42): 14 | for j in range(1, 11): 15 | fp.write(info.format(i, j, i-1)) 16 | 17 | fp.close() 18 | 19 | if __name__ == '__main__': 20 | createFile() 21 | -------------------------------------------------------------------------------- /MachineLearning/decision_tree/C4.5/C4.5.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ======================================== 3 | * @Author = xefvan 4 | * @Remark = C4.5 5 | * @Version = 1.0 6 | * @DateTime = 2017-09-16 21:31:03 7 | * ======================================== 8 | */ 9 | 10 | #include "require.h" 11 | #include "decisionstructure.h" 12 | #include 13 | #include 14 | #include 15 | 16 | // C4.5决策算法 -- 西瓜决策树 17 | TreeRoot TreeGenerate(TreeRoot pTree, 18 | std::vector datas, // 训练集 19 | std::vector attributes, // 属性集 20 | std::map> map_attr) 21 | { 22 | if (belongs_same_label(datas, "yes")) { 23 | // All samples are positive. 24 | pTree->attribute = "yes"; 25 | return pTree; 26 | } 27 | else if (belongs_same_label(datas, "no")) { 28 | // All samples are negative. 29 | pTree->attribute = "no"; 30 | return pTree; 31 | } 32 | else { 33 | if (attributes.empty()) { 34 | pTree->attribute = majority_of_category(datas); 35 | return pTree; 36 | } 37 | else { 38 | std::pair> optimal_attrs = \ 39 | optimal_attribute(datas, attributes, map_attr); 40 | pTree->attribute = optimal_attrs.first; 41 | for (auto aptimal_attr : optimal_attrs.second) { 42 | Node* new_node = new Node(); 43 | new_node->edgeValue = aptimal_attr; 44 | 45 | std::vector new_datas = remain_watermelon_datas( 46 | datas, aptimal_attr, optimal_attrs.first); 47 | if (new_datas.empty()) { 48 | new_node->attribute = majority_of_category(datas); 49 | // return pTree; 50 | } 51 | else { 52 | std::vector new_attributes; 53 | for (auto train_attribute : attributes) { 54 | if (train_attribute.compare(optimal_attrs.first)) { 55 | new_attributes.push_back(train_attribute); 56 | } 57 | } 58 | TreeGenerate(new_node, new_datas, new_attributes, map_attr); 59 | } 60 | 61 | pTree->childs.push_back(new_node); 62 | } 63 | } 64 | } 65 | 66 | return pTree; 67 | } 68 | 69 | int main(int argc, char const *argv[]) 70 | { 71 | std::vector datas; 72 | std::vector attributes; 73 | std::vector train_attributes; 74 | 75 | train_attributes.push_back("color"); 76 | train_attributes.push_back("pedicle"); 77 | train_attributes.push_back("sound"); 78 | train_attributes.push_back("texture"); 79 | train_attributes.push_back("umbilical"); 80 | train_attributes.push_back("touch"); 81 | 82 | // load the datas and attributes.. 83 | // 84 | load_file(datas, attributes, "watermelondatas.txt"); 85 | 86 | std::map> map_attr; 87 | 88 | // match attribute set.. 89 | // 90 | match_properties(datas, attributes, map_attr); 91 | 92 | TreeRoot pTree = new Node(); 93 | pTree = TreeGenerate(pTree, datas, train_attributes, map_attr); 94 | print_tree(pTree, 0); 95 | 96 | 97 | return 0; 98 | } 99 | -------------------------------------------------------------------------------- /MachineLearning/decision_tree/C4.5/decisionstructure.h: -------------------------------------------------------------------------------- 1 | #ifndef DECISIONSTRUCTURE_H__ 2 | #define DECISIONSTRUCTURE_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | // 西瓜个体定义 9 | class Watermelon 10 | { 11 | public: 12 | std::string id; // 编号 13 | std::string color; // 颜色 14 | std::string pedicle; // 根蒂 15 | std::string sound; // 声音 16 | std::string texture; // 纹理 17 | std::string umbilical; // 脐部 18 | std::string touch; // 触感 19 | std::string good; // 好瓜? 20 | 21 | friend 22 | std::ostream& operator<<(std::ostream& os, const Watermelon& wm) 23 | { 24 | os << wm.id << " " << wm.color << " " << wm.pedicle << " " 25 | << wm.sound << " " << wm.texture << " " << wm.umbilical << " " 26 | << wm.touch << " " << wm.good; 27 | os << std::endl; 28 | return os; 29 | } 30 | }; 31 | 32 | struct Node 33 | { 34 | std::string attribute; 35 | std::string edgeValue; 36 | std::vector childs; 37 | Node() : attribute(""), edgeValue("") { } 38 | }; 39 | 40 | template 41 | using Ptr = T*; 42 | using TreeRoot = Ptr; 43 | 44 | #endif // DECISIONSTRUCTURE_H__ 45 | -------------------------------------------------------------------------------- /MachineLearning/decision_tree/C4.5/require.h: -------------------------------------------------------------------------------- 1 | #ifndef REQUIRE_H__ 2 | #define REQUIRE_H__ 3 | 4 | #include "decisionstructure.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | inline void assure(std::ifstream& in, 19 | const std::string& filename = "") 20 | { 21 | using namespace std; 22 | if (!in) { 23 | fprintf(stderr, "Could not open file: %s\n", filename.c_str()); 24 | exit(1); 25 | } 26 | } 27 | 28 | inline void assure(std::ofstream& out, 29 | const std::string& filename = "") 30 | { 31 | using namespace std; 32 | if (!out) { 33 | fprintf(stderr, "Could not open file: %s\n", filename.c_str()); 34 | } 35 | } 36 | 37 | void load_file(std::vector& datas, 38 | std::vector& attributes, 39 | const std::string& filename) 40 | { 41 | std::ifstream istrm(filename); 42 | assure(istrm, filename); 43 | 44 | if (istrm.is_open()) { 45 | char buffer[128]; 46 | bool firstline = true; 47 | while (!istrm.eof()) { 48 | istrm.getline(buffer, 128); 49 | const char* id = strtok(buffer, " "); 50 | const char* color = strtok(NULL, " "); 51 | const char* pedicle = strtok(NULL, " "); 52 | const char* sound = strtok(NULL, " "); 53 | const char* texture = strtok(NULL, " "); 54 | const char* umbilical = strtok(NULL, " "); 55 | const char* touch = strtok(NULL, " "); 56 | const char* good = strtok(NULL, " "); 57 | 58 | // Check if the first line. 59 | // The first line contains attributes of datas. 60 | // 61 | if (firstline) { 62 | attributes.push_back(std::string(id)); 63 | attributes.push_back(std::string(color)); 64 | attributes.push_back(std::string(pedicle)); 65 | attributes.push_back(std::string(sound)); 66 | attributes.push_back(std::string(texture)); 67 | attributes.push_back(std::string(umbilical)); 68 | attributes.push_back(std::string(touch)); 69 | attributes.push_back(std::string(good)); 70 | firstline = false; 71 | } 72 | else { 73 | Watermelon data; 74 | data.id = std::string(id); 75 | data.color = std::string(color); 76 | data.pedicle = std::string(pedicle); 77 | data.sound = std::string(sound); 78 | data.texture = std::string(texture); 79 | data.umbilical = std::string(umbilical); 80 | data.touch = std::string(touch); 81 | data.good = std::string(good); 82 | datas.push_back(data); 83 | } 84 | } 85 | } 86 | } 87 | 88 | void match_properties(std::vector datas, 89 | std::vector attributes, 90 | std::map>& map_attr) 91 | { 92 | int index = 0; 93 | for (auto attribute : attributes) { 94 | std::vector attrTmp; 95 | for (auto data : datas) { 96 | switch (index) { 97 | case 0: 98 | if (!attrTmp.empty() && 99 | std::find(attrTmp.begin(), attrTmp.end(), data.id) == attrTmp.end()) { 100 | attrTmp.push_back(data.id); 101 | } 102 | else if (attrTmp.empty()) { 103 | attrTmp.push_back(data.id); 104 | } 105 | break; 106 | case 1: 107 | if (!attrTmp.empty() && 108 | std::find(attrTmp.begin(), attrTmp.end(), data.color) == attrTmp.end()) { 109 | attrTmp.push_back(data.color); 110 | } 111 | else if (attrTmp.empty()) { 112 | attrTmp.push_back(data.color); 113 | } 114 | break; 115 | case 2: 116 | if (!attrTmp.empty() && 117 | std::find(attrTmp.begin(), attrTmp.end(), data.pedicle) == attrTmp.end()) { 118 | attrTmp.push_back(data.pedicle); 119 | } 120 | else if (attrTmp.empty()) { 121 | attrTmp.push_back(data.pedicle); 122 | } 123 | break; 124 | case 3: 125 | if (!attrTmp.empty() && 126 | std::find(attrTmp.begin(), attrTmp.end(), data.sound) == attrTmp.end()) { 127 | attrTmp.push_back(data.sound); 128 | } 129 | else if (attrTmp.empty()) { 130 | attrTmp.push_back(data.sound); 131 | } 132 | break; 133 | case 4: 134 | if (!attrTmp.empty() && 135 | std::find(attrTmp.begin(), attrTmp.end(), data.texture) == attrTmp.end()) { 136 | attrTmp.push_back(data.texture); 137 | } 138 | else if (attrTmp.empty()) { 139 | attrTmp.push_back(data.texture); 140 | } 141 | break; 142 | case 5: 143 | if (!attrTmp.empty() && 144 | std::find(attrTmp.begin(), attrTmp.end(), data.umbilical) == attrTmp.end()) { 145 | attrTmp.push_back(data.umbilical); 146 | } 147 | else if (attrTmp.empty()) { 148 | attrTmp.push_back(data.umbilical); 149 | } 150 | break; 151 | case 6: 152 | if (!attrTmp.empty() && 153 | std::find(attrTmp.begin(), attrTmp.end(), data.touch) == attrTmp.end()) { 154 | attrTmp.push_back(data.touch); 155 | } 156 | else if (attrTmp.empty()) { 157 | attrTmp.push_back(data.touch); 158 | } 159 | break; 160 | case 7: 161 | if (!attrTmp.empty() && 162 | std::find(attrTmp.begin(), attrTmp.end(), data.good) == attrTmp.end()) { 163 | attrTmp.push_back(data.good); 164 | } 165 | else if (attrTmp.empty()) { 166 | attrTmp.push_back(data.good); 167 | } 168 | break; 169 | default: 170 | break; 171 | } 172 | } 173 | index++; 174 | map_attr[attribute] = attrTmp; 175 | } 176 | } 177 | 178 | bool belongs_same_label(std::vector datas, 179 | std::string label = "yes") 180 | { 181 | if (datas.empty()) { 182 | std::cout << "the datas is empty" << std::endl; 183 | exit(1); 184 | } 185 | 186 | for (auto iter = datas.begin(); iter != datas.end(); ++iter) { 187 | if (iter->good != label) { 188 | return false; 189 | } 190 | } 191 | 192 | return true; 193 | } 194 | 195 | std::string majority_of_category(std::vector datas) 196 | { 197 | int positivecategory = 0; 198 | int negativecategory = 0; 199 | 200 | for (auto data : datas) { 201 | if (data.good == "yes") { 202 | ++positivecategory; 203 | } 204 | else if (data.good == "no") { 205 | ++negativecategory; 206 | } 207 | } 208 | return (positivecategory > negativecategory ? "yes" : "no"); 209 | } 210 | 211 | double calculate_information_entropy(std::vector datas, 212 | std::string mapAttr = "", 213 | std::string attribute = "good") 214 | { 215 | // Ent(D) = -∑(k=1, |Y|) p_k * log2(p_k) 216 | // 217 | int size = 0; 218 | double entropy = 0; 219 | int positive = 0; 220 | int negative = 0; 221 | 222 | // Beacuse of the datas only have two label. 223 | // So entropy = positiveSample + negativeSample 224 | // 225 | if (attribute == "color") { 226 | for (auto data : datas) { 227 | if (data.color == mapAttr) { 228 | if (data.good == "yes") { 229 | ++positive; 230 | } 231 | else { 232 | ++negative; 233 | } 234 | ++size; 235 | } 236 | } 237 | } 238 | else if (attribute == "pedicle") { 239 | for (auto data : datas) { 240 | if (data.pedicle == mapAttr) { 241 | if (data.good == "yes") { 242 | ++positive; 243 | } 244 | else { 245 | ++negative; 246 | } 247 | ++size; 248 | } 249 | } 250 | } 251 | else if (attribute == "sound") { 252 | for (auto data : datas) { 253 | if (data.sound == mapAttr) { 254 | if (data.good == "yes") { 255 | ++positive; 256 | } 257 | else { 258 | ++negative; 259 | } 260 | ++size; 261 | } 262 | } 263 | } 264 | else if (attribute == "texture") { 265 | for (auto data : datas) { 266 | if (data.texture == mapAttr) { 267 | if (data.good == "yes") { 268 | ++positive; 269 | } 270 | else { 271 | ++negative; 272 | } 273 | ++size; 274 | } 275 | } 276 | } 277 | else if (attribute == "umbilical") { 278 | for (auto data : datas) { 279 | if (data.umbilical == mapAttr) { 280 | if (data.good == "yes") { 281 | ++positive; 282 | } 283 | else { 284 | ++negative; 285 | } 286 | ++size; 287 | } 288 | } 289 | } 290 | else if (attribute == "touch") { 291 | for (auto data : datas) { 292 | if (data.touch == mapAttr) { 293 | if (data.good == "yes") { 294 | ++positive; 295 | } 296 | else { 297 | ++negative; 298 | } 299 | ++size; 300 | } 301 | } 302 | } 303 | else if (attribute == "good") { 304 | size = datas.size(); 305 | auto judget = [&](Watermelon wm) { if (wm.good == "yes") { ++positive; } else { ++negative; }}; 306 | for_each(datas.begin(), datas.end(), judget); 307 | } 308 | 309 | if (positive == 0 || negative == 0) { 310 | return 0; 311 | } 312 | else { 313 | entropy = -(((double)positive / size) * log2((double)positive / size) + ((double)negative / size) * log2((double)negative / size)); 314 | } 315 | 316 | return entropy; 317 | } 318 | 319 | double proportion(std::vector& datas, 320 | std::string mapAttr = "", 321 | std::string attribute = "") 322 | { 323 | int size = datas.size(); 324 | double proportion = 0; 325 | 326 | if (attribute == "color") { 327 | for (auto data : datas) { 328 | if (data.color == mapAttr) { 329 | ++proportion; 330 | } 331 | } 332 | } 333 | else if (attribute == "pedicle") { 334 | for (auto data : datas) { 335 | if (data.pedicle == mapAttr) { 336 | ++proportion; 337 | } 338 | } 339 | } 340 | else if (attribute == "sound") { 341 | for (auto data : datas) { 342 | if (data.sound == mapAttr) { 343 | ++proportion; 344 | } 345 | } 346 | } 347 | else if (attribute == "texture") { 348 | for (auto data : datas) { 349 | if (data.texture == mapAttr) { 350 | ++proportion; 351 | } 352 | } 353 | } 354 | else if (attribute == "umbilical") { 355 | for (auto data : datas) { 356 | if (data.umbilical == mapAttr) { 357 | ++proportion; 358 | } 359 | } 360 | } 361 | else if (attribute == "touch") { 362 | for (auto data : datas) { 363 | if (data.touch == mapAttr) { 364 | ++proportion; 365 | } 366 | } 367 | } 368 | 369 | proportion /= size; 370 | 371 | return proportion; 372 | } 373 | 374 | double calculate_information_gain(std::vector& datas, 375 | std::string attribute, 376 | std::map> map_attr) 377 | { 378 | // Gain(D, a) = Ent(D) - ∑(v=1, V) |D^|/|D| * Ent(D) 379 | // 380 | double gain = calculate_information_entropy(datas); 381 | std::vector attrs = map_attr[attribute]; 382 | 383 | for (auto attr : attrs) { 384 | gain -= proportion(datas, attr, attribute) * calculate_information_entropy(datas, attr, attribute); 385 | } 386 | 387 | return gain; 388 | } 389 | 390 | double calculate_information_gain_ratio(std::vector& datas, 391 | std::string attribute, 392 | std::map> map_attr) 393 | { 394 | // Gain_ratio(D, a) = Gain(D, a) / IV(a) 395 | // 396 | double gain = calculate_information_gain(datas, attribute, map_attr); 397 | 398 | double iv = 0; 399 | std::vector attrs = map_attr[attribute]; 400 | for (auto attr : attrs) { 401 | iv -= proportion(datas, attr, attribute) * log2(proportion(datas, attr, attribute)); 402 | } 403 | 404 | double gain_ratio = gain / iv; 405 | 406 | return gain_ratio; 407 | } 408 | 409 | std::pair> optimal_attribute(std::vector& datas, 410 | std::vector& attributes, 411 | std::map> map_attr) 412 | { 413 | std::map map_gains; 414 | std::map map_gains_ratio; 415 | for (auto attribute : attributes) { 416 | map_gains[attribute] = calculate_information_gain(datas, attribute, map_attr); 417 | map_gains_ratio[attribute] = calculate_information_gain_ratio(datas, attribute, map_attr); 418 | } 419 | 420 | // Sort the information gain and select the attribute of the maximum 421 | // information gain.The biggest value is in the first. 422 | // 423 | std::vector> vec_map_gains(map_gains.begin(), map_gains.end()); 424 | std::vector> vec_map_gains_ratios(map_gains_ratio.begin(), map_gains_ratio.end()); 425 | auto compare_x_y = [](const std::pair x, const std::pair y) { 426 | return x.second > y.second; 427 | }; 428 | std::sort(vec_map_gains.begin(), vec_map_gains.end(), compare_x_y); 429 | std::sort(vec_map_gains_ratios.begin(), vec_map_gains_ratios.end(), compare_x_y); 430 | 431 | // Find information gain greater than average. 432 | // 433 | std::vector vec_map_gains_name; 434 | int vec_map_gains_size = vec_map_gains.size() / 2; 435 | for (int i = 0; i < vec_map_gains_size; ++i) { 436 | vec_map_gains_name.push_back(vec_map_gains[i].first); 437 | } 438 | 439 | std::string best_attribute; 440 | for (auto vec_map_gains_ratio : vec_map_gains_ratios) { 441 | if (std::find(vec_map_gains_name.begin(), vec_map_gains_name.end(), vec_map_gains_ratio.first) 442 | != vec_map_gains_name.end()) { 443 | best_attribute = vec_map_gains_ratio.first; 444 | break; 445 | } 446 | } 447 | 448 | if (!best_attribute.empty()) { 449 | auto search = map_attr.find(best_attribute); 450 | if (search != map_attr.end()) { 451 | return std::make_pair(search->first, search->second); 452 | } 453 | else { 454 | return std::make_pair(std::string(""), std::vector()); 455 | } 456 | } 457 | else { 458 | return std::make_pair(std::string(""), std::vector()); 459 | } 460 | } 461 | 462 | std::vector remain_watermelon_datas(std::vector datas, 463 | std::string mapAttr, 464 | std::string attribute) 465 | { 466 | std::vector tmp; 467 | 468 | if (attribute == "color") { 469 | for (auto data : datas) { 470 | if (data.color == mapAttr) { 471 | tmp.push_back(data); 472 | } 473 | } 474 | } 475 | else if (attribute == "pedicle") { 476 | for (auto data : datas) { 477 | if (data.pedicle == mapAttr) { 478 | tmp.push_back(data); 479 | } 480 | } 481 | } 482 | else if (attribute == "sound") { 483 | for (auto data : datas) { 484 | if (data.sound == mapAttr) { 485 | tmp.push_back(data); 486 | } 487 | } 488 | } 489 | else if (attribute == "texture") { 490 | for (auto data : datas) { 491 | if (data.texture == mapAttr) { 492 | tmp.push_back(data); 493 | } 494 | } 495 | } 496 | else if (attribute == "umbilical") { 497 | for (auto data : datas) { 498 | if (data.umbilical == mapAttr) { 499 | tmp.push_back(data); 500 | } 501 | } 502 | } 503 | else if (attribute == "touch") { 504 | for (auto data : datas) { 505 | if (data.touch == mapAttr) { 506 | tmp.push_back(data); 507 | } 508 | } 509 | } 510 | 511 | return tmp; 512 | } 513 | 514 | void print_tree(TreeRoot pTree, int depth) 515 | { 516 | for (int i = 0; i < depth; ++i) { 517 | std::cout << '\t'; 518 | } 519 | 520 | if (!pTree->edgeValue.empty()) { 521 | std::cout << "--" << pTree->edgeValue << "--" << std::endl; 522 | for (int i = 0 ; i < depth; ++i) { 523 | std::cout << '\t'; 524 | } 525 | } 526 | 527 | std::cout << pTree->attribute << std::endl; 528 | for (auto child : pTree->childs) { 529 | print_tree(child, depth + 1); 530 | } 531 | } 532 | 533 | #endif // REQUIRE_H__ 534 | -------------------------------------------------------------------------------- /MachineLearning/decision_tree/C4.5/watermelondatas.txt: -------------------------------------------------------------------------------- 1 | id color pedicle sound texture umbilical touch good 2 | 1 darkgreen curled turbid clear sunken hardslip yes 3 | 2 jetblack curled dull clear sunken hardslip yes 4 | 3 jetblack curled turbid clear sunken hardslip yes 5 | 4 darkgreen curled dull clear sunken hardslip yes 6 | 5 lightwhite curled turbid clear sunken hardslip yes 7 | 6 darkgreen slightlycurled turbid clear slightlysunken softsticky yes 8 | 7 jetblack slightlycurled turbid lightblur slightlysunken softsticky yes 9 | 8 jetblack slightlycurled turbid clear slightlysunken hardslip yes 10 | 9 jetblack slightlycurled dull lightblur slightlysunken hardslip no 11 | 10 darkgreen stiffened crisp clear flat softsticky no 12 | 11 lightwhite stiffened crisp blur flat hardslip no 13 | 12 lightwhite curled turbid blur flat softsticky no 14 | 13 darkgreen slightlycurled turbid lightblur sunken hardslip no 15 | 14 lightwhite slightlycurled dull lightblur sunken hardslip no 16 | 15 jetblack slightlycurled turbid clear slightlysunken softsticky no 17 | 16 lightwhite curled turbid blur flat hardslip no 18 | 17 darkgreen curled dull lightblur slightlysunken hardslip no -------------------------------------------------------------------------------- /MachineLearning/decision_tree/ID3/ID3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ======================================== 3 | * @Author = xefvan 4 | * @Remark = TreeGenerate(D, A) 5 | * @Version = 1.0 6 | * @DateTime = 2017-09-06 20:30:44 7 | * ======================================== 8 | */ 9 | 10 | #include "require.h" 11 | #include "decisionstructure.h" 12 | #include 13 | #include 14 | #include 15 | 16 | // ID3决策算法 -- 西瓜决策树 17 | TreeRoot TreeGenerate(TreeRoot pTree, 18 | std::vector datas, // 训练集 19 | std::vector attributes, // 属性集 20 | std::map> map_attr) 21 | { 22 | if (belongs_same_label(datas, "yes")) { 23 | // All samples are positive. 24 | pTree->attribute = "yes"; 25 | return pTree; 26 | } 27 | else if (belongs_same_label(datas, "no")) { 28 | // All samples are negative. 29 | pTree->attribute = "no"; 30 | return pTree; 31 | } 32 | else { 33 | if (attributes.empty()) { 34 | pTree->attribute = majority_of_category(datas); 35 | return pTree; 36 | } 37 | else { 38 | std::pair> optimal_attrs = \ 39 | optimal_attribute(datas, attributes, map_attr); 40 | pTree->attribute = optimal_attrs.first; 41 | for (auto aptimal_attr : optimal_attrs.second) { 42 | Node* new_node = new Node(); 43 | new_node->edgeValue = aptimal_attr; 44 | 45 | std::vector new_datas = remain_watermelon_datas( 46 | datas, aptimal_attr, optimal_attrs.first); 47 | if (new_datas.empty()) { 48 | new_node->attribute = majority_of_category(datas); 49 | // return pTree; 50 | } 51 | else { 52 | std::vector new_attributes; 53 | for (auto train_attribute : attributes) { 54 | if (train_attribute.compare(optimal_attrs.first)) { 55 | new_attributes.push_back(train_attribute); 56 | } 57 | } 58 | TreeGenerate(new_node, new_datas, new_attributes, map_attr); 59 | } 60 | 61 | pTree->childs.push_back(new_node); 62 | } 63 | } 64 | } 65 | 66 | return pTree; 67 | } 68 | 69 | int main(int argc, char const *argv[]) 70 | { 71 | std::vector datas; 72 | std::vector attributes; 73 | std::vector train_attributes; 74 | 75 | train_attributes.push_back("color"); 76 | train_attributes.push_back("pedicle"); 77 | train_attributes.push_back("sound"); 78 | train_attributes.push_back("texture"); 79 | train_attributes.push_back("umbilical"); 80 | train_attributes.push_back("touch"); 81 | 82 | // load the datas and attributes.. 83 | // 84 | load_file(datas, attributes, "watermelondatas.txt"); 85 | 86 | std::map> map_attr; 87 | 88 | // match attribute set.. 89 | // 90 | match_properties(datas, attributes, map_attr); 91 | 92 | TreeRoot pTree = new Node(); 93 | 94 | pTree = TreeGenerate(pTree, datas, train_attributes, map_attr); 95 | 96 | print_tree(pTree, 0); 97 | 98 | 99 | return 0; 100 | } 101 | -------------------------------------------------------------------------------- /MachineLearning/decision_tree/ID3/decisionstructure.h: -------------------------------------------------------------------------------- 1 | #ifndef DECISIONSTRUCTURE_H__ 2 | #define DECISIONSTRUCTURE_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | // 西瓜个体定义 9 | class Watermelon 10 | { 11 | public: 12 | std::string id; // 编号 13 | std::string color; // 颜色 14 | std::string pedicle; // 根蒂 15 | std::string sound; // 声音 16 | std::string texture; // 纹理 17 | std::string umbilical; // 脐部 18 | std::string touch; // 触感 19 | std::string good; // 好瓜? 20 | 21 | friend 22 | std::ostream& operator<<(std::ostream& os, const Watermelon& wm) 23 | { 24 | os << wm.id << " " << wm.color << " " << wm.pedicle << " " 25 | << wm.sound << " " << wm.texture << " " << wm.umbilical << " " 26 | << wm.touch << " " << wm.good; 27 | os << std::endl; 28 | return os; 29 | } 30 | }; 31 | 32 | struct Node 33 | { 34 | std::string attribute; 35 | std::string edgeValue; 36 | std::vector childs; 37 | Node() : attribute(""), edgeValue("") { } 38 | }; 39 | 40 | template 41 | using Ptr = T*; 42 | using TreeRoot = Ptr; 43 | 44 | #endif // DECISIONSTRUCTURE_H__ 45 | -------------------------------------------------------------------------------- /MachineLearning/decision_tree/ID3/require.h: -------------------------------------------------------------------------------- 1 | #ifndef REQUIRE_H__ 2 | #define REQUIRE_H__ 3 | 4 | #include "decisionstructure.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | inline void assure(std::ifstream& in, 19 | const std::string& filename = "") 20 | { 21 | using namespace std; 22 | if (!in) { 23 | fprintf(stderr, "Could not open file: %s\n", filename.c_str()); 24 | exit(1); 25 | } 26 | } 27 | 28 | inline void assure(std::ofstream& out, 29 | const std::string& filename = "") 30 | { 31 | using namespace std; 32 | if (!out) { 33 | fprintf(stderr, "Could not open file: %s\n", filename.c_str()); 34 | } 35 | } 36 | 37 | void load_file(std::vector& datas, 38 | std::vector& attributes, 39 | const std::string& filename) 40 | { 41 | std::ifstream istrm(filename); 42 | assure(istrm, filename); 43 | 44 | if (istrm.is_open()) { 45 | char buffer[128]; 46 | bool firstline = true; 47 | while (!istrm.eof()) { 48 | istrm.getline(buffer, 128); 49 | const char* id = strtok(buffer, " "); 50 | const char* color = strtok(NULL, " "); 51 | const char* pedicle = strtok(NULL, " "); 52 | const char* sound = strtok(NULL, " "); 53 | const char* texture = strtok(NULL, " "); 54 | const char* umbilical = strtok(NULL, " "); 55 | const char* touch = strtok(NULL, " "); 56 | const char* good = strtok(NULL, " "); 57 | 58 | // Check if the first line. 59 | // The first line contains attributes of datas. 60 | // 61 | if (firstline) { 62 | attributes.push_back(std::string(id)); 63 | attributes.push_back(std::string(color)); 64 | attributes.push_back(std::string(pedicle)); 65 | attributes.push_back(std::string(sound)); 66 | attributes.push_back(std::string(texture)); 67 | attributes.push_back(std::string(umbilical)); 68 | attributes.push_back(std::string(touch)); 69 | attributes.push_back(std::string(good)); 70 | firstline = false; 71 | } 72 | else { 73 | Watermelon data; 74 | data.id = std::string(id); 75 | data.color = std::string(color); 76 | data.pedicle = std::string(pedicle); 77 | data.sound = std::string(sound); 78 | data.texture = std::string(texture); 79 | data.umbilical = std::string(umbilical); 80 | data.touch = std::string(touch); 81 | data.good = std::string(good); 82 | datas.push_back(data); 83 | } 84 | } 85 | } 86 | } 87 | 88 | void match_properties(std::vector datas, 89 | std::vector attributes, 90 | std::map>& map_attr) 91 | { 92 | int index = 0; 93 | for (auto attribute : attributes) { 94 | std::vector attrTmp; 95 | for (auto data : datas) { 96 | switch (index) { 97 | case 0: 98 | if (!attrTmp.empty() && 99 | std::find(attrTmp.begin(), attrTmp.end(), data.id) == attrTmp.end()) { 100 | attrTmp.push_back(data.id); 101 | } 102 | else if (attrTmp.empty()) { 103 | attrTmp.push_back(data.id); 104 | } 105 | break; 106 | case 1: 107 | if (!attrTmp.empty() && 108 | std::find(attrTmp.begin(), attrTmp.end(), data.color) == attrTmp.end()) { 109 | attrTmp.push_back(data.color); 110 | } 111 | else if (attrTmp.empty()) { 112 | attrTmp.push_back(data.color); 113 | } 114 | break; 115 | case 2: 116 | if (!attrTmp.empty() && 117 | std::find(attrTmp.begin(), attrTmp.end(), data.pedicle) == attrTmp.end()) { 118 | attrTmp.push_back(data.pedicle); 119 | } 120 | else if (attrTmp.empty()) { 121 | attrTmp.push_back(data.pedicle); 122 | } 123 | break; 124 | case 3: 125 | if (!attrTmp.empty() && 126 | std::find(attrTmp.begin(), attrTmp.end(), data.sound) == attrTmp.end()) { 127 | attrTmp.push_back(data.sound); 128 | } 129 | else if (attrTmp.empty()) { 130 | attrTmp.push_back(data.sound); 131 | } 132 | break; 133 | case 4: 134 | if (!attrTmp.empty() && 135 | std::find(attrTmp.begin(), attrTmp.end(), data.texture) == attrTmp.end()) { 136 | attrTmp.push_back(data.texture); 137 | } 138 | else if (attrTmp.empty()) { 139 | attrTmp.push_back(data.texture); 140 | } 141 | break; 142 | case 5: 143 | if (!attrTmp.empty() && 144 | std::find(attrTmp.begin(), attrTmp.end(), data.umbilical) == attrTmp.end()) { 145 | attrTmp.push_back(data.umbilical); 146 | } 147 | else if (attrTmp.empty()) { 148 | attrTmp.push_back(data.umbilical); 149 | } 150 | break; 151 | case 6: 152 | if (!attrTmp.empty() && 153 | std::find(attrTmp.begin(), attrTmp.end(), data.touch) == attrTmp.end()) { 154 | attrTmp.push_back(data.touch); 155 | } 156 | else if (attrTmp.empty()) { 157 | attrTmp.push_back(data.touch); 158 | } 159 | break; 160 | case 7: 161 | if (!attrTmp.empty() && 162 | std::find(attrTmp.begin(), attrTmp.end(), data.good) == attrTmp.end()) { 163 | attrTmp.push_back(data.good); 164 | } 165 | else if (attrTmp.empty()) { 166 | attrTmp.push_back(data.good); 167 | } 168 | break; 169 | default: 170 | break; 171 | } 172 | } 173 | index++; 174 | map_attr[attribute] = attrTmp; 175 | } 176 | } 177 | 178 | bool belongs_same_label(std::vector datas, 179 | std::string label = "yes") 180 | { 181 | if (datas.empty()) { 182 | std::cout << "the datas is empty" << std::endl; 183 | exit(1); 184 | } 185 | 186 | for (auto iter = datas.begin(); iter != datas.end(); ++iter) { 187 | if (iter->good != label) { 188 | return false; 189 | } 190 | } 191 | 192 | return true; 193 | } 194 | 195 | std::string majority_of_category(std::vector datas) 196 | { 197 | int positivecategory = 0; 198 | int negativecategory = 0; 199 | 200 | for (auto data : datas) { 201 | if (data.good == "yes") { 202 | ++positivecategory; 203 | } 204 | else if (data.good == "no") { 205 | ++negativecategory; 206 | } 207 | } 208 | return (positivecategory > negativecategory ? "yes" : "no"); 209 | } 210 | 211 | double calculate_information_entropy(std::vector datas, 212 | std::string mapAttr = "", 213 | std::string attribute = "good") 214 | { 215 | // Ent(D) = -∑(k=1, |Y|) p_k * log2(p_k) 216 | // 217 | int size = 0; 218 | double entropy = 0; 219 | int positive = 0; 220 | int negative = 0; 221 | 222 | // Beacuse of the datas only have two label. 223 | // So entropy = positiveSample + negativeSample 224 | // 225 | if (attribute == "color") { 226 | for (auto data : datas) { 227 | if (data.color == mapAttr) { 228 | if (data.good == "yes") { 229 | ++positive; 230 | } 231 | else { 232 | ++negative; 233 | } 234 | ++size; 235 | } 236 | } 237 | } 238 | else if (attribute == "pedicle") { 239 | for (auto data : datas) { 240 | if (data.pedicle == mapAttr) { 241 | if (data.good == "yes") { 242 | ++positive; 243 | } 244 | else { 245 | ++negative; 246 | } 247 | ++size; 248 | } 249 | } 250 | } 251 | else if (attribute == "sound") { 252 | for (auto data : datas) { 253 | if (data.sound == mapAttr) { 254 | if (data.good == "yes") { 255 | ++positive; 256 | } 257 | else { 258 | ++negative; 259 | } 260 | ++size; 261 | } 262 | } 263 | } 264 | else if (attribute == "texture") { 265 | for (auto data : datas) { 266 | if (data.texture == mapAttr) { 267 | if (data.good == "yes") { 268 | ++positive; 269 | } 270 | else { 271 | ++negative; 272 | } 273 | ++size; 274 | } 275 | } 276 | } 277 | else if (attribute == "umbilical") { 278 | for (auto data : datas) { 279 | if (data.umbilical == mapAttr) { 280 | if (data.good == "yes") { 281 | ++positive; 282 | } 283 | else { 284 | ++negative; 285 | } 286 | ++size; 287 | } 288 | } 289 | } 290 | else if (attribute == "touch") { 291 | for (auto data : datas) { 292 | if (data.touch == mapAttr) { 293 | if (data.good == "yes") { 294 | ++positive; 295 | } 296 | else { 297 | ++negative; 298 | } 299 | ++size; 300 | } 301 | } 302 | } 303 | else if (attribute == "good") { 304 | size = datas.size(); 305 | auto judget = [&](Watermelon wm) { if (wm.good == "yes") { ++positive; } else { ++negative; }}; 306 | for_each(datas.begin(), datas.end(), judget); 307 | } 308 | 309 | if (positive == 0 || negative == 0) { 310 | return 0; 311 | } 312 | else { 313 | entropy = -(((double)positive / size) * log2((double)positive / size) + ((double)negative / size) * log2((double)negative / size)); 314 | } 315 | 316 | return entropy; 317 | } 318 | 319 | double proportion(std::vector& datas, 320 | std::string mapAttr = "", 321 | std::string attribute = "") 322 | { 323 | int size = datas.size(); 324 | double proportion = 0; 325 | 326 | if (attribute == "color") { 327 | for (auto data : datas) { 328 | if (data.color == mapAttr) { 329 | ++proportion; 330 | } 331 | } 332 | } 333 | else if (attribute == "pedicle") { 334 | for (auto data : datas) { 335 | if (data.pedicle == mapAttr) { 336 | ++proportion; 337 | } 338 | } 339 | } 340 | else if (attribute == "sound") { 341 | for (auto data : datas) { 342 | if (data.sound == mapAttr) { 343 | ++proportion; 344 | } 345 | } 346 | } 347 | else if (attribute == "texture") { 348 | for (auto data : datas) { 349 | if (data.texture == mapAttr) { 350 | ++proportion; 351 | } 352 | } 353 | } 354 | else if (attribute == "umbilical") { 355 | for (auto data : datas) { 356 | if (data.umbilical == mapAttr) { 357 | ++proportion; 358 | } 359 | } 360 | } 361 | else if (attribute == "touch") { 362 | for (auto data : datas) { 363 | if (data.touch == mapAttr) { 364 | ++proportion; 365 | } 366 | } 367 | } 368 | 369 | proportion /= size; 370 | 371 | return proportion; 372 | } 373 | 374 | double calculate_information_gain(std::vector& datas, 375 | std::string attribute, 376 | std::map> map_attr) 377 | { 378 | // Gain(D) = Ent(D) - ∑(v=1, V) |D^|/|D| * Ent(D) 379 | // 380 | double gain = calculate_information_entropy(datas); 381 | std::vector attrs = map_attr[attribute]; 382 | 383 | for (auto attr : attrs) { 384 | gain -= proportion(datas, attr, attribute) * calculate_information_entropy(datas, attr, attribute); 385 | } 386 | 387 | return gain; 388 | } 389 | 390 | std::pair> optimal_attribute(std::vector& datas, 391 | std::vector& attributes, 392 | std::map> map_attr) 393 | { 394 | std::map map_gains; 395 | 396 | for (auto attribute : attributes) { 397 | map_gains[attribute] = calculate_information_gain(datas, attribute, map_attr); 398 | } 399 | 400 | // Sort the information gain and select the attribute of the maximum 401 | // information gain.The biggest value is in the first. 402 | // 403 | std::vector> vec_map_gains(map_gains.begin(), map_gains.end()); 404 | auto compare_x_y = [](const std::pair x, const std::pair y) { 405 | return x.second > y.second; 406 | }; 407 | 408 | std::sort(vec_map_gains.begin(), vec_map_gains.end(), compare_x_y); 409 | 410 | auto search = map_attr.find(vec_map_gains[0].first); 411 | if (search != map_attr.end()) { 412 | return std::make_pair(search->first, search->second); 413 | } 414 | else { 415 | return std::make_pair(std::string(""), std::vector()); 416 | } 417 | } 418 | 419 | std::vector remain_watermelon_datas(std::vector datas, 420 | std::string mapAttr, 421 | std::string attribute) 422 | { 423 | std::vector tmp; 424 | 425 | if (attribute == "color") { 426 | for (auto data : datas) { 427 | if (data.color == mapAttr) { 428 | tmp.push_back(data); 429 | } 430 | } 431 | } 432 | else if (attribute == "pedicle") { 433 | for (auto data : datas) { 434 | if (data.pedicle == mapAttr) { 435 | tmp.push_back(data); 436 | } 437 | } 438 | } 439 | else if (attribute == "sound") { 440 | for (auto data : datas) { 441 | if (data.sound == mapAttr) { 442 | tmp.push_back(data); 443 | } 444 | } 445 | } 446 | else if (attribute == "texture") { 447 | for (auto data : datas) { 448 | if (data.texture == mapAttr) { 449 | tmp.push_back(data); 450 | } 451 | } 452 | } 453 | else if (attribute == "umbilical") { 454 | for (auto data : datas) { 455 | if (data.umbilical == mapAttr) { 456 | tmp.push_back(data); 457 | } 458 | } 459 | } 460 | else if (attribute == "touch") { 461 | for (auto data : datas) { 462 | if (data.touch == mapAttr) { 463 | tmp.push_back(data); 464 | } 465 | } 466 | } 467 | 468 | return tmp; 469 | } 470 | 471 | void print_tree(TreeRoot pTree, int depth) 472 | { 473 | for (int i = 0; i < depth; ++i) { 474 | std::cout << '\t'; 475 | } 476 | 477 | if (!pTree->edgeValue.empty()) { 478 | std::cout << "--" << pTree->edgeValue << "--" << std::endl; 479 | for (int i = 0 ; i < depth; ++i) { 480 | std::cout << '\t'; 481 | } 482 | } 483 | 484 | std::cout << pTree->attribute << std::endl; 485 | for (auto child : pTree->childs) { 486 | print_tree(child, depth + 1); 487 | } 488 | } 489 | 490 | #endif // REQUIRE_H__ 491 | -------------------------------------------------------------------------------- /MachineLearning/decision_tree/ID3/watermelondatas.txt: -------------------------------------------------------------------------------- 1 | id color pedicle sound texture umbilical touch good 2 | 1 darkgreen curled turbid clear sunken hardslip yes 3 | 2 jetblack curled dull clear sunken hardslip yes 4 | 3 jetblack curled turbid clear sunken hardslip yes 5 | 4 darkgreen curled dull clear sunken hardslip yes 6 | 5 lightwhite curled turbid clear sunken hardslip yes 7 | 6 darkgreen slightlycurled turbid clear slightlysunken softsticky yes 8 | 7 jetblack slightlycurled turbid lightblur slightlysunken softsticky yes 9 | 8 jetblack slightlycurled turbid clear slightlysunken hardslip yes 10 | 9 jetblack slightlycurled dull lightblur slightlysunken hardslip no 11 | 10 darkgreen stiffened crisp clear flat softsticky no 12 | 11 lightwhite stiffened crisp blur flat hardslip no 13 | 12 lightwhite curled turbid blur flat softsticky no 14 | 13 darkgreen slightlycurled turbid lightblur sunken hardslip no 15 | 14 lightwhite slightlycurled dull lightblur sunken hardslip no 16 | 15 jetblack slightlycurled turbid clear slightlysunken softsticky no 17 | 16 lightwhite curled turbid blur flat hardslip no 18 | 17 darkgreen curled dull lightblur slightlysunken hardslip no -------------------------------------------------------------------------------- /QQ/QQ.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2017-08-03T15:40:23 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui 8 | 9 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 10 | 11 | TARGET = QQ 12 | TEMPLATE = app 13 | 14 | # The following define makes your compiler emit warnings if you use 15 | # any feature of Qt which as been marked as deprecated (the exact warnings 16 | # depend on your compiler). Please consult the documentation of the 17 | # deprecated API in order to know how to port your code away from it. 18 | DEFINES += QT_DEPRECATED_WARNINGS 19 | 20 | # You can also make your code fail to compile if you use deprecated APIs. 21 | # In order to do so, uncomment the following line. 22 | # You can also select to disable deprecated APIs only up to a certain version of Qt. 23 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 24 | 25 | 26 | SOURCES += \ 27 | main.cpp \ 28 | logininterface.cpp 29 | 30 | HEADERS += \ 31 | logininterface.h 32 | 33 | FORMS += \ 34 | logininterface.ui 35 | -------------------------------------------------------------------------------- /QQ/Resource.qrc: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /QQ/basewindow.cpp: -------------------------------------------------------------------------------- 1 | #include "basewindow.h" 2 | 3 | BaseWindow::BaseWindow() 4 | { 5 | 6 | } 7 | -------------------------------------------------------------------------------- /QQ/basewindow.h: -------------------------------------------------------------------------------- 1 | #ifndef BASEWINDOW_H 2 | #define BASEWINDOW_H 3 | 4 | 5 | class BaseWindow 6 | { 7 | public: 8 | BaseWindow(); 9 | }; 10 | 11 | #endif // BASEWINDOW_H -------------------------------------------------------------------------------- /QQ/config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H 2 | #define CONFIG_H 3 | 4 | #endif // CONFIG_H 5 | -------------------------------------------------------------------------------- /QQ/css/BaseWindowCss.css: -------------------------------------------------------------------------------- 1 | *{font-family:Microsoft YaHei;} 2 | 3 | QLabel#TitleContent 4 | { 5 | color:black; 6 | } 7 | 8 | /*最小化按钮*/ 9 | QPushButton#ButtonMin 10 | { 11 | border-image:url(:/Resources/MyTitle/min.png) 0 60 0 0 ; 12 | } 13 | 14 | QPushButton#ButtonMin:hover 15 | { 16 | border-image:url(:/Resources/MyTitle/min.png) 0 30 0 30 ; 17 | } 18 | 19 | QPushButton#ButtonMin:pressed 20 | { 21 | border-image:url(:/Resources/MyTitle/min.png) 0 0 0 60 ; 22 | } 23 | 24 | /*最大化按钮*/ 25 | QPushButton#ButtonMax 26 | { 27 | border-image:url(:/Resources/MyTitle/max.png) 0 81 0 0 ; 28 | } 29 | 30 | QPushButton#ButtonMax:hover 31 | { 32 | border-image:url(:/Resources/MyTitle/max.png) 0 54 0 27 ; 33 | } 34 | 35 | QPushButton#ButtonMax:pressed 36 | { 37 | border-image:url(:/Resources/MyTitle/max.png) 0 27 0 54 ; 38 | } 39 | 40 | /*还原按钮*/ 41 | QPushButton#ButtonRestore 42 | { 43 | border-image:url(:/Resources/MyTitle/restore.png) 0 81 0 0 ; 44 | } 45 | 46 | QPushButton#ButtonRestore:hover 47 | { 48 | border-image:url(:/Resources/MyTitle/restore.png) 0 54 0 27 ; 49 | } 50 | 51 | QPushButton#ButtonRestore:pressed 52 | { 53 | border-image:url(:/Resources/MyTitle/restore.png) 0 27 0 54 ; 54 | } 55 | 56 | /*关闭按钮*/ 57 | QPushButton#ButtonClose 58 | { 59 | border-image:url(:/Resources/MyTitle/close.png) 0 60 0 0 ; 60 | border-top-right-radius:3 ; 61 | } 62 | 63 | QPushButton#ButtonClose:hover 64 | { 65 | border-image:url(:/Resources/MyTitle/close.png) 0 30 0 30 ; 66 | border-top-right-radius:3 ; 67 | } 68 | 69 | QPushButton#ButtonClose:pressed 70 | { 71 | border-image:url(:/Resources/MyTitle/close.png) 0 0 0 60 ; 72 | border-top-right-radius:3 ; 73 | } 74 | -------------------------------------------------------------------------------- /QQ/css/LoginWindowCss.css: -------------------------------------------------------------------------------- 1 | *{font-family:Microsoft YaHei;} 2 | 3 | QPushButton 4 | { 5 | border-image: url(:/LoginImages/images/LoginImages/arrowback.png) 0 60 0 0 6 | } 7 | 8 | QPushButton#FlipPushButton:hover 9 | { 10 | border-image:url(:/LoginImages/images/LoginImages/arrowback.png) 0 30 0 30 ; 11 | } 12 | -------------------------------------------------------------------------------- /QQ/css/LoginWindowCss.qss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/css/LoginWindowCss.qss -------------------------------------------------------------------------------- /QQ/images/HeadImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/HeadImage.png -------------------------------------------------------------------------------- /QQ/images/LoginImages/HeadImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/LoginImages/HeadImage.png -------------------------------------------------------------------------------- /QQ/images/LoginImages/arrowback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/LoginImages/arrowback.png -------------------------------------------------------------------------------- /QQ/images/LoginImages/back.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/LoginImages/back.gif -------------------------------------------------------------------------------- /QQ/images/LoginImages/checkbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/LoginImages/checkbox.png -------------------------------------------------------------------------------- /QQ/images/LoginImages/closeback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/LoginImages/closeback.png -------------------------------------------------------------------------------- /QQ/images/LoginImages/drop_down_Button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/LoginImages/drop_down_Button.png -------------------------------------------------------------------------------- /QQ/images/LoginImages/flicker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/LoginImages/flicker.png -------------------------------------------------------------------------------- /QQ/images/LoginImages/keyboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/LoginImages/keyboard.png -------------------------------------------------------------------------------- /QQ/images/LoginImages/minback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/LoginImages/minback.png -------------------------------------------------------------------------------- /QQ/images/LoginImages/more_accountlogin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/LoginImages/more_accountlogin.png -------------------------------------------------------------------------------- /QQ/images/LoginState/state_Qme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/LoginState/state_Qme.png -------------------------------------------------------------------------------- /QQ/images/LoginState/state_away.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/LoginState/state_away.png -------------------------------------------------------------------------------- /QQ/images/LoginState/state_busy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/LoginState/state_busy.png -------------------------------------------------------------------------------- /QQ/images/LoginState/state_hide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/LoginState/state_hide.png -------------------------------------------------------------------------------- /QQ/images/LoginState/state_notdisturb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/LoginState/state_notdisturb.png -------------------------------------------------------------------------------- /QQ/images/LoginState/state_online.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/LoginState/state_online.png -------------------------------------------------------------------------------- /QQ/images/TitleBar/arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/TitleBar/arrow.png -------------------------------------------------------------------------------- /QQ/images/TitleBar/arrow_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/TitleBar/arrow_hover.png -------------------------------------------------------------------------------- /QQ/images/TitleBar/arrow_press.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/TitleBar/arrow_press.png -------------------------------------------------------------------------------- /QQ/images/TitleBar/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/TitleBar/close.png -------------------------------------------------------------------------------- /QQ/images/TitleBar/close_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/TitleBar/close_hover.png -------------------------------------------------------------------------------- /QQ/images/TitleBar/close_press.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/TitleBar/close_press.png -------------------------------------------------------------------------------- /QQ/images/TitleBar/max.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/TitleBar/max.png -------------------------------------------------------------------------------- /QQ/images/TitleBar/min_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/TitleBar/min_.png -------------------------------------------------------------------------------- /QQ/images/TitleBar/min_hover.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/TitleBar/min_hover.bmp -------------------------------------------------------------------------------- /QQ/images/TitleBar/min_press.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/TitleBar/min_press.bmp -------------------------------------------------------------------------------- /QQ/images/TitleBar/restore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/TitleBar/restore.png -------------------------------------------------------------------------------- /QQ/images/arrowback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/arrowback.png -------------------------------------------------------------------------------- /QQ/images/back.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/back.gif -------------------------------------------------------------------------------- /QQ/images/checkbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/checkbox.png -------------------------------------------------------------------------------- /QQ/images/closeback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/closeback.png -------------------------------------------------------------------------------- /QQ/images/drop_down_Button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/drop_down_Button.png -------------------------------------------------------------------------------- /QQ/images/flicker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/flicker.png -------------------------------------------------------------------------------- /QQ/images/headBack.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/headBack.gif -------------------------------------------------------------------------------- /QQ/images/keyboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/keyboard.png -------------------------------------------------------------------------------- /QQ/images/menu_border.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/menu_border.png -------------------------------------------------------------------------------- /QQ/images/minback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/minback.png -------------------------------------------------------------------------------- /QQ/images/more_accountlogin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/more_accountlogin.png -------------------------------------------------------------------------------- /QQ/images/shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/shadow.png -------------------------------------------------------------------------------- /QQ/images/state_Qme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/state_Qme.png -------------------------------------------------------------------------------- /QQ/images/state_away.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/state_away.png -------------------------------------------------------------------------------- /QQ/images/state_busy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/state_busy.png -------------------------------------------------------------------------------- /QQ/images/state_hide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/state_hide.png -------------------------------------------------------------------------------- /QQ/images/state_notdisturb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/state_notdisturb.png -------------------------------------------------------------------------------- /QQ/images/state_online.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiafanxue/Coding/ab54ba6dae5e5690b8d40c80023073c5faa8287f/QQ/images/state_online.png -------------------------------------------------------------------------------- /QQ/logininterface.cpp: -------------------------------------------------------------------------------- 1 | #include "logininterface.h" 2 | #include "ui_logininterface.h" 3 | 4 | LoginInterface::LoginInterface(QWidget *parent) : 5 | QWidget(parent), 6 | ui(new Ui::LoginInterface) 7 | { 8 | ui->setupUi(this); 9 | } 10 | 11 | LoginInterface::~LoginInterface() 12 | { 13 | delete ui; 14 | } 15 | -------------------------------------------------------------------------------- /QQ/logininterface.h: -------------------------------------------------------------------------------- 1 | #ifndef LOGININTERFACE_H 2 | #define LOGININTERFACE_H 3 | 4 | #include 5 | 6 | namespace Ui { 7 | class LoginInterface; 8 | } 9 | 10 | class LoginInterface : public QWidget 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | explicit LoginInterface(QWidget *parent = 0); 16 | ~LoginInterface(); 17 | 18 | private: 19 | Ui::LoginInterface *ui; 20 | }; 21 | 22 | #endif // LOGININTERFACE_H 23 | -------------------------------------------------------------------------------- /QQ/logininterface.ui: -------------------------------------------------------------------------------- 1 | 2 | LoginInterface 3 | 4 | 5 | 6 | 0 7 | 0 8 | 400 9 | 300 10 | 11 | 12 | 13 | LoginInterface 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /QQ/main.cpp: -------------------------------------------------------------------------------- 1 | #include "logininterface.h" 2 | #include 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | QApplication a(argc, argv); 7 | LoginInterface w; 8 | w.show(); 9 | 10 | return a.exec(); 11 | } 12 | -------------------------------------------------------------------------------- /QQ/qrcodedialog.cpp: -------------------------------------------------------------------------------- 1 | #include "qrcodedialog.h" 2 | #include "ui_qrcodedialog.h" 3 | 4 | QRcodeDialog::QRcodeDialog(QWidget *parent) : 5 | QDialog(parent), 6 | ui(new Ui::QRcodeDialog) 7 | { 8 | ui->setupUi(this); 9 | } 10 | 11 | QRcodeDialog::~QRcodeDialog() 12 | { 13 | delete ui; 14 | } 15 | -------------------------------------------------------------------------------- /QQ/qrcodedialog.h: -------------------------------------------------------------------------------- 1 | #ifndef QRCODEDIALOG_H 2 | #define QRCODEDIALOG_H 3 | 4 | #include 5 | 6 | namespace Ui { 7 | class QRcodeDialog; 8 | } 9 | 10 | class QRcodeDialog : public QDialog 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | explicit QRcodeDialog(QWidget *parent = 0); 16 | ~QRcodeDialog(); 17 | 18 | private: 19 | Ui::QRcodeDialog *ui; 20 | }; 21 | 22 | #endif // QRCODEDIALOG_H 23 | -------------------------------------------------------------------------------- /QQ/qrcodedialog.ui: -------------------------------------------------------------------------------- 1 | 2 | QRcodeDialog 3 | 4 | 5 | 6 | 0 7 | 0 8 | 400 9 | 300 10 | 11 | 12 | 13 | Dialog 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /QQ/windowtoptitle.cpp: -------------------------------------------------------------------------------- 1 | #include "windowtoptitle.h" 2 | 3 | WindowTopTitle::WindowTopTitle(QWidget *parent) : QWidget(parent) 4 | { 5 | 6 | } 7 | -------------------------------------------------------------------------------- /QQ/windowtoptitle.h: -------------------------------------------------------------------------------- 1 | #ifndef WINDOWTOPTITLE_H 2 | #define WINDOWTOPTITLE_H 3 | 4 | #include 5 | 6 | class WindowTopTitle : public QWidget 7 | { 8 | Q_OBJECT 9 | public: 10 | explicit WindowTopTitle(QWidget *parent = nullptr); 11 | 12 | signals: 13 | 14 | public slots: 15 | }; 16 | 17 | #endif // WINDOWTOPTITLE_H -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 项目 2 | 3 | ## STL_Re 4 | 仿照标准模实现的部分STL容器,算法 5 | 6 | ## Face_Recognize 7 | 一个人脸识别程序 8 | 9 | ## QQ 10 | 仿照QQ,使用Qt开发的界面 11 | -------------------------------------------------------------------------------- /STL_re/docs/allocator.md: -------------------------------------------------------------------------------- 1 | # allocator 2 | 3 | ## Introduction 4 | This is the first version of the allocator, can only achieve a simple operation. 5 | 6 | ## Member type 7 | The type of the Allocator: 8 | 9 | allocator::value_type 10 | allocator::pointer 11 | allocator::const_pointer 12 | allocator::reference 13 | allocator::const_reference 14 | allocator::size_type 15 | allocator::difference_type 16 | allocator::rebind --- template struct rebind { typedef allocator other; }; 17 | 18 | ## Function 19 | The interface function of the Allocator: 20 | 21 | allocator() -- Default constructor 22 | allocaotr(const allocator&) -- Copy constructor 23 | template allocator(const allocator& other ); -- template construcotr 24 | ~allocator() -- Destructor 25 | 26 | pointer address(reference x) const -- Return the address of object. e.g. a.address(x) <=> &x 27 | const_pointer address(const_reference x) const -- Return the const address of object 28 | pointer allocate(size_type n, const void* = 0) -- Allocate memory, enough to store the n size of T objects. The 29 | second parameter is used prompting 30 | void deallocate(pointer p, size_type n) -- Release memory 31 | size_type max_size() const -- Return the max size of the memory 32 | void construct(pointer p, const T& x) -- Equal 'new((void*)p) T(x)' 33 | void destroy(pointer p) -- Equal 'p->~T()' -------------------------------------------------------------------------------- /STL_re/docs/string.mdown: -------------------------------------------------------------------------------- 1 | # string 2 | 3 | There are some bugs. But I don't want to debug now. So it will delay.... 4 | 5 | -------------------------------------------------------------------------------- /STL_re/docs/vector.md: -------------------------------------------------------------------------------- 1 | # vector 2 | 3 | ## 简介(后期可能会继续添加) 4 | 1.vector是STL中的循序容器,是一种动态的数组。vector的存储被自动处理,根据需要被扩展或者收缩。但由于vector中存放有额外的信息用来记录数据(如:大小,容量等等),因此,通常它比静态数组占用更多的内存空间。 5 | 6 | 2.与关联容器不同,vector中的元素存放是连续的,这意味着我们即可以通过iterator操作,也可以通过传统指针加上偏移量来进行操作。 7 | 8 | 3.vector优先于动态分配的数组。因为通过使用new申请的内存空间,存在内存泄漏的危险,有时还会泄漏资源和破坏内存。 9 | 10 | 4.vector的容量每次以2的倍数增长。 11 | 12 | 5.vector存在一个特例化vector 13 | 14 | 6.特别值得一提的是,vector是C++通向C和其他语言的通道。 15 | 16 | 7.注意迭代器失效的情况 17 | 18 | ## 资料 19 | 《Effective STL》 13 - 18条 -------------------------------------------------------------------------------- /STL_re/library/xstl_algo_copy.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBRARY_XSTL_ALGO_COPY_H__ 2 | #define LIBRARY_XSTL_ALGO_COPY_H__ 3 | 4 | namespace xstl 5 | { 6 | namespace algo 7 | { 8 | template 9 | OutputIt copy(InputIt first, InputIt last, OutputIt d_first) 10 | { 11 | while(first != last) { 12 | *d_first++ = *first++; 13 | } 14 | return d_first; 15 | } 16 | 17 | /* Since C++17 18 | template 19 | OutputIt copy(ExecutionPolicy&& policy, InputIt first, InputIt last, 20 | OutputIt d_first) 21 | { 22 | 23 | } 24 | */ 25 | 26 | template 27 | OutputIt copy_if(InputIt first, InputIt last, 28 | OutputIt d_first, UnaryPredicate pred) 29 | { 30 | while(first != last) { 31 | if(pred(*first)) { 32 | *d_first++ = *first; 33 | } 34 | *first++; 35 | } 36 | return d_first; 37 | } 38 | 39 | /* Since C++17 40 | template 41 | OutputIt copy_if(ExecutionPolicy&& policy, InputIt first, InputIt last, 42 | OutputIt d_first, UnaryPredicate pred) 43 | { 44 | 45 | } 46 | */ 47 | 48 | template 49 | OutputIt copy_n(InputIt first, Size count, OutputIt result) 50 | { 51 | if(count > 0) { 52 | *result++ = *first; 53 | for(Size i = 1; i < count; ++i) { 54 | *result++ = *++first; 55 | } 56 | 57 | /* 58 | why not ? 59 | for(Size = 0; i < count; ++i) { 60 | *result = *first++; 61 | } 62 | */ 63 | } 64 | return result; 65 | } 66 | 67 | /* Since C++17 68 | template 69 | OutputIt copy_n(ExecutionPolicy&& policy, InputIt first, InputIt last, 70 | Size count, OutputIt result) 71 | { 72 | 73 | } 74 | */ 75 | 76 | template 77 | BidirIt2 copy_backward(BidirIt1 first, BidirIt1 last, BidirIt2 d_last) 78 | { 79 | while(first != last) { 80 | *(--d_last) = *(--last); 81 | } 82 | return d_last; 83 | } 84 | } 85 | } 86 | 87 | #endif // LIBRARY_XSTL_ALGO_COPY_H__ -------------------------------------------------------------------------------- /STL_re/library/xstl_algo_equal.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBRARY_XSTL_ALGO_EQUAL_H__ 2 | #define LIBRARY_XSTL_ALGO_EQUAL_H__ 3 | 4 | namespace xstl 5 | { 6 | namespace algo 7 | { 8 | template 9 | bool equal(InputIt1 first1, InputIt1 last1, 10 | InputIt2 first2) 11 | { 12 | for(; first1 != last1; ++first1, ++first2) { 13 | if(!(*first1 == *first2)) { 14 | return false; 15 | } 16 | } 17 | return true; 18 | } 19 | 20 | /* Since C++17 21 | template 22 | bool equal(ExecutionPolicy&& policy, ForwardIt1 first1, ForwardIt1 last1, 23 | ForwardIt2 first2) 24 | { 25 | 26 | } 27 | */ 28 | 29 | template 30 | bool equal(InputIt1 first1, InputIt1 last1, 31 | InputIt2 first2, BinaryPredicate p) 32 | { 33 | for(; first1 != last1; ++first1, ++first2) { 34 | if(!p(*first1, *first2)) { 35 | return false; 36 | } 37 | } 38 | return true; 39 | } 40 | 41 | /* Since C++17 42 | template 43 | bool equal(ExecutionPolicy&& policy, ForwardIt1 first1, ForwardIt1 last1, 44 | ForwardIt2 first2, BinaryPredicate p) 45 | { 46 | 47 | } 48 | */ 49 | 50 | // Since C++14 51 | template 52 | bool equal(InputIt1 first1, InputIt1 last1, 53 | InputIt2 first2, InputIt2 last2) 54 | { 55 | int size1 = last1 - first1; 56 | int size2 = last2 - first2; 57 | if(size1 != size2) { 58 | return false; 59 | } 60 | for(; first1 != last1; ++first1, ++first2) { 61 | if(!(*first1 == *first2)) { 62 | return false; 63 | } 64 | } 65 | return true; 66 | } 67 | 68 | 69 | /* Since C++17 70 | template 71 | bool equal(ExecutionPolicy%% policy, ForwardIt1 first1, ForwardIt1 last1, 72 | ForwardIt2 first2, ForwardIt2 last2) 73 | { 74 | 75 | } 76 | */ 77 | 78 | /* Since C++14 79 | template 80 | bool equal(InputIt1 first1, InputIt1 last1, 81 | InputIt2 first2, InputIt2 last2, 82 | BinaryPredicate p) 83 | { 84 | 85 | } 86 | */ 87 | 88 | /* Since C++17 89 | template 90 | bool equal(ExecutionPolicy&& policy, ForwardIt1 first1, ForwardIt1 last1, 91 | ForwardIt2 first2, ForwardIt2 last2, 92 | BinaryPredicate p) 93 | { 94 | 95 | } 96 | */ 97 | } 98 | } 99 | 100 | #endif // LIBRARY_XSTL_ALGO_EQUAL_H__ -------------------------------------------------------------------------------- /STL_re/library/xstl_algo_fill.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBRARY_XSTL_ALGO_FILL_H__ 2 | #define LIBRARY_XSTL_ALGO_FILL_H__ 3 | 4 | namespace xstl 5 | { 6 | namespace algo 7 | { 8 | template 9 | void fill(ForwardIt first, ForwardIt last, const T& value) 10 | { 11 | for(; first != last; ++first) { 12 | *first = value; 13 | } 14 | } 15 | 16 | /* Since C++17 17 | template 18 | void fill(ExecutionPolicy&& policy, ForwardIt first, ForwardIt last, const T& value) 19 | { 20 | 21 | } 22 | */ 23 | 24 | /* Unitl C++11 25 | template 26 | void fill_n(OutputIt first, Size count, const T& value) 27 | { 28 | for(Size i = 0; i < count; ++i) { 29 | *first++ = value; 30 | } 31 | } 32 | */ 33 | 34 | template 35 | OutputIt fill_n(OutputIt first, Size count, const T& value) 36 | { 37 | for(Size i = 0; i < count; ++i) { 38 | *first++ = value; 39 | } 40 | return first; 41 | } 42 | 43 | /* Since C++17 44 | template 45 | OutputIt fill_n(ExecutionPolicy&& policy, OutputIt first, OutputIt last, 46 | Size count, const T& value) 47 | { 48 | 49 | } 50 | */ 51 | } 52 | } 53 | 54 | #endif // LIBRARY_XSTL_ALGO_FILL_H__ -------------------------------------------------------------------------------- /STL_re/library/xstl_algo_find.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBRARY_XSTL_ALGO_FIND_H__ 2 | #define LIBRARY_XSTL_ALGO_FIND_H__ 3 | 4 | namespace xstl 5 | { 6 | namespace algo 7 | { 8 | template 9 | InputIt find(InputIt first, InputIt last, const T& value) 10 | { 11 | for(; first != last; ++first) { 12 | if(*first == value) { 13 | return first; 14 | } 15 | } 16 | return last; 17 | } 18 | 19 | /* Since C++17 20 | template 21 | InputIt find(ExecutionPolicy&& policy, InputIt first, InputIt last, const T& value) 22 | { 23 | 24 | } 25 | */ 26 | 27 | template 28 | InputIt find_if(InputIt first, InputIt last, 29 | UnaryPredicate p) 30 | { 31 | for(; first != last; ++first) { 32 | if(p(*first)) { 33 | return first; 34 | } 35 | } 36 | return last; 37 | } 38 | 39 | /* Since C++17 40 | template 41 | InputIt find_if(ExecutionPolicy&& policy, InputIt first, InputIt last, 42 | UnaryPredicate p) 43 | { 44 | 45 | } 46 | */ 47 | 48 | template 49 | InputIt find_if_not(InputIt first, InputIt last, 50 | UnaryPredicate q) 51 | { 52 | for(; first != last; ++first) { 53 | if(!q(*first)) { 54 | return first; 55 | } 56 | } 57 | return last; 58 | } 59 | 60 | /* Since C++17 61 | template 62 | InputIt find_if_not(ExecutionPolicy&& policy, InputIt first, InputIt last, 63 | UnaryPredicate q) 64 | { 65 | 66 | } 67 | */ 68 | } 69 | } 70 | 71 | #endif // LIBRARY_XSTL_ALGO_FIND_H__ -------------------------------------------------------------------------------- /STL_re/library/xstl_algo_for_each.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBRARY_XSTL_ALGO_FOR_EACH_H__ 2 | #define LIBRARY_XSTL_ALGO_FOR_EACH_H__ 3 | 4 | namespace xstl 5 | { 6 | namespace algo 7 | { 8 | template 9 | UnaryFunction for_each(InputIt first, InputIt last, UnaryFunction f) 10 | { 11 | for(; first != last; ++first) { 12 | f(*first); 13 | } 14 | return f; 15 | } 16 | 17 | /* Since C++17 18 | template 19 | void for_each(ExecutionPolicy&& policy, InputIt first, InputIt last, UnaryFunction2 f) 20 | { 21 | 22 | } 23 | */ 24 | 25 | } 26 | } 27 | 28 | #endif // LIBRARY_XSTL_ALGO_FOR_EACH_H__ -------------------------------------------------------------------------------- /STL_re/library/xstl_algo_unique.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBRARY_XSTL_ALGO_UNIQUE_H__ 2 | #define LIBRARY_XSTL_ALGO_UNIQUE_H__ 3 | 4 | namespace xstl 5 | { 6 | namespace algo 7 | { 8 | template 9 | ForwardIt unique(ForwardIt first, ForwardIt last) 10 | { 11 | if(first == last) { 12 | return last; 13 | } 14 | 15 | ForwardIt result = first; 16 | while(++first != last) { 17 | if(!(*result == *first) && ++result != first) { 18 | *result = std::move(*first); 19 | } 20 | } 21 | return result; 22 | } 23 | 24 | /* Since C++17 25 | template 26 | ForwardIt unique(ExecutionPolicy&& policy, ForwardIt first, ForwardIt last) 27 | { 28 | 29 | } 30 | */ 31 | 32 | template 33 | ForwardIt unique(ForwardIt first, ForwardIt last, BinaryPredicate p) 34 | { 35 | if(first == last) { 36 | return last; 37 | } 38 | 39 | ForwardIt result = first; 40 | while(++first != last) { 41 | if(!p(*result, *first) && ++result != first) { 42 | *result = std::move(*first); 43 | } 44 | } 45 | return result; 46 | } 47 | 48 | /* Since C++17 49 | template 50 | ForwardIt unique(ExecutionPolicy&& policy, ForwardIt first, ForwardIt last, BinaryPredicate p) 51 | { 52 | 53 | } 54 | */ 55 | 56 | template 57 | OutputIt unique_copy(InputIt first, InputIt last, 58 | OutputIt d_first) 59 | { 60 | if(first == last) { 61 | return d_first; 62 | } 63 | 64 | InputIt result = first; 65 | *d_first = *first; 66 | while(++first != last) { 67 | if(!(*result == *first) && ++result != first) { 68 | *result = std::move(*first); 69 | } 70 | *++d_first = *result; 71 | } 72 | return ++d_first; 73 | } 74 | 75 | /* Since C++17 76 | template 77 | OutputIt unqiue_copy(ExecutionPolicy&& policy, InputIt first, InputIt last, 78 | OutputIt d_first) 79 | { 80 | 81 | } 82 | */ 83 | 84 | template 85 | OutputIt unique_copy(InputIt first, InputIt last, 86 | OutputIt d_first, BinaryPredicate p) 87 | { 88 | if(first == last) { 89 | return d_first; 90 | } 91 | 92 | InputIt result = first; 93 | *d_first = *first; 94 | while(++first != last) { 95 | if(!p(*result, *first) && ++result != first) { 96 | *result = std::move(*first); 97 | } 98 | *++d_first = *result; 99 | } 100 | return ++d_first; 101 | } 102 | 103 | /* Since C++17 104 | template 105 | OutputIt unqiue_copy(ExecutionPolicy&& policy, InputIt first, InputIt last, 106 | OutputIt d_first, BinaryPredicate p) 107 | { 108 | 109 | } 110 | */ 111 | } 112 | } 113 | 114 | #endif // LIBRARY_XSTL_ALGO_UNIQUE_H__ -------------------------------------------------------------------------------- /STL_re/library/xstl_algorithm.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBRARY_XSTL_ALGORITHM_H__ 2 | #define LIBRARY_XSTL_ALGORITHM_H__ 3 | 4 | // Non-modifying sequence operations 5 | #include "xstl_algo_find.h" // find && find_if && find_if_not 6 | #include "xstl_algo_for_each.h" // for_each 7 | #include "xstl_algo_equal.h" // equal 8 | 9 | // Modifying sequence operations 10 | #include "xstl_algo_copy.h" // copy && copy_if && copy_n && copy_backward 11 | #include "xstl_algo_fill.h" // fill && fill_n 12 | 13 | #include "xstl_algo_unique.h" // unique && unique_copy 14 | 15 | // Sorting operations(on sorted ranges) 16 | // #include "xstl_algo_sort.h" // is_sorted && is_srted_until && sort && 17 | // partial_sort && partial_sort_copy && stable_sort && nth_element 18 | 19 | #endif // LIBRARY_XSTL_ALGORITHM_H__ -------------------------------------------------------------------------------- /STL_re/library/xstl_allocator.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBRARY_XSTL_ALLOCATOR_H__ 2 | #define LIBRARY_XSTL_ALLOCATOR_H__ 3 | 4 | #include // for UINT_MAX 5 | #include // for std::ptrdiff_t, std::size_t 6 | #include // for exit() 7 | #include // for std::cerr, std::endl; 8 | #include // for placement new 9 | #include // for std::true_type 10 | 11 | namespace xstl 12 | { 13 | template 14 | inline T* _allocate(std::ptrdiff_t size, T*) 15 | { 16 | std::set_new_handler(0); 17 | T* tmp = (T*)(::operator new((static_cast(size * sizeof(T))))); 18 | if(tmp == 0) { 19 | std::cerr << "Out of memory" << std::endl; 20 | exit(1); 21 | } 22 | return tmp; 23 | } 24 | 25 | template 26 | inline void _deallocate(T* buffer, std::size_t /* n */) 27 | { 28 | ::operator delete(buffer); 29 | } 30 | 31 | template 32 | inline void _construct(T1* p, const T2& val) 33 | { 34 | new ((void *)p) T1(val); 35 | } 36 | 37 | template 38 | inline void _destroy(T* ptr) 39 | { 40 | ptr->~T(); 41 | } 42 | 43 | // simple_alloc 44 | template 45 | class simple_alloc 46 | { 47 | public: 48 | static T* allocate(std::size_t n) 49 | { 50 | // return 0 == n ? 0 : (T*) Alloc::allocate(n * sizeof(T)); 51 | // return 0 == n ? 0 : (T*) _allocate(n * sizeof(T)); 52 | return _allocate(static_cast(n * sizeof(T)), 53 | static_cast(0)); 54 | } 55 | 56 | static T* allocate(void) 57 | { 58 | // return (T*)Alloc::allocate(sizeof(T)); 59 | // return (T*)_allocate(sizeof(T)); 60 | return _allocate(static_cast(sizeof(T)), 61 | static_cast(0)); 62 | } 63 | 64 | static void deallocate(T* p, std::size_t n) 65 | { 66 | if(0 != n) { 67 | // Alloc::deallocate(p, n * sizeof(T)); 68 | _deallocate(p, n * sizeof(T)); 69 | } 70 | } 71 | 72 | static void deallocate(T* p) 73 | { 74 | // Alloc::deallocate(p, sizeof(T)); 75 | _deallocate(p, sizeof(T)); 76 | } 77 | }; 78 | 79 | 80 | template 81 | class allocator 82 | { 83 | public: 84 | // Member types 85 | using value_type = T; 86 | using pointer = T*; 87 | using const_pointer = const T*; 88 | using reference = T&; 89 | using const_reference = const T&; 90 | using size_type = std::size_t; 91 | using difference_type = std::ptrdiff_t; 92 | // using propagate_on_container_move_assignment = std::true_type; 93 | 94 | // template struct rebind { 95 | // typedef allocator other; 96 | // }; 97 | template 98 | using rebind = allocator; 99 | // using is_always_equal = std::true_type; 100 | 101 | public: 102 | // Member functions 103 | /* 104 | costructor && destructor 105 | */ 106 | allocator() {} 107 | allocator(const allocator& other) {} 108 | template allocator(const allocator& other) {} 109 | ~allocator() {} 110 | 111 | /* 112 | address : obtains the address of an object, even if operator& is overloaded 113 | */ 114 | pointer address(reference x) const 115 | { 116 | return static_cast(&x); 117 | } 118 | 119 | const_pointer address(const_reference x) const 120 | { 121 | return static_cast(&x); 122 | /* 123 | In sgi stl only return &x; 124 | */ 125 | } 126 | 127 | /* 128 | allocate : allocates uninitialized storage 129 | */ 130 | pointer allocate(size_type n, const void * hint = 0) 131 | { 132 | return _allocate(static_cast(n), 133 | static_cast(0)); 134 | /* 135 | return n != 0 ? static_cast(_Alloc::allocte(n * sizeof(T*))) : 0; 136 | */ 137 | } 138 | 139 | /* 140 | T* allocate(std::size_t n) 141 | { 142 | return _allocate(static_cast(n), 143 | static_cast(0)); 144 | } 145 | */ 146 | 147 | /* 148 | deallocate : deallocates storage 149 | */ 150 | void deallocate(T* p, std::size_t n) 151 | { 152 | _deallocate(p, n * sizeof(T)); 153 | } 154 | 155 | /* 156 | max_size : returns the largest supported allocation size 157 | */ 158 | size_type max_size() const 159 | { 160 | return static_cast(UINT_MAX / sizeof(T)); 161 | /* 162 | return size_t(-1) / sizeof(T); 163 | */ 164 | } 165 | 166 | /* 167 | construct : constructs an object in allocated storage 168 | */ 169 | void construct(pointer p, const_reference val) 170 | { 171 | _construct(p, val); 172 | } 173 | 174 | /* 175 | destroy : destructs an object in allocated storage 176 | */ 177 | void destroy(pointer p) 178 | { 179 | _destroy(p); 180 | } 181 | }; 182 | 183 | template<> 184 | class allocator 185 | { 186 | public: 187 | // Member types 188 | using value_type = void; 189 | using pointer = void*; 190 | using const_pointer = const void*; 191 | using size_type = std::size_t; 192 | using difference_type = std::ptrdiff_t; 193 | // using propagate_on_container_move_assignment = std::true_type; 194 | 195 | // template struct rebind { 196 | // typedef allocator other; 197 | // }; 198 | template 199 | using rebind = allocator; 200 | 201 | // using is_always_equal = std::true_type; 202 | }; 203 | 204 | template 205 | bool operator==(const allocator& lhs, const allocator& rhs) 206 | { 207 | return true; 208 | } 209 | 210 | template 211 | bool operator!=(const allocator& lhs, const allocator& rhs) 212 | { 213 | return false; 214 | } 215 | } 216 | 217 | #endif // LIBRARY_XSTL_ALLOCATOR_H__ -------------------------------------------------------------------------------- /STL_re/library/xstl_string.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBRARY_XSTL_STRING_H__ 2 | #define LIBRARY_XSTL_STRING_H__ 3 | 4 | #include // for std::search, std::find_if, std::find_end 5 | #include // for std::size_t, std::ptrdiff_t 6 | #include // for std::reverse_iterator 7 | #include // for std::binary_function 8 | #include // for std::allocator_traits::pointer, std::uninitialized_fill_n 9 | #include 10 | #include // for std::basic_ostream, std::basic_istream 11 | //#include 12 | #include "xstl_allocator.h" 13 | 14 | #ifndef _STL_THROW_ERROR 15 | #define _STL_THROW_ERROR 16 | 17 | #define _stl_throw_length_error(error) { std::cerr << "Length error" << error << std::endl; exit(1); } 18 | #define _stl_throw_out_of_range(error) { std::cerr << "Out of range " << error << std::endl; exit(1); } 19 | 20 | #endif // _STL_THROW_ERROR 21 | 22 | namespace xstl 23 | { 24 | template 25 | struct _Eq_traits : 26 | public std::unary_function 27 | { 28 | bool operator()(const T& lhs, const T& rhs) const 29 | { 30 | if (lhs == rhs) { 31 | return true; 32 | } 33 | return false; 34 | } 35 | }; 36 | 37 | template 38 | struct _Not_within_traits : 39 | public std::unary_function 40 | { 41 | typedef const typename Traits::char_type* _Pointer; 42 | const _Pointer m_first; 43 | const _Pointer m_last; 44 | 45 | _Not_within_traits(_Pointer _first, _Pointer _last) : m_first(_first), m_last(_last) { } 46 | 47 | bool operator()(const typename Traits::char_type& _x) const 48 | { 49 | return std::find_if(m_first, m_last, 50 | std::bind1st(_Eq_traits(), _x)) == m_last; 51 | } 52 | }; 53 | 54 | template 55 | class _String_base 56 | { 57 | public: 58 | using allocator_type = Alloc; 59 | allocator_type get_allocator() const { return allocator_type(); } 60 | 61 | protected: 62 | _String_base(const allocator_type&) 63 | : m_start(0), m_finish(0), m_end_of_storage(0) 64 | { 65 | // empty 66 | } 67 | 68 | _String_base(const allocator_type&, size_t _n) 69 | : m_start(0), m_finish(0), m_end_of_storage(0) 70 | { 71 | m_allocate_block(_n); 72 | } 73 | 74 | protected: 75 | T* m_start; 76 | T* m_finish; 77 | T* m_end_of_storage; 78 | 79 | using _Alloc_type = xstl::simple_alloc; 80 | 81 | T* m_allocate(size_t _n) { return _Alloc_type::allocate(_n); } 82 | 83 | void m_deallocate(T* _p, size_t _n) 84 | { 85 | if (_p) { 86 | _Alloc_type::deallocate(_p, _n); 87 | } 88 | } 89 | 90 | void m_allocate_block(size_t _n) 91 | { 92 | if (_n <= max_size()) { 93 | m_start = m_allocate(_n); 94 | m_finish = m_start; 95 | m_end_of_storage = m_start + _n; 96 | } 97 | else { 98 | m_throw_length_error(); 99 | } 100 | } 101 | 102 | void m_deallocate_block() 103 | { 104 | m_deallocate(m_start, m_end_of_storage - m_start); 105 | } 106 | 107 | size_t max_size() const { return (static_cast(-1) / sizeof(T)) - 1; } 108 | 109 | void m_throw_length_error() const; 110 | void m_throw_out_of_range() const; 111 | }; 112 | 113 | #ifdef _STL_THROW_ERROR 114 | 115 | template 116 | void _String_base::m_throw_length_error() const 117 | { 118 | _stl_throw_length_error("basic_string"); 119 | } 120 | 121 | template 122 | void _String_base::m_throw_out_of_range() const 123 | { 124 | _stl_throw_out_of_range("basic_string"); 125 | } 126 | 127 | #endif 128 | 129 | 130 | 131 | template 132 | class basic_string : private _String_base 133 | { 134 | public: 135 | // Member Types 136 | using traits_type = Traits; 137 | using value_type = CharT; 138 | using pointer = value_type*; 139 | using const_pointer = const value_type*; 140 | using reference = value_type&; 141 | using const_reference = const value_type&; 142 | using size_type = std::size_t; 143 | using difference_type = std::ptrdiff_t; 144 | using iterator = value_type*; 145 | using const_iterator = const value_type*; 146 | 147 | using reverse_iterator = std::reverse_iterator; 148 | using const_reverse_iterator = std::reverse_iterator; 149 | 150 | using _Base = _String_base; 151 | 152 | static const std::size_t npos = -1; 153 | 154 | public: 155 | typedef typename _Base::allocator_type allocator_type; 156 | allocator_type get_allocator() const { return _Base::get_allocator(); } 157 | 158 | protected: 159 | using _Base::m_allocate; 160 | using _Base::m_deallocate; 161 | using _Base::m_allocate_block; 162 | using _Base::m_deallocate_block; 163 | using _Base::m_throw_out_of_range; 164 | using _Base::m_throw_length_error; 165 | 166 | using _Base::m_start; 167 | using _Base::m_finish; 168 | using _Base::m_end_of_storage; 169 | 170 | public: 171 | struct _Reserve_t {}; 172 | 173 | basic_string(_Reserve_t, size_t count, 174 | const allocator_type& alloc = allocator_type()) 175 | : _Base(alloc, count + 1) { 176 | m_terminate_string(); 177 | } 178 | 179 | // Constructor && Destructor 180 | explicit basic_string(const allocator_type& alloc = allocator_type()) 181 | : _Base(alloc, 8) 182 | { 183 | m_terminate_string(); 184 | } 185 | 186 | // Since C++14 187 | /* 188 | basic_string() : basic_string(allocator_type()) {} 189 | explicit basic_string(const allocator_type& alloc); 190 | */ 191 | 192 | basic_string(size_type count, CharT ch, 193 | const allocator_type& alloc = allocator_type()) 194 | : _Base(alloc, count + 1) 195 | { 196 | m_finish = std::uninitialized_fill_n(m_start, count, ch); 197 | m_terminate_string(); 198 | } 199 | 200 | basic_string(const basic_string& other, size_type pos, 201 | size_type count = npos, 202 | const allocator_type& alloc = allocator_type()) 203 | : _Base(alloc) 204 | { 205 | if (pos > other.size()) { 206 | m_throw_out_of_range(); 207 | } 208 | else { 209 | m_range_initialize(other.begin() + pos, 210 | other.begin() + pos + std::min(count, other.size() - pos)); 211 | } 212 | } 213 | 214 | basic_string(const CharT* s, size_type count, 215 | const allocator_type& alloc = allocator_type()) 216 | : _Base(alloc) 217 | { 218 | m_range_initialize(s, s + count); 219 | } 220 | 221 | basic_string(const CharT* s, 222 | const allocator_type& alloc = allocator_type()) 223 | : _Base(alloc) 224 | { 225 | m_range_initialize(s, s + Traits::length(s)); 226 | } 227 | 228 | // Since C++11 229 | /* 230 | basic_string(const basic_string& other, 231 | const allocator_type& alloc = allocator_type()) 232 | { 233 | 234 | } 235 | */ 236 | 237 | basic_string(const CharT* first, const CharT* last, 238 | const allocator_type& alloc = allocator_type()) 239 | : _Base(alloc) 240 | { 241 | m_range_initialize(first, last); 242 | } 243 | 244 | ~basic_string() 245 | { 246 | destroy(m_start, m_finish + 1); 247 | } 248 | 249 | void destroy(iterator pos); 250 | void destroy(iterator _first, iterator _last); 251 | void constuct(CharT* &p) 252 | { 253 | p = new CharT(); 254 | } 255 | 256 | private: 257 | void m_construct_null(CharT* _p) 258 | { 259 | constuct(_p); 260 | try { 261 | *_p = static_cast(0); 262 | } 263 | catch (...) { 264 | destroy(_p); 265 | } 266 | } 267 | 268 | void m_terminate_string() 269 | { 270 | try { 271 | m_construct_null(m_finish); 272 | } 273 | catch (...) { 274 | destroy(m_start, m_finish); 275 | } 276 | } 277 | 278 | void m_range_initialize(const CharT* _first, const CharT* _last) 279 | { 280 | difference_type _n = _last - _first; 281 | m_allocate_block(_n + 1); 282 | m_finish = std::uninitialized_copy(_first, _last, m_start); 283 | m_terminate_string(); 284 | } 285 | 286 | public: 287 | basic_string& operator=(const basic_string& str) 288 | { 289 | if (&str != this) { 290 | assign(str.begin(), str.end()); 291 | } 292 | return *this; 293 | } 294 | 295 | /* Since C++11 */ 296 | // basic_string& operator=(basic_string&& str) 297 | // { 298 | 299 | // } 300 | 301 | basic_string& operator=(const CharT* s) 302 | { 303 | return assign(s, s + Traits::length(s)); 304 | } 305 | 306 | basic_string& operator=(CharT ch) 307 | { 308 | return assign(static_cast(1), ch); 309 | } 310 | 311 | /* Since C++11 */ 312 | // basic_string& operator=(std::initializer_list ilist) 313 | // { 314 | 315 | // } 316 | 317 | reference operator[](size_type pos) 318 | { 319 | return *(m_start + pos); 320 | } 321 | 322 | const_reference operator[](size_type pos) const 323 | { 324 | return *(m_start + pos); 325 | } 326 | 327 | basic_string& operator+=(const basic_string& str) 328 | { 329 | return append(str); 330 | } 331 | 332 | basic_string& operator+=(CharT ch) 333 | { 334 | push_back(ch); 335 | return *this; 336 | } 337 | 338 | basic_string& operator+=(const CharT* s) 339 | { 340 | return append(s); 341 | } 342 | 343 | // Since C++11 344 | basic_string& operator+=(std::initializer_list ilist) 345 | { 346 | return append(ilist.begin(), ilist.end()); 347 | } 348 | // Since C++17 349 | // basic_string& operator+=(std::basic_string_view sv); 350 | 351 | public: 352 | basic_string& assign(size_type count, CharT ch); 353 | 354 | basic_string& assign(const basic_string& str) 355 | { 356 | return assign(str.begin(), str.end()); 357 | } 358 | 359 | basic_string& assign(const basic_string& str, 360 | size_type pos, 361 | size_type count) 362 | { 363 | if (pos > str.size()) { 364 | m_throw_out_of_range(); 365 | } 366 | return assign(str.begin() + pos, 367 | str.begin() + pos + std::min(count, str.size() - pos)); 368 | } 369 | 370 | // Since C++14 371 | /* 372 | basic_string& assign(const basic_string& str, 373 | size_type pos, 374 | size_type count = npos) 375 | { 376 | 377 | } 378 | */ 379 | 380 | basic_string& assign(const CharT& s, 381 | size_type count) 382 | { 383 | return assign(s, s + count); 384 | } 385 | 386 | basic_string& assign(const CharT* s) 387 | { 388 | return assign(s, s + Traits::length(s)); 389 | } 390 | 391 | basic_string& assign(const CharT* first, const CharT* last); 392 | 393 | public: 394 | // Element access 395 | reference at(size_type pos) 396 | { 397 | if (pos >= size()) { 398 | m_throw_out_of_range(); 399 | } 400 | return *(m_start + pos); 401 | } 402 | 403 | const_reference at(size_type pos) const 404 | { 405 | if (pos >= size()) { 406 | m_throw_out_of_range(); 407 | } 408 | return *(m_start + pos); 409 | } 410 | 411 | public: 412 | // Since C++11 413 | // is equivalent to operator[](0) 414 | CharT& front() 415 | { 416 | return *m_start; 417 | } 418 | 419 | const CharT& front() const 420 | { 421 | return *m_start; 422 | } 423 | 424 | CharT& back() 425 | { 426 | return *(m_finish - 1); 427 | } 428 | 429 | const CharT& back() const 430 | { 431 | return *(m_finish - 1); 432 | } 433 | 434 | public: 435 | /* Since C++11 data() and c_str() perform the same function. */ 436 | const CharT* data() const { return m_start; } 437 | // Since C++17 438 | CharT* data() { return m_start; } 439 | 440 | const CharT* c_str() const { return m_start; } 441 | 442 | // operator std::basic_string_view() const; 443 | 444 | public: 445 | // Iterators 446 | iterator begin() /*noexcept*/ { return m_start; } 447 | const_iterator begin() const /*noexcept*/ { return m_start; } 448 | const_iterator cbegin() const /*noexcept*/ { return static_cast(m_start); } 449 | iterator end() /*noexcept*/ { return m_finish; } 450 | const_iterator end() const /*noexcept*/ { return m_finish; } 451 | const_iterator cend() const /*noexcept*/ { return static_cast(m_finish); } 452 | 453 | reverse_iterator rbegin() /*noexcept*/ { return static_cast(m_finish); } 454 | const_reverse_iterator rbegin() const /*noexcept*/ { return static_cast(m_finish); } 455 | const_reverse_iterator crbegin() const /*noexcept*/ { return static_cast(m_finish); } 456 | reverse_iterator rend() /*noexcept*/ { return static_cast(m_start); } 457 | const_reverse_iterator rend() const /*noexcept*/ { return static_cast(m_start); } 458 | const_reverse_iterator crend() const /*noexcept*/ { return static_cast(m_start); } 459 | 460 | public: 461 | // Capacity 462 | bool empty() const 463 | { 464 | // return begin() == end(); 465 | return m_start == m_finish; 466 | } 467 | 468 | size_type size() const 469 | { 470 | // return std::distance(end() - begin()); 471 | return static_cast(m_finish - m_start); 472 | } 473 | 474 | size_type length() const 475 | { 476 | return size(); 477 | } 478 | 479 | size_type max_size() const 480 | { 481 | return static_cast(-1) / sizeof(CharT); 482 | } 483 | 484 | void reserve(size_type new_cap = 0); 485 | 486 | size_type capacity() const 487 | { 488 | // return static_cast(m_end_of_storage - begin()); 489 | return static_cast(m_end_of_storage - begin()) - 1; 490 | } 491 | 492 | public: 493 | void clear() 494 | { 495 | if (!empty()) { 496 | Traits::assign(*m_start, m_null()); 497 | destroy(m_start + 1, m_finish + 1); 498 | m_finish = m_start; 499 | } 500 | } 501 | 502 | public: 503 | // s.insert(0, 1, 'E'); 504 | basic_string& insert(size_type index, size_type count, CharT ch) 505 | { 506 | if (index > size()) { 507 | m_throw_out_of_range(); 508 | } 509 | if (size() > max_size() - count) { 510 | m_throw_length_error(); 511 | } 512 | insert(m_start + index, count, ch); 513 | return *this; 514 | } 515 | 516 | basic_string& insert(size_type index, const CharT* s) 517 | { 518 | if (index > size()) { 519 | m_throw_out_of_range(); 520 | } 521 | size_type len = Traits::length(s); 522 | if (size() > max_size() - len) { 523 | m_throw_length_error; 524 | } 525 | insert(m_start + index, s, s + len); 526 | return *this; 527 | } 528 | 529 | basic_string& insert(size_type index, const CharT* s, size_type count) 530 | { 531 | if (index > size()){ 532 | m_throw_out_of_range(); 533 | } 534 | if (size() > max_size() - count) { 535 | m_throw_length_error(); 536 | } 537 | insert(m_start + index, s, s + count); 538 | return *this; 539 | } 540 | 541 | basic_string& insert(size_type index, const basic_string& str) 542 | { 543 | if (index > size()) { 544 | m_throw_out_of_range(); 545 | } 546 | if (size() > max_size() - str.size()) { 547 | m_throw_length_error(); 548 | } 549 | insert(m_start + index, str.begin(), str.end()); 550 | return *this; 551 | } 552 | 553 | // Until C++14 554 | basic_string& insert(size_type index, const basic_string& str, 555 | size_type index_str, size_type count) 556 | { 557 | if (index > size() || index_str > str.size()) { 558 | m_throw_out_of_range(); 559 | } 560 | size_type len = min(count, str.size() - index_str); 561 | if (size() > max_size() - len) { 562 | m_throw_length_error(); 563 | } 564 | insert(m_start + index, 565 | str.begin() + index_str, 566 | str.begin() + index_str + len); 567 | return *this; 568 | } 569 | 570 | // Since C++14 571 | /* 572 | basic_string& insert(size_type index, const basic_string& str, 573 | size_type index_str, size_type count = npos) 574 | { 575 | if(index > size() || index_str > str.size()) { 576 | m_throw_out_of_range(); 577 | } 578 | size_type len = min(count, str.size() - index_str); 579 | if(size() > max_size() - len) { 580 | m_throw_length_error(); 581 | } 582 | insert(m_start + index, 583 | str.begin() + index_str, 584 | str.begin() + index_str + len); 585 | return *this; 586 | } 587 | */ 588 | 589 | // Until C++11 590 | iterator insert(iterator pos, CharT ch) 591 | { 592 | if (pos == m_finish) { 593 | push_back(ch); 594 | return m_finish - 1; 595 | } 596 | else { 597 | m_insert_aux(pos, ch); 598 | } 599 | } 600 | 601 | // Since C++11 602 | // iterator insert(const_iterator pos, CharT ch); 603 | 604 | // Until C++11 605 | // void insert(iterator pos, size_t count, CharT ch); 606 | void insert(iterator pos, size_type count, CharT ch); 607 | // Since C++11 608 | // iterator insert(const_iterator pos, size_type count, CharT ch); 609 | 610 | void insert(iterator pos, const CharT* first, const CharT* last); 611 | 612 | // iterator insert(const_iterator pos, std::initializer_list ilist); 613 | 614 | private: 615 | iterator m_insert_aux(iterator, CharT); 616 | 617 | 618 | public: 619 | basic_string& erase(size_type index = 0, size_type count = npos) 620 | { 621 | if (index > size()) { 622 | m_throw_out_of_range(); 623 | } 624 | erase(m_start + index, m_start + index + min(count, size() - index)); 625 | return *this; 626 | } 627 | 628 | // Until C++11 629 | iterator erase(iterator position) 630 | { 631 | Traits::move(position, position + 1, m_finish - position); 632 | destroy(m_finish); 633 | --m_finish; 634 | return position; 635 | } 636 | 637 | // Since C++11 638 | // iterator erase(const_iterator position); 639 | 640 | // Until C++11 641 | iterator erase(iterator first, iterator last) 642 | { 643 | if (first != last) { 644 | Traits::move(first, last, (m_finish - last) + 1); 645 | const iterator new_finish = m_finish - (last - first); 646 | destroy(new_finish + 1, m_finish + 1); 647 | m_finish = new_finish; 648 | } 649 | } 650 | 651 | // Since C++11 652 | // iterator erase(const_iterator first, const_iterator last); 653 | 654 | void push_back(CharT ch) 655 | { 656 | if (m_finish + 1 == m_end_of_storage) { 657 | reserve(size() + max(size(), static_cast(1))); 658 | } 659 | m_construct_null(m_finish + 1); 660 | Traits::assign(*m_finish, ch); 661 | ++m_finish; 662 | } 663 | 664 | void pop_back() 665 | { 666 | Traits::assign(*(m_finish - 1), m_null()); 667 | destroy(m_finish); 668 | --m_finish; 669 | } 670 | 671 | // append 672 | basic_string& append(size_type count, CharT ch); 673 | 674 | basic_string& append(const basic_string& str) 675 | { 676 | return append(str.begin(), str.end()); 677 | } 678 | 679 | basic_string& append(const basic_string& str, 680 | size_type pos, 681 | size_type count) 682 | { 683 | if (pos > str.size()) { 684 | m_throw_out_of_range(); 685 | } 686 | return append(str.begin() + pos, 687 | str.begin() + pos + std::min(count, size() - pos)); 688 | } 689 | 690 | // Since C++14 691 | // basic_string& append(const basic_string& str, 692 | // size_type pos, 693 | // size_type count = npos); 694 | 695 | basic_string& append(const CharT* s, size_type count) 696 | { 697 | return append(s, s + count); 698 | } 699 | 700 | basic_string& append(const CharT* s) 701 | { 702 | return append(s, s + Traits::length(s)); 703 | } 704 | 705 | basic_string& append(const CharT* first, const CharT* last); 706 | 707 | private: 708 | static CharT m_null() 709 | { 710 | return (CharT)0; 711 | } 712 | 713 | 714 | public: 715 | // compare 716 | int compare(const basic_string& str) const 717 | { 718 | return m_compare(m_start, m_finish, str.m_start, str.m_finish); 719 | } 720 | 721 | int compare(size_type pos1, size_type count1, 722 | const basic_string& str) const 723 | { 724 | if (pos1 > size()) { 725 | m_throw_out_of_range(); 726 | } 727 | return m_compare(m_start + pos1, 728 | m_finish + pos1 + std::min(count1, size() - pos1), 729 | str.m_start, str.m_finish); 730 | } 731 | 732 | int compare(const CharT* s) const 733 | { 734 | return m_compare(m_start, m_finish, s, s + Traits::length(s)); 735 | } 736 | 737 | int compare(size_type pos1, size_type count1, 738 | const CharT* s) const 739 | { 740 | if (pos1 > size()) { 741 | m_throw_out_of_range(); 742 | } 743 | return m_compare(m_start + pos1, 744 | m_finish + pos1 + std::min(count1, size() - pos1), 745 | s, s + Traits::length(s)); 746 | } 747 | 748 | int compare(size_type pos1, size_type count1, 749 | const CharT* s, size_type count2) const 750 | { 751 | if (pos1 > size()) { 752 | m_throw_out_of_range(); 753 | } 754 | return m_compare(m_start + pos1, 755 | m_start + pos1 + std::min(count1, size() - pos1), 756 | s, s + count2); 757 | } 758 | 759 | public: 760 | static int m_compare(const CharT* first1, const CharT* last1, 761 | const CharT* first2, const CharT* last2) 762 | { 763 | const difference_type n1 = last1 - first1; 764 | const difference_type n2 = last2 - first2; 765 | const int cmp = Traits::compare(first1, first2, std::min(n1, n2)); 766 | return cmp != 0 ? cmp : (n1 < n2 ? -1 : (n1 > n2 ? 1 : 0)); 767 | } 768 | 769 | public: 770 | // replace 771 | basic_string& replace(size_type pos, size_type count, 772 | const basic_string& str) 773 | { 774 | if (pos > size()) { 775 | m_throw_out_of_range(); 776 | } 777 | const size_type len = std::min(count, size() - pos); 778 | if (size() - len >= max_size() - str.size()) { 779 | m_throw_length_error(); 780 | } 781 | return replace(m_start + pos, m_start + pos + len, 782 | str.begin(), str.end()); 783 | } 784 | 785 | basic_string& replace(const_iterator first, const_iterator last, 786 | const basic_string& str) 787 | { 788 | return replace(first, last, str.begin(), str.end()); 789 | } 790 | 791 | // Until C++14 792 | basic_string& replace(size_type pos1, size_type count1, 793 | const basic_string& str, 794 | size_type pos2, size_type count2) 795 | { 796 | if (pos1 > size() || pos2 > str.size()) { 797 | m_throw_out_of_range(); 798 | } 799 | const size_type len1 = std::min(count1, size() - pos1); 800 | const size_type len2 = std::min(count2, str.size() - pos2); 801 | if (size() - len1 >= max_size() - len2) { 802 | m_throw_length_error(); 803 | } 804 | return replace(m_start + pos1, m_start + pos1 + len1, 805 | str.begin() + pos2, str.begin() + pos2 + len2); 806 | } 807 | 808 | basic_string& replace(iterator first1, iterator last1, 809 | const iterator first2, const iterator last2); 810 | 811 | basic_string& replace(size_type pos, size_type count, 812 | const CharT* cstr, size_type count2) 813 | { 814 | if (pos > size()) { 815 | m_throw_out_of_range(); 816 | } 817 | const size_type len = std::min(count, size() - pos); 818 | if (count2 > max_size() || size() - len >= max_size() - count2) { 819 | m_throw_length_error(); 820 | } 821 | return replace(m_start + pos, m_start + pos + len, 822 | cstr, cstr + count2); 823 | } 824 | 825 | basic_string& replace(const_iterator first, const_iterator last, 826 | const CharT* cstr, size_type count2) 827 | { 828 | return replace(first, last, cstr, cstr + count2); 829 | } 830 | 831 | basic_string& replace(size_type pos, size_type count, 832 | const CharT* cstr) 833 | { 834 | if (pos > size()) { 835 | m_throw_out_of_range(); 836 | } 837 | const size_type len = std::min(count, size() - pos); 838 | const size_type n2 = Traits::length(cstr); 839 | if (n2 > max_size() || size() - len >= max_size() - n2) { 840 | m_throw_length_error(); 841 | } 842 | return replace(m_start + pos, m_start + pos + len, 843 | cstr, cstr + Traits::length(cstr)); 844 | } 845 | 846 | // basic_string& replace(iterator first, iterator last, const CharT* cstr) 847 | // { 848 | // return replace(first2, last, cstr, cstr + Traits::length(cstr)); 849 | // } 850 | 851 | basic_string& replace(const_iterator first, const_iterator last, 852 | const CharT* cstr) 853 | { 854 | return replace(first, last, cstr, cstr + Traits::length(cstr)); 855 | } 856 | 857 | basic_string& replace(size_type pos1, size_type count1, 858 | size_type count2, CharT ch) 859 | { 860 | if (pos1 > size()) { 861 | m_throw_out_of_range(); 862 | } 863 | const size_type len = std::min(count1, size() - pos1); 864 | if (count2 > max_size() || size() - len >= max_size() - count2) { 865 | m_throw_length_error(); 866 | } 867 | return replace(m_start + pos1, m_start + pos1 + len, 868 | count2, ch); 869 | } 870 | 871 | basic_string& replace(const_iterator first, const_iterator last, 872 | size_type count2, CharT ch); 873 | 874 | private: 875 | template 876 | void m_copy(_InputIterator _first, _InputIterator _last, iterator _result) 877 | { 878 | for (; _first != _last; ++_first, ++_last) { 879 | Traits::assign(*_result, *_first); 880 | } 881 | } 882 | 883 | void m_copy(const CharT* _first, const CharT* _last, CharT* _result) 884 | { 885 | Traits::copy(_result, _first, _last - _first); 886 | } 887 | 888 | public: 889 | // substr 890 | basic_string substr(size_type pos = 0, size_type count = npos) const 891 | { 892 | if (pos > size()) { 893 | m_throw_out_of_range(); 894 | } 895 | return basic_string(m_start + pos, 896 | m_start + pos + std::min(count, size() - pos)); 897 | } 898 | 899 | // copy 900 | size_type copy(CharT* dest, size_type count, size_type pos = 0) const 901 | { 902 | if (pos > size()) { 903 | m_throw_out_of_range(); 904 | } 905 | const size_type len = std::min(count, size() - pos); 906 | Traits::copy(dest, m_start + pos, count); 907 | return len; 908 | } 909 | 910 | // resize 911 | void resize(size_type count) 912 | { 913 | return resize(count, m_null()); 914 | } 915 | 916 | void resize(size_type count, CharT ch) 917 | { 918 | if (count <= size()) { 919 | erase(begin() + count, end()); 920 | } 921 | else { 922 | append(count - size(), ch); 923 | } 924 | } 925 | 926 | // swap 927 | void swap(basic_string& other) 928 | { 929 | std::swap(m_start, other.m_start); 930 | std::swap(m_finish, other.m_finish); 931 | std::swap(m_end_of_storage, other.m_end_of_storage); 932 | } 933 | 934 | public: 935 | // Search 936 | size_type find(const basic_string& str, size_type pos = 0) const 937 | { 938 | return find(str.begin(), pos, str.size()); 939 | } 940 | 941 | size_type find(const CharT* s, size_type pos, size_type count) const; 942 | 943 | size_type find(const CharT* s, size_type pos = 0) const 944 | { 945 | return find(s, pos, Traits::length(s)); 946 | } 947 | 948 | size_type find(CharT ch, size_type pos = 0) const; 949 | 950 | public: 951 | size_type rfind(const basic_string& str, size_type pos = npos) const 952 | { 953 | return rfind(str.begin(), pos, str.size()); 954 | } 955 | 956 | size_type rfind(const CharT* s, size_type pos, size_type count) const; 957 | 958 | size_type rfind(const CharT* s, size_type pos = npos) const 959 | { 960 | return rfind(s, pos, Traits::length(s)); 961 | } 962 | 963 | size_type rfind(CharT ch, size_type pos = npos) const; 964 | 965 | public: 966 | size_type find_first_of(const basic_string& str, size_type pos = 0) const 967 | { 968 | return find_first_of(str.begin(), pos, str.size()); 969 | } 970 | 971 | size_type find_first_of(const CharT* S, size_type pos, size_type count) const; 972 | 973 | size_type find_first_of(const CharT* s, size_type pos = 0) const 974 | { 975 | return find_first_of(s, pos, Traits::length(s)); 976 | } 977 | 978 | size_type find_first_of(CharT ch, size_type pos = 0) const 979 | { 980 | return find(ch, pos); 981 | } 982 | 983 | public: 984 | size_type find_first_not_of(const basic_string& str, size_type pos = 0) const 985 | { 986 | return find_first_not_of(str.begin(), pos, str.size()); 987 | } 988 | 989 | size_type find_first_not_of(const CharT* s, size_type pos, size_type count) const; 990 | 991 | size_type find_first_not_of(const CharT* s, size_type pos = 0) const 992 | { 993 | return find_first_not_of(s, pos, Traits::length(s)); 994 | } 995 | 996 | size_type find_first_not_of(CharT ch, size_type pos = 0) const; 997 | 998 | public: 999 | size_type find_last_of(const basic_string& str, size_type pos = 0) const 1000 | { 1001 | return find_last_of(str.begin(), pos, str.size()); 1002 | } 1003 | 1004 | size_type find_last_of(const CharT* s, size_type pos, size_type count) const; 1005 | 1006 | size_type find_last_of(const CharT* s, size_type pos = npos) 1007 | { 1008 | return find_last_of(s, pos, Traits::length(s)); 1009 | } 1010 | 1011 | size_type find_last_of(CharT ch, size_type pos = npos) const 1012 | { 1013 | return rfind(ch, pos); 1014 | } 1015 | 1016 | public: 1017 | size_type find_last_not_of(const basic_string& str, size_type pos = 0) const 1018 | { 1019 | return find_last_not_of(str.begin(), pos, str.size()); 1020 | } 1021 | 1022 | size_type find_last_not_of(const CharT* s, size_type pos, size_type count) const; 1023 | 1024 | size_type find_last_not_of(const CharT* s, size_type pos = npos) 1025 | { 1026 | return find_last_not_of(s, pos, Traits::length(s)); 1027 | } 1028 | 1029 | size_type find_last_not_of(CharT ch, size_type pos = npos) const; 1030 | 1031 | }; 1032 | 1033 | template 1034 | void basic_string::destroy(iterator pos) 1035 | { 1036 | pos->~CharT(); 1037 | } 1038 | 1039 | template 1040 | void basic_string::destroy(iterator first, iterator last) 1041 | { 1042 | for (; first != last; ++first) { 1043 | first->~CharT(); 1044 | } 1045 | } 1046 | 1047 | template 1048 | basic_string& 1049 | basic_string::assign(size_type count, CharT ch) 1050 | { 1051 | if (count < size()) { 1052 | Traits::assign(m_start, count, ch); 1053 | erase(m_start + count, m_finish); 1054 | } 1055 | else { 1056 | Traits::assign(m_start, size(), count); 1057 | append(count - size(), ch); 1058 | } 1059 | return *this; 1060 | } 1061 | 1062 | template 1063 | basic_string& 1064 | basic_string::assign(const CharT* first, 1065 | const CharT* last) 1066 | { 1067 | const difference_type n = last - first; 1068 | if (static_cast(n) <= size()) { 1069 | Traits::copy(m_start, first, n); 1070 | erase(m_start + n, m_finish); 1071 | } 1072 | else { 1073 | Traits::copy(m_start, first, size()); 1074 | append(first + size(), last); 1075 | } 1076 | } 1077 | 1078 | template 1079 | basic_string& 1080 | basic_string::append(size_type count, CharT ch) 1081 | { 1082 | if (count > max_size() || size() > max_size() - count) { 1083 | m_throw_length_error(); 1084 | } 1085 | 1086 | if (size() + count > capacity()) { 1087 | reserve(size() + max(size(), count)); 1088 | } 1089 | 1090 | if (count > 0) { 1091 | std::uninitialized_fill_n(m_finish + 1, count - 1, ch); 1092 | try { 1093 | m_construct_null(m_finish + count); 1094 | } 1095 | catch (...) { 1096 | destroy(m_finish + 1, m_finish + count); 1097 | } 1098 | Traits::assign(*m_finish, ch); 1099 | m_finish += count; 1100 | } 1101 | return *this; 1102 | } 1103 | 1104 | template 1105 | basic_string& 1106 | basic_string::append(const CharT* first, 1107 | const CharT* last) 1108 | { 1109 | if (first != last) { 1110 | const size_type old_size = size(); 1111 | std::ptrdiff_t n = last - first; 1112 | if (n > max_size() || old_size > max_size() - n) { 1113 | m_throw_length_error(); 1114 | } 1115 | if (old_size + n > capacity()) { 1116 | const size_type len = old_size + std::max(old_size, (size_t)n) + 1; 1117 | pointer new_start = m_allocate(len); 1118 | pointer new_finish = new_start; 1119 | try { 1120 | new_finish = std::uninitialized_copy(m_start, m_finish, new_start); 1121 | new_finish = std::uninitialized_copy(first, last, new_finish); 1122 | m_construct_null(new_finish); 1123 | } 1124 | catch (...) { 1125 | destroy(new_start, new_finish); 1126 | m_deallocate(new_start, len); 1127 | } 1128 | destroy(m_start, m_finish + 1); 1129 | m_deallocate_block(); 1130 | m_start = new_start; 1131 | m_finish = new_finish; 1132 | m_end_of_storage = m_start + len; 1133 | } 1134 | } 1135 | return *this; 1136 | } 1137 | 1138 | template 1139 | basic_string& 1140 | basic_string::replace( 1141 | const_iterator first, 1142 | const_iterator last, 1143 | size_type count2, CharT ch) 1144 | { 1145 | const size_type len = static_cast(last - first); 1146 | if (len >= count2) { 1147 | Traits::assign(first, count2, ch); 1148 | erase(first + count2, last); 1149 | } 1150 | else { 1151 | Traits::assign(first, len, ch); 1152 | insert(last, count2 - len, ch); 1153 | } 1154 | return *this; 1155 | } 1156 | 1157 | template 1158 | basic_string& 1159 | basic_string::replace( 1160 | iterator first1, iterator last1, 1161 | const iterator first2, const iterator last2) 1162 | { 1163 | const difference_type n = last1 - first2; 1164 | const difference_type len = last2 - first2; 1165 | if (len >= n) { 1166 | m_copy(first2, last2, first1); 1167 | erase(first1 + n, last1); 1168 | } 1169 | else { 1170 | const CharT* m = first2 + len; 1171 | m_copy(first2, m, first1); 1172 | insert(last1, m, last2); 1173 | } 1174 | return *this; 1175 | } 1176 | 1177 | template 1178 | typename basic_string::size_type 1179 | basic_string::find(const CharT* s, 1180 | size_type pos, size_type count) const 1181 | { 1182 | if (pos + count > size()) { 1183 | return npos; 1184 | } 1185 | else { 1186 | const const_iterator result = 1187 | std::search( 1188 | m_start + pos, m_finish, 1189 | s, s + count); 1190 | return result != m_finish ? result - begin() : npos; 1191 | } 1192 | } 1193 | 1194 | template 1195 | typename basic_string::size_type 1196 | basic_string::find(CharT ch, 1197 | size_type pos) const 1198 | { 1199 | if (pos >= size()) { 1200 | return npos; 1201 | } 1202 | else { 1203 | const const_iterator result = 1204 | find_if( 1205 | m_start + pos, m_start, 1206 | bind2nd(_Eq_traits(), ch)); 1207 | return result != m_finish ? result - begin() : npos; 1208 | } 1209 | } 1210 | 1211 | template 1212 | typename basic_string::size_type 1213 | basic_string::rfind(const CharT* s, 1214 | size_type pos, size_type count) const 1215 | { 1216 | const size_t len = size(); 1217 | 1218 | if (count > len) { 1219 | return npos; 1220 | } 1221 | else if (count == 0) { 1222 | return std::min(len, pos); 1223 | } 1224 | else { 1225 | const const_iterator last = begin() + std::min(len - count, pos) + count; 1226 | const const_iterator result = 1227 | std::find_end(begin(), last, 1228 | s, s + count, _Eq_traits()); 1229 | return result != last ? result - begin() : npos; 1230 | } 1231 | } 1232 | 1233 | template 1234 | typename basic_string::size_type 1235 | basic_string::rfind(CharT ch, 1236 | size_type pos) const 1237 | { 1238 | const size_type len = size(); 1239 | 1240 | if (len < 1) { 1241 | return npos; 1242 | } 1243 | else { 1244 | const const_iterator last = begin() + std::min(len - 1, pos) + 1; 1245 | const_reverse_iterator rresult = 1246 | std::find_if(const_reverse_iterator(last), rend(), 1247 | std::bind2nd(_Eq_traits(), ch)); 1248 | 1249 | return rresult != rend() ? (rresult.base() - 1) - begin() : npos; 1250 | } 1251 | } 1252 | 1253 | template 1254 | typename basic_string::size_type 1255 | basic_string::find_first_of(const CharT* s, 1256 | size_type pos, size_type count) const 1257 | { 1258 | if (pos >= size()) { 1259 | return npos; 1260 | } 1261 | else { 1262 | const_iterator result = std::find_first_of(begin() + pos, end(), 1263 | s, s + count, 1264 | _Eq_traits()); 1265 | return result != m_finish ? result - begin() : npos; 1266 | } 1267 | } 1268 | 1269 | template 1270 | typename basic_string::size_type 1271 | basic_string::find_first_not_of(const CharT* s, size_type pos, size_type count) const 1272 | { 1273 | if (pos > size()) { 1274 | return npos; 1275 | } 1276 | else { 1277 | const_iterator result = std::find_if(m_start + pos, m_finish, 1278 | _Not_within_traits(s, s + count)); 1279 | return result != m_finish ? result - m_start : npos; 1280 | } 1281 | } 1282 | 1283 | template 1284 | typename basic_string::size_type 1285 | basic_string::find_first_not_of(CharT ch, size_type pos) const 1286 | { 1287 | if (pos > size()) { 1288 | return npos; 1289 | } 1290 | else { 1291 | const_iterator result = 1292 | std::find_if(begin() + pos, end(), 1293 | std::not1(std::bind2nd(_Eq_traits(), ch))); 1294 | return result != m_finish ? result - begin() : npos; 1295 | } 1296 | } 1297 | 1298 | template 1299 | typename basic_string::size_type 1300 | basic_string::find_last_of(const CharT* s, size_type pos, size_type count) const 1301 | { 1302 | const size_type len = size(); 1303 | 1304 | if (len < 1) { 1305 | return npos; 1306 | } 1307 | else { 1308 | const const_iterator last = m_start + std::min(len - 1, pos) + 1; 1309 | const const_reverse_iterator rresult = 1310 | std::find_first_of(const_reverse_iterator(last), rend(), 1311 | s, s + count, 1312 | _Eq_traits()); 1313 | return rresult != rend() ? (rresult.base() - 1) - m_start : npos; 1314 | } 1315 | } 1316 | 1317 | template 1318 | typename basic_string::size_type 1319 | basic_string::find_last_not_of(const CharT* s, size_type pos, size_type count) const 1320 | { 1321 | const size_type len = size(); 1322 | 1323 | if (len < 1) { 1324 | return npos; 1325 | } 1326 | else { 1327 | const const_iterator last = begin() + std::min(len - 1, pos) + 1; 1328 | const const_reverse_iterator rresult = 1329 | std::find_if(const_reverse_iterator(last), rend(), 1330 | _Not_within_traits(s, s + count)); 1331 | return rresult != rend() ? (rresult.base() - 1) - m_start : npos; 1332 | } 1333 | } 1334 | 1335 | 1336 | template 1337 | typename basic_string::size_type 1338 | basic_string::find_last_not_of(CharT ch, size_type pos) const 1339 | { 1340 | const size_type len = size(); 1341 | 1342 | if (len < 1) { 1343 | return npos; 1344 | } 1345 | else { 1346 | const const_iterator last = begin() + std::min(len - 1, pos) + 1; 1347 | const_reverse_iterator rresult = 1348 | std::find_if(const_reverse_iterator(last), rend(), 1349 | std::not1(std::bind2nd(_Eq_traits(), ch))); 1350 | return rresult != rend() ? (rresult.base() - 1) - begin() : npos; 1351 | } 1352 | } 1353 | 1354 | // Non-member functions 1355 | // Operator+ 1356 | template 1357 | inline basic_string 1358 | operator+(const basic_string& lhs, 1359 | const basic_string& rhs) 1360 | { 1361 | typedef basic_string _Str; 1362 | typedef typename _Str::_Reserve_t _Reserve_t; 1363 | _Reserve_t _reserve; 1364 | _Str _result(_reserve, lhs.size() + rhs.size(), lhs.get_allocator()); 1365 | _result.append(lhs); 1366 | _result.append(rhs); 1367 | return _result; 1368 | } 1369 | 1370 | template 1371 | inline basic_string 1372 | operator+(const CharT* lhs, 1373 | const basic_string& rhs) 1374 | { 1375 | typedef basic_string _Str; 1376 | typedef typename _Str::_Reserve_t _Reserve_t; 1377 | _Reserve_t _reserve; 1378 | const std::size_t n = Traits::length(lhs); 1379 | _Str _result(_reserve, n + rhs.size()); 1380 | _result.append(lhs, lhs + n); 1381 | _result.append(rhs); 1382 | return _result; 1383 | } 1384 | 1385 | template 1386 | inline basic_string 1387 | operator+(CharT lhs, 1388 | const basic_string& rhs) 1389 | { 1390 | typedef basic_string _Str; 1391 | typedef typename _Str::_Reserve_t _Reserve_t; 1392 | _Reserve_t _reserve; 1393 | _Str _result(_reserve, 1 + rhs.size()); 1394 | _result.push_back(lhs); 1395 | _result.append(rhs); 1396 | return _result; 1397 | } 1398 | 1399 | template 1400 | inline basic_string 1401 | operator+(const basic_string& lhs, 1402 | const CharT* rhs) 1403 | { 1404 | typedef basic_string _Str; 1405 | typedef typename _Str::_Reserve_t _Reserve_t; 1406 | _Reserve_t _reserve; 1407 | const size_t n = Traits::length(rhs); 1408 | _Str _result(_reserve, lhs.size() + n, lhs.get_allocator()); 1409 | _result.append(lhs); 1410 | _result.append(rhs, rhs + n); 1411 | return _result; 1412 | } 1413 | 1414 | template 1415 | inline basic_string 1416 | operator+(const basic_string& lhs, 1417 | CharT rhs) 1418 | { 1419 | typedef basic_string _Str; 1420 | typedef typename _Str::_Reserve_t _Reserve_t; 1421 | _Reserve_t _reserve; 1422 | _Str _result(_reserve, lhs.size() + 1); 1423 | _result.append(lhs); 1424 | _result.push_back(rhs); 1425 | return _result; 1426 | } 1427 | 1428 | template 1429 | std::basic_ostream<_CharT, _Traits>& 1430 | operator<<(std::basic_ostream<_CharT, _Traits>& _os, 1431 | const basic_string<_CharT, _Traits, _Alloc>& _s) 1432 | { 1433 | typename std::basic_ostream<_CharT, _Traits>::sentry _sentry(_os); 1434 | bool _ok = false; 1435 | 1436 | if (_sentry) { 1437 | _ok = true; 1438 | std::size_t _n = _s.size(); 1439 | std::size_t _pad_len = 0; 1440 | const bool _left = (_os.flags() & std::ios::left) != 0; 1441 | const std::size_t _w = _os.width(0); 1442 | std::basic_streambuf<_CharT, _Traits>* _buf = _os.rdbuf(); 1443 | 1444 | if (_w != 0 && _n < _w) 1445 | _pad_len = _w - _n; 1446 | 1447 | if (!_left) 1448 | _ok = _sgi_string_fill(_os, _buf, _pad_len); 1449 | 1450 | _ok = _ok && 1451 | _buf->sputn(_s.data(), std::streamsize(_n)) == std::streamsize(_n); 1452 | 1453 | if (_left) 1454 | _ok = _ok && _sgi_string_fill(_os, _buf, _pad_len); 1455 | } 1456 | 1457 | if (!_ok) 1458 | _os.setstate(std::ios_base::failbit); 1459 | 1460 | return _os; 1461 | } 1462 | 1463 | template 1464 | std::basic_istream<_CharT, _Traits>& 1465 | operator>>(std::basic_istream<_CharT, _Traits>& _is, 1466 | basic_string<_CharT, _Traits, _Alloc>& _s) 1467 | { 1468 | typename std::basic_istream<_CharT, _Traits>::sentry _sentry(_is); 1469 | 1470 | if (_sentry) { 1471 | std::basic_streambuf<_CharT, _Traits>* _buf = _is.rdbuf(); 1472 | const std::ctype<_CharT>& _ctype = std::use_facet >(_is.getloc()); 1473 | 1474 | _s.clear(); 1475 | size_t _n = _is.width(0); 1476 | if (_n == 0) 1477 | _n = static_cast(-1); 1478 | else 1479 | _s.reserve(_n); 1480 | 1481 | 1482 | while (_n-- > 0) { 1483 | typename _Traits::int_type _c1 = _buf->sbumpc(); 1484 | if (_Traits::eq_int_type(_c1, _Traits::eof())) { 1485 | _is.setstate(std::ios_base::eofbit); 1486 | break; 1487 | } 1488 | else { 1489 | _CharT _c = _Traits::to_char_type(_c1); 1490 | 1491 | if (_ctype.is(std::ctype<_CharT>::space, _c)) { 1492 | if (_Traits::eq_int_type(_buf->sputbackc(_c), _Traits::eof())) 1493 | _is.setstate(std::ios_base::failbit); 1494 | break; 1495 | } 1496 | else 1497 | _s.push_back(_c); 1498 | } 1499 | } 1500 | 1501 | // If we have read no characters, then set failbit. 1502 | if (_s.size() == 0) 1503 | _is.setstate(std::ios_base::failbit); 1504 | } 1505 | else 1506 | _is.setstate(std::ios_base::failbit); 1507 | 1508 | return _is; 1509 | } 1510 | 1511 | template 1512 | inline bool 1513 | _sgi_string_fill(std::basic_ostream<_CharT, _Traits>& _os, 1514 | std::basic_streambuf<_CharT, _Traits>* _buf, 1515 | std::size_t _n) 1516 | { 1517 | _CharT _f = _os.fill(); 1518 | size_t _i; 1519 | bool _ok = true; 1520 | 1521 | for (_i = 0; _i < _n; _i++) 1522 | _ok = _ok && !_Traits::eq_int_type(_buf->sputc(_f), _Traits::eof()); 1523 | return _ok; 1524 | } 1525 | 1526 | #ifndef XSTL_STRING 1527 | #define XSTL_STRING 1528 | 1529 | typedef basic_string, xstl::allocator> string; 1530 | typedef basic_string, xstl::allocator> wstring; 1531 | 1532 | #endif // XSTL_STRING 1533 | } 1534 | 1535 | #endif // LIBRARY_XSTL_STRING_H__ -------------------------------------------------------------------------------- /STL_re/library/xstl_vector.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBRARY_XSTL_VECTOR_H__ 2 | #define LIBRARY_XSTL_VECTOR_H__ 3 | 4 | #include // for std::initializer_list 5 | #include // for std::cerr 6 | #include // for std::fill, std::copy, std::copy_backward, std::equal 7 | #include // for std::reverse_iterator 8 | #include // for std::allocator_traits::pointer, std::uninitialized_fill_n 9 | #include "xstl_allocator.h" 10 | 11 | #ifndef _STL_THROW_RANGE_ERROR 12 | #define _STL_THROW_RANGE_ERROR 13 | 14 | #define _stl_throw_range_errors(error) { std::cerr << "Out of range " << error << std::endl; exit(1); } 15 | 16 | #endif // _STL_THROW_RANGE_ERROR 17 | 18 | namespace xstl 19 | { 20 | template 21 | class vector_base 22 | { 23 | public: 24 | using allocator_type = Alloc; 25 | allocator_type get_allocator() const 26 | { 27 | return allocator_type(); 28 | } 29 | 30 | public: 31 | vector_base(const Alloc&) 32 | : m_start(0), m_finish(0), m_end_of_storage(0) 33 | { 34 | // empty 35 | } 36 | 37 | vector_base(std::size_t n, const Alloc&) 38 | : m_start(0), m_finish(0), m_end_of_storage(0) 39 | { 40 | m_start = m_allocate(n); 41 | m_finish = m_start; 42 | m_end_of_storage = m_start + n; 43 | } 44 | 45 | ~vector_base() 46 | { 47 | m_deallocate(m_start, m_end_of_storage - m_start); 48 | } 49 | 50 | protected: 51 | T* m_start; // 表示目前使用空间的头 52 | T* m_finish; // 表示目前使用空间的尾 53 | T* m_end_of_storage; // 表示目前可用空间的尾 54 | 55 | using m_data_allocator = xstl::simple_alloc; 56 | 57 | T* m_allocate(std::size_t _n) 58 | { 59 | return m_data_allocator::allocate(_n); 60 | } 61 | 62 | void m_deallocate(T* _p, std::size_t _n) 63 | { 64 | m_data_allocator::deallocate(_p, _n); 65 | } 66 | }; 67 | 68 | 69 | template > 70 | class vector : protected vector_base 71 | { 72 | private: 73 | using _base = vector_base; 74 | 75 | public: 76 | // Member Types 77 | using value_type = T; 78 | using size_type = std::size_t; 79 | using difference_type = std::ptrdiff_t; 80 | using reference = value_type&; 81 | using const_reference = const value_type&; 82 | using pointer = value_type*; 83 | using const_pointer = const value_type*; 84 | using iterator = value_type*; 85 | using const_iterator = const value_type*; 86 | 87 | typedef typename _base::allocator_type allocator_type; 88 | 89 | using reverse_iterator = std::reverse_iterator; 90 | using const_reverse_iterator = std::reverse_iterator; 91 | 92 | protected: 93 | using _base::m_start; 94 | using _base::m_finish; 95 | using _base::m_end_of_storage; 96 | using _base::m_allocate; 97 | using _base::m_deallocate; 98 | 99 | 100 | public: 101 | // Member functions 102 | 103 | // Constructor 104 | // Until C++14 105 | explicit vector(const allocator_type& alloc = allocator_type()) 106 | : _base(alloc) 107 | { 108 | // empty 109 | } 110 | 111 | // C++14 实现 112 | /* 113 | vector() : vector(allocator_type()) {} 114 | explicit vector(allocator_type& alloc = allocator_type()) 115 | : _base(alloc) 116 | { 117 | // empty 118 | } 119 | */ 120 | 121 | /* 122 | 例如实现:vector vec(10, 'c') 123 | */ 124 | vector(size_type count, const T& value, 125 | const allocator_type& alloc = allocator_type()) 126 | : _base(count, alloc) 127 | { 128 | m_finish = std::uninitialized_fill_n(m_start, count, value); 129 | } 130 | 131 | // C++11 132 | // explicit vecotr(size_type count) 133 | // Since C++14 134 | explicit vector(size_type count, const allocator_type& alloc = allocator_type()) 135 | : _base(count, alloc) 136 | { 137 | m_finish = std::uninitialized_fill_n(m_start, count, T()); 138 | } 139 | 140 | vector(const T* _first, const T* _last, 141 | const allocator_type& alloc = allocator_type()) 142 | : _base(_last - _first, alloc) 143 | { 144 | m_finish = std::uninitialized_copy(_first, _last, m_start); 145 | } 146 | 147 | vector(const vector& x) 148 | : _base(x.size(), x.get_allocator()) 149 | { 150 | m_finish = std::uninitialized_copy(x.begin(), x.end(), m_start); 151 | } 152 | 153 | vector(std::initializer_list init, 154 | const allocator_type& alloc = allocator_type()) 155 | : _base(init.end() - init.begin(), alloc) 156 | { 157 | m_finish = std::uninitialized_copy(init.begin(), init.end(), m_start); 158 | } 159 | 160 | // destructor 161 | ~vector() 162 | { 163 | destroy(m_start, m_finish); 164 | } 165 | 166 | void destroy(iterator pos); 167 | void destroy(iterator _first, iterator _last); 168 | 169 | public: 170 | vector& operator=(const vector& x); 171 | // Since C++11 172 | // vector& operator=(vector&& x); 173 | void assign(size_type count, const T& value) { m_fill_assign(count, value); } 174 | void m_fill_assign(size_type count, const T& value); 175 | allocator_type get_allocator() const { return _base::get_allocator(); } 176 | 177 | public: 178 | // Element access 179 | // 下标检查 180 | #ifndef _STL_THROW_RANGE_ERRORS 181 | #define _STL_THROW_RANGE_ERRORS 182 | void m_range_check(size_type n) const 183 | { 184 | if (!(n < this->size())) { 185 | _stl_throw_range_errors("vector"); 186 | } 187 | } 188 | #endif // _STL_THROW_RANGE_ERRORS 189 | 190 | reference at(size_type pos) 191 | { 192 | m_range_check(pos); 193 | return (*this)[pos]; 194 | } 195 | 196 | const_reference at(size_type pos) const 197 | { 198 | m_range_check(pos); 199 | return (*this)[pos]; 200 | } 201 | 202 | 203 | reference operator[](size_type pos) { return *(begin() + pos); } 204 | const_reference operator[](size_type pos) const { return *(begin() + pos); } 205 | 206 | reference front() { return *begin(); } 207 | const_reference front() const { return *begin(); } 208 | 209 | reference back() { return *(end() - 1); } 210 | const_reference back() const { return *(end() - 1); } 211 | 212 | T* data() /*noexcept*/ { return &front(); } 213 | const T* data() const /*noexcept*/ { return &front(); } 214 | 215 | public: 216 | // Iterators 217 | iterator begin() /*noexcept*/ { return m_start; } 218 | const_iterator begin() const /*noexcept*/ { return m_start; } 219 | const_iterator cbegin() const /*noexcept*/ { return static_cast(m_start); } 220 | iterator end() /*noexcept*/ { return m_finish; } 221 | const_iterator end() const /*noexcept*/ { return m_finish; } 222 | const_iterator cend() const /*noexcept*/ { return static_cast(m_finish); } 223 | 224 | reverse_iterator rbegin() /*noexcept*/ { return reverse_iterator(end()); } 225 | const_reverse_iterator rbegin() const /*noexcept*/ { return const_reverse_iterator(end()); } 226 | const_reverse_iterator crbegin() const /*noexcept*/ { return const_reverse_iterator(end()); } 227 | reverse_iterator rend() /*noexcept*/ { return reverse_iterator(begin()); } 228 | const_reverse_iterator rend() const /*noexcept*/ { return const_reverse_iterator(begin()); } 229 | const_reverse_iterator crend() const /*noexcept*/ { return const_reverse_iterator(begin()); } 230 | 231 | public: 232 | // Capacity 233 | bool empty() const /*noexcept*/ 234 | { 235 | return begin() == end(); 236 | } 237 | 238 | size_type size() const /*noexcept*/ 239 | { 240 | // return std::distance(begin(), end()); 241 | return static_cast(end() - begin()); 242 | } 243 | 244 | size_type max_size() const /*noexcept*/ 245 | { 246 | return static_cast(-1) / sizeof(T); 247 | } 248 | 249 | void reserve(size_type new_cap) 250 | { 251 | if (capacity() < new_cap) { 252 | const size_type old_size = size(); 253 | iterator tmp = m_allocate_and_copy(new_cap, m_start, m_finish); 254 | destroy(m_start, m_finish); 255 | m_deallocate(m_start, m_end_of_storage - m_start); 256 | m_start = tmp; 257 | m_finish = tmp + old_size; 258 | m_end_of_storage = m_start + new_cap; 259 | } 260 | } 261 | 262 | size_type capacity() const 263 | { 264 | return static_cast(m_end_of_storage - begin()); 265 | } 266 | 267 | /*void shrink_to_fit() {}*/ 268 | 269 | public: 270 | // Until C++11 271 | iterator erase(iterator pos) 272 | { 273 | if (pos + 1 != end()) { 274 | std::copy(pos + 1, m_finish, pos); 275 | } 276 | --m_finish; 277 | destroy(m_finish); 278 | return pos; 279 | } 280 | 281 | // Since C++11 282 | iterator erase(const_iterator pos) 283 | { 284 | if (pos + 1 != end()) { 285 | std::copy(pos + 1, m_finish, pos); 286 | } 287 | --m_finish; 288 | destroy(m_finish); 289 | return pos; 290 | } 291 | 292 | iterator erase(iterator first, iterator last) 293 | { 294 | iterator i = std::copy(last, m_finish, first); 295 | destroy(i, m_finish); 296 | m_finish = m_finish - (last - first); 297 | return first; 298 | } 299 | 300 | iterator erase(const_iterator first, const_iterator last) 301 | { 302 | iterator i = std::copy(last, m_finish, first); 303 | destroy(i, m_finish); 304 | m_finish = m_finish - (last - first); 305 | return first; 306 | } 307 | 308 | void clear() 309 | { 310 | erase(begin(), end()); 311 | } 312 | 313 | iterator insert(iterator pos, const T& value) 314 | { 315 | size_type n = pos - begin(); 316 | if (m_finish != m_end_of_storage && pos == end()) { 317 | construct(m_finish, value); 318 | ++m_finish; 319 | } 320 | else { 321 | m_insert_aux(pos, value); 322 | } 323 | return begin() + n; 324 | } 325 | 326 | // Since C++11 327 | iterator insert(const_iterator pos, const T& value) 328 | { 329 | size_type n = pos - begin(); 330 | if (m_finish != m_end_of_storage && pos == end()) { 331 | construct(m_finish, value); 332 | ++m_finish; 333 | } 334 | else { 335 | m_insert_aux(pos, value); 336 | } 337 | return begin() + n; 338 | } 339 | 340 | iterator insert(const_iterator pos) 341 | { 342 | size_type n = pos - begin(); 343 | if (m_finish != m_end_of_storage && pos == end()) { 344 | construct(m_finish); 345 | ++m_finish; 346 | } 347 | else { 348 | m_insert_aux(pos); 349 | } 350 | return begin() + n; 351 | } 352 | 353 | void insert(iterator pos, size_type count, const T& value) 354 | { 355 | m_fill_insert(pos, count, value); 356 | } 357 | 358 | void m_fill_insert(iterator pos, size_type count, const T& value); 359 | 360 | void push_back(const T& value) 361 | { 362 | if (m_finish != m_end_of_storage) { 363 | construct(m_finish, value); 364 | ++m_finish; 365 | } 366 | else { 367 | m_insert_aux(end(), value); 368 | } 369 | } 370 | 371 | void push_back() 372 | { 373 | if (m_finish != m_end_of_storage) { 374 | construct(m_finish); 375 | ++m_finish; 376 | } 377 | else { 378 | m_insert_aux(end()); 379 | } 380 | } 381 | 382 | /* 383 | void push_back(T&& value) 384 | { 385 | if(m_finish != m_end_of_storage) { 386 | construct(m_finish, value); 387 | ++m_finish; 388 | } 389 | else { 390 | m_insert_aux(end(), value); 391 | } 392 | } 393 | */ 394 | 395 | void pop_back() 396 | { 397 | --m_finish; 398 | destroy(m_finish); 399 | } 400 | 401 | void resize(size_type new_size) 402 | { 403 | resize(new_size, T()); 404 | } 405 | 406 | void resize(size_type new_size, const value_type& value) /* const T& value*/ 407 | { 408 | if (new_size < size()) { 409 | erase(begin() + new_size, end()); 410 | } 411 | else { 412 | insert(end(), new_size - size(), value); 413 | } 414 | } 415 | 416 | void swap(vector& x) 417 | { 418 | // Specializetion 419 | // std::swap for vector 420 | std::swap(m_start, x.m_start); 421 | std::swap(m_finish, x.m_finish); 422 | std::swap(m_end_of_storage, x.m_end_of_storage); 423 | } 424 | 425 | protected: 426 | template 427 | iterator m_allocate_and_copy(size_type _n, ForwardIterator _first, ForwardIterator _last) 428 | { 429 | iterator _result = m_allocate(_n); 430 | try { 431 | std::uninitialized_copy(_first, _last, _result); 432 | return _result; 433 | } 434 | catch (...) { 435 | m_deallocate(_result, _n); 436 | } 437 | return NULL; 438 | } 439 | 440 | void m_insert_aux(iterator pos, const T& value); 441 | void m_insert_aux(iterator pos); 442 | void construct(pointer _p, const T& _val) { new(_p)T(_val); } 443 | }; 444 | 445 | template 446 | void vector::destroy(iterator pos) 447 | { 448 | pos->~T(); 449 | } 450 | 451 | template 452 | void vector::destroy(iterator first, iterator last) 453 | { 454 | for (; first != last; ++first) { 455 | first->~T(); 456 | } 457 | } 458 | 459 | template 460 | vector& vector::operator=(const vector& x) 461 | { 462 | if (&x != this) { 463 | const size_type xlen = x.size(); 464 | if (xlen > capacity()) { 465 | iterator tmp = m_allocate_and_copy(xlen, x.begin(), x.end()); 466 | destroy(m_start, m_finish); 467 | m_deallocate(m_start, m_end_of_storage - m_start); 468 | m_start = tmp; 469 | m_end_of_storage = m_start + xlen; 470 | } 471 | else if (size() >= xlen) { 472 | iterator i = std::copy(x.begin(), x.end(), begin()); 473 | destroy(i, m_finish); 474 | } 475 | else { 476 | std::copy(x.begin(), x.begin() + size(), m_start); 477 | std::uninitialized_copy(x.begin() + size(), x.end(), m_finish); 478 | } 479 | m_finish = m_start + xlen; 480 | } 481 | return *this; 482 | } 483 | 484 | template 485 | void vector::m_fill_assign(size_type count, const T& value) 486 | { 487 | if (count > capacity()) { 488 | vector tmp(count, value, get_allocator()); 489 | tmp.swap(*this); 490 | } 491 | else if (count > size()) { 492 | std::fill(begin(), end(), value); 493 | m_finish = std::uninitialized_fill_n(m_start, count - size(), value); 494 | } 495 | else { // 如果失败,删除全部元素 496 | erase(std::fill_n(begin(), count, value), end()); 497 | } 498 | } 499 | 500 | template 501 | void vector::m_insert_aux(iterator pos, const T& value) 502 | { 503 | if (m_finish != m_end_of_storage) { 504 | construct(m_finish, *(m_finish - 1)); 505 | ++m_finish; 506 | T value_copy = value; 507 | std::copy_backward(pos, m_finish - 2, m_finish - 1); 508 | *pos = value_copy; 509 | } 510 | else { 511 | const size_type old_size = size(); 512 | const size_type len = old_size != 0 ? 2 * old_size : 1; 513 | iterator new_start = m_allocate(len); 514 | iterator new_finish = new_start; 515 | try { 516 | new_finish = std::uninitialized_copy(m_start, pos, new_start); 517 | construct(new_finish, value); 518 | ++new_finish; 519 | new_finish = std::uninitialized_copy(pos, m_finish, new_finish); 520 | } 521 | catch (...) { 522 | destroy(new_start, new_finish); 523 | m_deallocate(new_start, len); 524 | } 525 | destroy(begin(), end()); 526 | m_deallocate(m_start, m_end_of_storage - m_start); 527 | m_start = new_start; 528 | m_finish = new_finish; 529 | m_end_of_storage = new_start + len; 530 | } 531 | } 532 | 533 | template 534 | void vector::m_insert_aux(iterator pos) 535 | { 536 | if (m_finish != m_end_of_storage) { 537 | construct(m_finish, *(m_finish - 1)); 538 | ++m_finish; 539 | std::copy_backward(pos, m_finish - 2, m_finish - 1); 540 | *pos = T(); 541 | } 542 | else { 543 | const size_type old_size = size(); 544 | const size_type len = old_size != 0 ? 2 * old_size : 1; 545 | iterator new_start = m_allocate(len); 546 | iterator new_finish = m_start; 547 | try { 548 | new_finish = std::uninitialized_copy(m_start, pos, new_start); 549 | construct(new_finish); 550 | ++new_finish; 551 | new_finish = std::uninitialized_copy(pos, m_finish, new_finish); 552 | } 553 | catch (...) { 554 | destroy(new_start, new_finish); 555 | m_deallocate(new_start, len); 556 | } 557 | destroy(begin(), end()); 558 | m_deallocate(m_start, m_end_of_storage - m_start); 559 | m_start = new_start; 560 | m_finish = new_finish; 561 | m_end_of_storage = new_start + len; 562 | } 563 | } 564 | 565 | template 566 | void vector::m_fill_insert(iterator pos, size_type count, const T& value) 567 | { 568 | if (count != 0) { 569 | if (static_cast(m_end_of_storage - m_finish) >= 0) { 570 | T value_copy = value; 571 | const size_type elems_after = m_finish - pos; 572 | iterator old_finish = m_finish; 573 | if (elems_after > count) { 574 | std::uninitialized_copy(m_finish - count, m_finish, m_finish); 575 | m_finish += count; 576 | std::copy_backward(pos, old_finish - count, old_finish); 577 | std::fill(pos, pos + count, value_copy); 578 | } 579 | else { 580 | std::uninitialized_fill_n(m_finish, count - elems_after, value_copy); 581 | m_finish += count - elems_after; 582 | std::uninitialized_copy(pos, old_finish, m_finish); 583 | m_finish += elems_after; 584 | std::fill(pos, old_finish, value_copy); 585 | } 586 | } 587 | else { 588 | const size_type old_size = size(); 589 | const size_type len = old_size + std::max(old_size, count); 590 | iterator new_start = m_allocate(len); 591 | iterator new_finish = m_start; 592 | try { 593 | new_finish = std::uninitialized_copy(m_start, pos, new_start); 594 | new_finish = std::uninitialized_fill_n(new_finish, count, value); 595 | new_finish = std::uninitialized_copy(pos, m_finish, new_finish); 596 | } 597 | catch (...) { 598 | destroy(new_start, new_finish); 599 | m_deallocate(new_start, len); 600 | } 601 | destroy(m_start, m_finish); 602 | m_deallocate(m_start, m_end_of_storage - m_start); 603 | m_start = new_start; 604 | m_finish = new_finish; 605 | m_end_of_storage = new_start + len; 606 | } 607 | } 608 | } 609 | 610 | 611 | // Non-member functions 612 | template 613 | inline bool operator==(const vector& lhs, 614 | const vector& rhs) 615 | { 616 | return lhs.size() == rhs.size() && 617 | std::equal(lhs.begin(), lhs.end(), rhs.begin()); 618 | } 619 | 620 | template 621 | inline bool operator!=(const vector& lhs, 622 | const vector& rhs) 623 | { 624 | return !(lhs == rhs); 625 | } 626 | 627 | template 628 | inline bool operator<(const vector& lhs, 629 | const vector& rhs) 630 | { 631 | return lexicographical_compare(lhs.begin(), lhs.end(), 632 | rhs.begin(), rhs.end()); 633 | } 634 | 635 | template 636 | inline bool operator<=(const vector& lhs, 637 | const vector& rhs) 638 | { 639 | return !(lhs > rhs); 640 | } 641 | 642 | template 643 | inline bool operator>(const vector& lhs, 644 | const vector& rhs) 645 | { 646 | return lhs < rhs; 647 | } 648 | 649 | template 650 | inline bool operator>=(const vector& lhs, 651 | const vector& rhs) 652 | { 653 | return !(lhs < rhs); 654 | } 655 | 656 | } 657 | 658 | #endif // LIBRARY_XSTL_VECTOR_H__ -------------------------------------------------------------------------------- /STL_re/test/algorithm_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "../library/xstl_algorithm.h" 7 | 8 | struct Sum 9 | { 10 | Sum() : sum{0} { } 11 | void operator()(int n) { sum += n; } 12 | int sum; 13 | }; 14 | 15 | bool is_palindrome(const std::string& s) 16 | { 17 | return xstl::algo::equal(s.begin(), s.begin() + s.size() / 2, s.rbegin()); 18 | } 19 | 20 | void test(const std::string& s) 21 | { 22 | std::cout << "\"" << s << "\"" 23 | << (is_palindrome(s) ? "is" : "is not") 24 | << " a is_palindrome" << std::endl; 25 | } 26 | 27 | int main(int argc, char const *argv[]) 28 | { 29 | std::vector v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 30 | // fill 31 | xstl::algo::fill(v.begin(), v.end(), 1); 32 | // fill_n 33 | xstl::algo::fill_n(std::back_inserter(v), 5, -1); 34 | // copy 35 | xstl::algo::copy(v.cbegin(), v.cend(), std::ostream_iterator(std::cout, " ")); 36 | std::cout << std::endl; 37 | // copy_n 38 | std::string in = "123456"; 39 | std::string out; 40 | xstl::algo::copy_n(in.cbegin(), 4, std::back_inserter(out)); 41 | std::cout << out << std::endl; 42 | // copy_backward 43 | std::vector from_vector; 44 | from_vector.reserve(10); 45 | for(int i = 1; i <= 10; ++i) { 46 | from_vector.push_back(i); 47 | } 48 | std::vector to_vector(15); 49 | xstl::algo::copy_backward(from_vector.cbegin(), from_vector.cend(), to_vector.end()); 50 | xstl::algo::copy(to_vector.cbegin(), to_vector.cend(), std::ostream_iterator(std::cout, " ")); 51 | std::cout << std::endl; 52 | 53 | // unique 54 | std::vector vec{1, 1, 2, 3, 3, 3, 4}; 55 | xstl::algo::unique(vec.begin(), vec.end()); 56 | xstl::algo::copy(vec.cbegin(), vec.cend(), std::ostream_iterator(std::cout, " ")); 57 | std::cout << std::endl; 58 | 59 | std::string s = "wanna go to space?"; 60 | std::cout << s << std::endl; 61 | auto send = xstl::algo::unique(s.begin(), s.end(), [](char l, char r){ 62 | return std::isspace(l) && std::isspace(r) && l == r; 63 | }); 64 | std::cout << std::string(s.begin(), send) << std::endl; 65 | 66 | // unique_copy 67 | std::string s1 = "The string with many spaces!"; 68 | std::cout << "before: " << s1 << std::endl; 69 | std::string s2; 70 | std::string s3; 71 | xstl::algo::unique_copy(s1.begin(), s1.end(), std::back_inserter(s2)); 72 | std::cout << "s2: " << s2 << std::endl; 73 | xstl::algo::unique_copy(s1.begin(), s1.end(), std::back_inserter(s3), 74 | [](char c1, char c2){ return c1 == ' ' && c2 == ' '; }); 75 | std::cout << "after: " << s3 << std::endl; 76 | 77 | // for_each 78 | std::vector nums{3, 4, 2, 8, 15, 267}; 79 | auto print = [](const int& i) { std::cout << " " << i; }; 80 | 81 | std::cout << "before:"; 82 | std::for_each(nums.begin(), nums.end(), print); 83 | std::cout << std::endl; 84 | 85 | std::for_each(nums.begin(), nums.end(), [](int& n) { n++; }); 86 | 87 | Sum sss = std::for_each(nums.begin(), nums.end(), Sum()); 88 | 89 | std::cout << "after: "; 90 | std::for_each(nums.begin(), nums.end(), print); 91 | std::cout << std::endl; 92 | std::cout << "sum:" << sss.sum << std::endl; 93 | 94 | // equal 95 | test("radar"); 96 | test("hello"); 97 | std::string str1 = "radar"; 98 | if(xstl::algo::equal(str1.begin(), str1.end(), str1.rbegin(), str1.rend())) { 99 | std::cout << "Yes" << std::endl; 100 | } 101 | else { 102 | std::cout << "No" << std::endl; 103 | } 104 | 105 | return 0; 106 | } -------------------------------------------------------------------------------- /STL_re/test/allocator_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "../library/xstl_allocator.h" 5 | 6 | int main(int argc, char const *argv[]) 7 | { 8 | xstl::allocator a1; 9 | int* a = a1.allocate(10); 10 | 11 | a[9] = 7; 12 | 13 | std::cout << a[9] << std::endl; 14 | 15 | a1.deallocate(a, 10); 16 | 17 | std::allocator a2; 18 | 19 | // decltype(a1)::rebind::other a2_1; 20 | 21 | // std::allocator_traits::rebind_alloc a2_2; 22 | 23 | std::string* s = a2.allocate(2); 24 | 25 | a2.construct(s, "foo"); 26 | a2.construct(s + 1, "bar"); 27 | 28 | std::cout << s[0] << " " << s[1] << std::endl; 29 | 30 | a2.destroy(s); 31 | a2.destroy(s + 1); 32 | a2.deallocate(s, 2); 33 | 34 | return 0; 35 | } -------------------------------------------------------------------------------- /STL_re/test/string_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "../library/xstl_allocator.h" 6 | #include "../library/xstl_string.h" 7 | using namespace std; 8 | 9 | int main(int argc, char const *argv[]) 10 | { 11 | { 12 | xstl::string s; 13 | assert(s.empty() && (s.length() == 0) && (s.size() == 0)); 14 | } 15 | 16 | { 17 | xstl::string s(4, '='); 18 | cout << s << endl; 19 | } 20 | 21 | { 22 | xstl::string const other("Exemplary"); 23 | // string::string(string const& other, size_type pos, size_type count) 24 | xstl::string s(other, 0, other.length() - 1); 25 | cout << s << endl; // "Exemplar" 26 | } 27 | 28 | { 29 | // string::string(charT const* s, size_type count) 30 | xstl::string s("C-style string", 7); 31 | cout << s << endl; // "C-style" 32 | } 33 | 34 | { 35 | // string::string(charT const* s) 36 | xstl::string s("C-style\0string"); 37 | cout << s << endl; // "C-style" 38 | } 39 | 40 | { 41 | char mutable_c_str[] = "another C-style string"; 42 | // string::string(InputIt first, InputIt last) 43 | xstl::string s(std::begin(mutable_c_str) + 8, std::end(mutable_c_str) - 1); 44 | cout << s << endl; // "C-style string" 45 | } 46 | 47 | { 48 | xstl::string const other("Exemplar"); 49 | xstl::string s(other); 50 | cout << s << endl; // "Exemplar" 51 | } 52 | 53 | { 54 | // string::string(string&& str) 55 | //xstl::string s(xstl::string("C++ by ") + xstl::string("example")); 56 | //cout << s << endl; // "C++ by example" 57 | } 58 | 59 | { 60 | // string(std::initializer_list ilist) 61 | //xstl::string s({ 'C', '-', 's', 't', 'y', 'l', 'e' }); 62 | //cout << s << endl; // "C-style" 63 | } 64 | 65 | return 0; 66 | } -------------------------------------------------------------------------------- /STL_re/test/vector_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "../library/xstl_allocator.h" 5 | #include "../library/xstl_vector.h" 6 | using namespace std; 7 | 8 | int main(int argc, char const *argv[]) 9 | { 10 | xstl::vector vec1 = { 1, 2, 3 }; 11 | for (unsigned i = 0; i < vec1.size(); ++i) { 12 | cout << vec1[i] << " "; 13 | } 14 | cout << endl; 15 | 16 | xstl::vector vec2(vec1.begin(), vec1.end()); 17 | for (unsigned i = 0; i < vec2.size(); ++i) { 18 | cout << vec2[i] << " "; 19 | } 20 | cout << endl; 21 | 22 | xstl::vector vec3(vec1); 23 | for (unsigned i = 0; i < vec3.size(); ++i) { 24 | cout << vec3[i] << " "; 25 | } 26 | cout << endl; 27 | 28 | xstl::vector vec4(3, 0); 29 | for (unsigned i = 0; i < vec4.size(); ++i) { 30 | cout << vec4[i] << " "; 31 | } 32 | cout << endl; 33 | 34 | xstl::vector vec5; 35 | vec5 = vec1; 36 | for (unsigned i = 0; i < vec5.size(); ++i) { 37 | cout << vec5[i] << " "; 38 | } 39 | cout << endl; 40 | 41 | xstl::vector vec6; 42 | vec6.assign(5, 1); 43 | for (unsigned i = 0; i < vec6.size(); ++i) { 44 | cout << vec6[i] << " "; 45 | } 46 | cout << endl; 47 | 48 | cout << vec1.at(1) << endl; 49 | cout << vec1[1] << endl; 50 | cout << vec1.front() << endl; 51 | cout << vec1.back() << endl; 52 | int* p = vec1.data(); 53 | *p = 10; 54 | ++p; 55 | *p = 20; 56 | *++p = 100; 57 | 58 | for (xstl::vector::iterator i = vec1.begin(); i != vec1.end(); ++i) { 59 | cout << *i << " "; 60 | } 61 | cout << endl; 62 | 63 | for (xstl::vector::const_iterator i = vec1.cbegin(); i != vec1.cend(); ++i) { 64 | cout << *i << " "; 65 | } 66 | cout << endl; 67 | 68 | for (xstl::vector::reverse_iterator i = vec1.rbegin(); i != vec1.rend(); ++i) { 69 | cout << *i << " "; 70 | } 71 | cout << endl; 72 | 73 | for (xstl::vector::const_reverse_iterator i = vec1.crbegin(); i != vec1.crend(); ++i) { 74 | cout << *i << " "; 75 | } 76 | cout << endl; 77 | 78 | if (!vec1.empty()) { 79 | cout << "vec1 is not empty" << endl; 80 | } 81 | else { 82 | cout << "vec1 is empty" << endl; 83 | } 84 | 85 | cout << vec1.size() << endl; 86 | 87 | cout << vec1.max_size() << endl; 88 | 89 | cout << vec1.capacity() << endl; 90 | 91 | vec1.clear(); 92 | if (vec1.empty()) { 93 | cout << "After clear() the vec1 is empty" << endl; 94 | } 95 | 96 | xstl::vector::iterator i = vec1.begin(); 97 | vec1.insert(i, 100); 98 | cout << vec1[0] << endl; 99 | 100 | vec1.erase(vec1.begin()); 101 | 102 | if (vec1.empty()) { 103 | cout << "After erase() the vec1 is empty" << endl; 104 | } 105 | 106 | vec1.push_back(100); 107 | cout << vec1[0] << endl; 108 | 109 | vec1.pop_back(); 110 | cout << vec1.size() << endl; 111 | 112 | vec2.resize(5); 113 | for (unsigned i = 0; i < vec2.size(); ++i) { 114 | cout << vec2[i] << " "; 115 | } 116 | cout << endl; 117 | 118 | cout << "Before swap ---" << endl; 119 | for (unsigned i = 0; i < vec4.size(); ++i) { 120 | cout << vec4[i] << " "; 121 | } 122 | cout << endl; 123 | cout << "After swap ---" << endl; 124 | vec4.swap(vec2); 125 | for (unsigned i = 0; i < vec4.size(); ++i) { 126 | cout << vec4[i] << " "; 127 | } 128 | cout << endl; 129 | 130 | 131 | return 0; 132 | } -------------------------------------------------------------------------------- /Spider/Taobao/login_taobao.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | 4 | import random 5 | from urllib import request, parse 6 | import time 7 | from selenium import webdriver 8 | from selenium.webdriver.common.action_chains import ActionChains 9 | from selenium.webdriver.firefox.firefox_profile import FirefoxProfile 10 | 11 | class Taobao: 12 | 13 | def __init__(self): 14 | 15 | # 淘宝个人页面 16 | self.url='https://i.taobao.com/my_taobao.htm' 17 | # 淘宝登录页面 18 | self.login_url = "https://login.taobao.com/member/login.jhtml" 19 | # 帐号和密码 20 | self.username = '' 21 | self.password = '' 22 | 23 | self.proxy = '117.36.103.170' 24 | self.port = '8118' 25 | 26 | # Chrome浏览器 27 | # chrome_options = webdriver.ChromeOptions() 28 | # chrome_options.add_argument('--proxy-server=http://' + self.proxy + self.port) 29 | # self.driver = webdriver.Chrome(chrome_options=chrome_options) 30 | 31 | # # Firefox浏览器 32 | profile = FirefoxProfile() 33 | profile.set_preference("network.proxy.type", 1) 34 | profile.set_preference("network.proxy.http", self.proxy) 35 | profile.set_preference("network.proxy.http_port", self.port) 36 | profile.set_preference("network.proxy.share_proxy_settings", True) 37 | self.driver = webdriver.Firefox(profile) 38 | self.driver.implicitly_wait(5) 39 | 40 | # Token 41 | self._tb_token_ = '' 42 | 43 | def login(self): 44 | self.driver.get(self.login_url) 45 | time.sleep(3) 46 | 47 | # 普通登录 48 | self.driver.find_element_by_id("J_Quick2Static").click() 49 | 50 | # 输入帐号密码 51 | username = self.driver.find_element_by_id("TPL_username_1") 52 | username.clear() 53 | username.send_keys(self.username) 54 | password = self.driver.find_element_by_id("TPL_password_1") 55 | password.clear() 56 | password.send_keys(self.password) 57 | 58 | time.sleep(3) 59 | 60 | while True: 61 | try: 62 | # 检验是否需要滑动解锁 63 | check = self.driver.find_element_by_xpath("//*[@id='nocaptcha']") 64 | if not check.is_displayed(): 65 | break 66 | 67 | #定位滑块元素 68 | source = self.driver.find_element_by_xpath("//*[@id='nc_1_n1z']") 69 | time.sleep(3) 70 | 71 | #定义鼠标拖放动作 72 | action = ActionChains(self.driver) 73 | action.click_and_hold(source).perform() 74 | 75 | for index in range(3): 76 | try: 77 | action.move_by_offset(100, 0).perform() #平行移动鼠标 78 | except Exception as e: 79 | print(e) 80 | break 81 | if(index == 3): 82 | action.release() 83 | time.sleep(1) 84 | else: 85 | time.sleep(0.01) #等待停顿时间 86 | 87 | #等待JS认证运行,如果不等待容易报错 88 | time.sleep(3) 89 | #查看是否认证成功,获取text值 90 | text = self.driver.find_element_by_xpath("//*[@id='nc_1__scale_text']/span") 91 | if text.text.startswith(u'验证通过'): 92 | print('成功滑动') 93 | break 94 | if text.text.startswith(u'请点击'): 95 | print('成功滑动') 96 | break 97 | if text.text.startswith(u'请按住'): 98 | continue 99 | except Exception as e: 100 | print(e) 101 | self.driver.find_element_by_xpath("//div[@id='nocaptcha']/div/span/a").click() 102 | 103 | res = "" 104 | while True: 105 | url = self.driver.current_url 106 | if not url.startswith("https://login.taobao.com"): 107 | cookies = self.driver.get_cookies() 108 | for cookie in cookies: 109 | res += cookie.get('name')+'='+cookie.get('value')+';' 110 | res = res[:-1] 111 | break 112 | 113 | try: 114 | self.driver.find_element_by_id("J_SubmitStatic").click() 115 | except Exception as e: 116 | print(e) 117 | 118 | time.sleep(3) 119 | 120 | self.driver.quit() 121 | return res 122 | 123 | # cookie登录 124 | def getInfo(self, cookie): 125 | try: 126 | headers = { 127 | 'Host': 'i.taobao.com', 128 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:53.0) Gecko/20100101 Firefox/53.0', 129 | 'Accept': '*/*', 130 | 'Referer': 'https://www.taobao.com/', 131 | 'Connection': 'keep-alive', 132 | 'Cookie': cookie 133 | } 134 | req = request.Request(url = self.url, headers = headers) 135 | response = request.urlopen(req) 136 | html = response.read().decode() 137 | 138 | # 获取信息的各种操作 139 | print("获取到各种信息...") 140 | with open("rsp.html","w",encoding="utf-8") as f: 141 | f.write(html) 142 | except: 143 | print("获取信息失败...") 144 | 145 | def main(self): 146 | cookie = self.login() 147 | self.getInfo(cookie) 148 | 149 | taobao = Taobao() 150 | taobao.main() 151 | --------------------------------------------------------------------------------