郵便番号検索の実用化 [C++]
別記事〔郵便番号の検索〕で、日本郵便のWEBからダウンロードした郵便番号データを、Rubyのスクリプトで書いたプログラムで検索する事例を紹介しました。
でも、郵便番号からの検索しかできず、あまり実用性がないのも事実です。組み込むデータベースのほうを、もっと検索機能などが豊富なものに出来ないかと考えましたが、意外と面倒です。
そこで、C++を使って、メモリーに全県データを読み込み、任意の文字列(「,」で区切れば二個まで指定可能)を含むデータを検索して表示するプログラムを書いてみましたので、紹介します。
郵便番号(7桁)を指定して表示するだけではなく、住所に含まれる文字列を入力して候補を絞り込むことが可能です。
日本郵便のWEBから最新の全県版の郵便番号データをダウンロードさえすれば、プログラムは修正しなくても、最新の郵便番号が検索できますので実用性は高いと思います。
(by 心如)
───〔表示例〕───────────────────────────
[長崎,平和]、[広島,平和]の組合せはHitしますが、
[沖縄,平和]の組合せはHitしませんでした…^^;
───〔プログラム例〕───────────────────────────
// 2012.04.18 ───── coded by 心如
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
using namespace std;
// 文字列を、指定された文字で分割し、文字列の配列にする
vector<string> split(string s, char c){
string::size_type i, tp;
string temp;
vector<string> data;
tp = 0;
for(i = 0; i < s.size(); i++){
if(s[i] == c){
temp = s.substr(tp, i - tp);
data.push_back(temp);
tp = i + 1;
}
}
temp = s.substr(tp);
data.push_back(temp);
return data;
}
string strip_s(string s){
return s.substr(1, s.size() - 2);
}
// 郵便番号、住所データの表示
void print_jzc(string row){
vector<string> tmps = split(row, ',');
cout << tmps[0] << ",";
cout << tmps[1] << ",";
cout << strip_s(tmps[2]) << ",";
cout << strip_s(tmps[6]) << strip_s(tmps[7]);
if(tmps[8].find("以下に") == -1){
cout << strip_s(tmps[8]);
}
}
inline float get_sec(){
return (float)clock() / CLOCKS_PER_SEC;
}
int main(){
int n;
string temp, ss1, ss2;
float wsec;
vector<string> data;
temp = "D:/Data/KEN_ALL.CSV"; //調べるファイルの指定
ifstream f(temp.c_str());
//指定されたファイルを1行ずつ読み込んでそれをdataに格納
n = 0;
while(getline(f,temp)){
data.push_back(temp);
n++;
}
printf("[%dlines loaded, %.3f sec.]\n", n, get_sec());
// 検索処理
do{
cout << "・探す文字列の入力(xxx:終了)>";
cin >> temp;
if(temp == "xxx") break; // 終了判定
n = 0;
wsec = get_sec();
ss1 = temp;
ss2 = temp;
string::size_type m = temp.find(",");
if(m != -1){
ss1 = ss1.substr(0, m);
ss2 = ss2.substr(m + 1);
}
for(vector<string>::size_type i = 0; i < data.size(); i++){
if(data[i].find(ss1) != -1 && data[i].find(ss2) != -1){
printf("%06d: ", i);
print_jzc(data[i]);
cout << endl;
n++;
}
}
cout << "[" << ss1;
if(ss1 != ss2){
cout << "," << ss2;
}
printf(": %d Hit](%.3fsec.)\n\n", n, get_sec() - wsec);
}while(1);
}
コメント 0