Skip to content

Instantly share code, notes, and snippets.

@hapo31
Created April 21, 2016 14:40
Show Gist options
  • Save hapo31/bd87cc83b4d57d3ad233c257f6d423e3 to your computer and use it in GitHub Desktop.
Save hapo31/bd87cc83b4d57d3ad233c257f6d423e3 to your computer and use it in GitHub Desktop.
#include <string>
#include <fstream>
#include <iostream>
#include <chrono>
#include <vector>
#include <boost/algorithm/string.hpp>
using namespace std;
using namespace std::chrono;
using namespace boost::algorithm;
using tstring = wstring;
//郵便番号と住所を保存するクラス
class Addr
{
public:
Addr(const tstring& number, const tstring& addr) : number_(number), addr_(addr) {}
Addr(const Addr& ) = default;
tstring addr() const { return addr_; }
tstring number() const { return number_; }
private:
tstring addr_;
tstring number_;
};
//時間測定ヘルパークラス
class StopWatch
{
public:
StopWatch()
{
Reset();
}
void Start()
{
start = system_clock::now();
}
void Stop()
{
end = system_clock::now();
}
void Reset()
{
start = time_point_t();
end = time_point_t();
}
auto GetDuration() const
{
return duration_cast<milliseconds>(end - start);
}
private:
using time_point_t = decltype(system_clock::now());
time_point_t start;
time_point_t end;
};
// line: src
// delim: 区切り文字
vector<tstring> split(const tstring& line, char delim)
{
vector<tstring> result;
size_t old = 0;
size_t pos;
while ((pos = line.find_first_of(delim, old)) != tstring::npos)
{
//cout << old << ":" << pos << endl;
result.emplace_back(line.substr(old, pos - old));
old = pos + 1;
}
result.emplace_back(line.substr(old));
return result;
}
int main(const char ** argv, int argc)
{
//wcharじゃないと自作splitが日本語処理に失敗してうまく動かない
const tstring filename = L"KEN_ALL.CSV";
auto ifs = wfstream(filename);
vector<Addr> addrs;
//KEN_ALL.CSVは123925行なのでこんなもんやろ
addrs.reserve(12400);
wcout << filename << "...";
StopWatch stop_watch;
//測定開始
stop_watch.Start();
{
vector<tstring> splited;
vector<tstring> lines;
//KEN_ALL.CSVは123925行なので(ry
lines.reserve(12400);
//一旦全部vectorに読み込んでからsplitする
{
tstring line;
while (getline(ifs, line))
{
lines.emplace_back(line);
}
ifs.close();
}
for (auto&& line : lines)
{
remove_if(line.begin(), line.end(), [](char s) { return s == '\"'; });
//200msほど遅くなるのでクビ
//boost::algorithm::split(splited, line, is_punct());
splited = ::split(line, ',');
tstring num = splited[2];
tstring addr;
//なんかよくわからんけど住所部分が分割されてるので結合する
for_each(&splited[6], &splited[9], [&](const tstring& str) { addr += str; });
addrs.emplace_back(num, addr);
}
stop_watch.Stop();
//測定終了
auto c = stop_watch.GetDuration().count();
//処理結果を適当に出力
cout << addrs.size() << "lines loaded." << endl;
cout << "time:" << c << "ms" << endl;
}
tstring cmd;
do
{
//検索プロンプト
cout << "s[search] q[quit]>";
wcin >> cmd;
if (cmd == L"q") break;
if (cmd == L"s")
{
//郵便番号の一部を入れると適当に探してきて住所を出力
tstring number;
cout << "input search number>";
wcin >> number;
cout << "================================================" << endl;
//測定開始
stop_watch.Start();
vector<Addr> finds;
//一旦全部調べてから表示
for (auto&& addr : addrs)
{
if (addr.number().find(number) != tstring::npos)
{
finds.emplace_back(addr);
}
}
//測定終了
stop_watch.Stop();
//検索結果と時間表示
for (auto&& addr : finds)
{
wcout << addr.addr() << endl;
}
cout << "time:" << stop_watch.GetDuration().count() << endl;
}
} while (true); //一生やってろ
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment