-
전화번호 무작위 생성개발/C·C++ 2024. 8. 3. 13:57
테스트 삼아 10,000개의 데이터를 선형 자료구조에서 중복 검사까지 하면서 생성해보니 6~7분 정도 걸리는 것 같다. C++에서 제공하는 라이브러리들은 비선형 구조이기 때문에 데이터 삽입과 탐색이 선형 자료구조에 비해 압도적으로 빠르다.
PhoneNumberMaker 클래스에서는 PhoneNumberMakerImpl의 unique_pointer만 들고 있고 실제 구현은 PhoneNumberMakerImpl에서 이뤄진다. 이 구조의 장점은 데이터를 가리키는 포인터와 실제 데이터를 클래스로 구분할 수 있다는 점이다. 별도의 클래스 생성으로 아주 약간 메모리를 더 쓰긴 하지만 차이는 미미하다고 봐도 될 것 같다. PhoneNumberMaker은 일종의 인터페이스만 제공하는 역할을 한다
PhoneNumberMaker
// PhoneNumberMaker.h #pragma once #include "PhoneMakerImpl.h" class PhoneNumberMaker { public: PhoneNumberMaker(); ~PhoneNumberMaker() = default; void GeneratePhoneNumber(int total_number_count, int phone_number_length); const std::unordered_set<std::string>& GetData(); private: std::unique_ptr<PhoneMakerImpl> data_ptr_; }; ///////////////////////////////////////////////////////////////////////////////////////////////////////// // PhoneNumberMaker.cpp #include "PhoneNumberMaker.h" #include <stdexcept> PhoneNumberMaker::PhoneNumberMaker() : data_ptr_(std::make_unique<PhoneNumberMakerImpl>()) {} void PhoneNumberMaker::GeneratePhoneNumber(int total_number_count, int phone_number_length) { if (total_number_count <= 0 || phone_number_length <= 0) { throw std::invalid_argument("total count and phone number length must be positive"); } data_ptr_->GeneratorPhoneNumber(total_number_count, phone_number_length); } const std::unordered_set<std::string>& PhoneNumberMaker::GetData() { return data_ptr_->GetResult(); }
PhoneNumberMakerImpl
// PhoneNumberMakerImpl.h #pragma once #include <unordered_set> #include <string> #include <memory> #include <random> class PhoneNumberMakerImpl { public: PhoneNumberMakerImpl() = default; ~PhoneNumberMakerImpl() = default; void GeneratorPhoneNumber(int total_number_count, int phone_number_length); const std::unordered_set<std::string>& GetResult() const; private: std::string GenerateRandomString(std::mt19937& generator, int phone_number_length); private: std::unordered_set<std::string> result_set_; }; ///////////////////////////////////////////////////////////////////////////////////////////////////////// // PhoneNumberMakerImpl #include "PhoneNumberMakerImpl.h" void PhoneNumberMakerImpl::GeneratorPhoneNumber(int total_number_count, int phone_number_length) { std::random_device rd; std::mt19937 generator(rd()); while (result_set_.size() < total_number_count) { std::string string = GenerateRandomString(generator, phone_number_length); if (result_set_.find(string) == result_set_.end()) { result_set_.insert(string); } } } std::string PhoneNumberMakerImpl::GenerateRandomString(std::mt19937& generator, int phone_number_length) { std::uniform_int_distribution<int> distribution(0, 9); std::string result("010-"); for (int i = 0; i < phone_number_length + 1; ++i) if (phone_number_length - 4 == i) result += "-"; else result += std::to_string(distribution(generator)); return result; } const std::unordered_set<std::string>& PhoneNumberMakerImpl::GetResult() const { return result_set_; }
다음 사용하는 코드다.
#include "PhoneNumberMaker.h" #include <iostream> #include <unordered_set> #include <string> int main() { PhoneNumberMaker number_maker; number_maker.GeneratePhoneNumber(10000, 8); auto& result = number_maker.GetData(); for (const std::string& string : result) { printf("%s\n", string.c_str()); } }
'개발 > C·C++' 카테고리의 다른 글
[윈도우 시스템 프로그래밍] 압축 파일 복사하기 (0) 2024.08.27 std::remove_if, std::erase (0) 2024.08.17 [정렬] 더미 노드와 병합 정렬 (0) 2024.07.18 [디스어셈블리 코드] 간단한 메서드 호출과 동작을 해석해보자 (0) 2024.07.13 메모리 정렬, 패딩 그리고 비트필드(feat. 구조체) (0) 2024.07.07