ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 전화번호 무작위 생성
    개발/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());
    	}
    }

    댓글

Designed by Tistory.