まったりモードでコーディング遊び。
ネタ元 → mapの使い方教えてください
STL/CLRで書いてみた:
#include <cliext/map>
value class key_type {
public:
System::String^ mesh;
System::String^ error;
static bool operator<(key_type^ x, key_type^ y) {
return x->mesh < y->mesh ? true :
( y->mesh < x->mesh ? false : x->error < y->error );
}
};
typedef cliext::map<key_type,int> map_type;
int main() {
System::String^ str;
key_type key;
map_type ary;
System::IO::StreamReader
reader(System::IO::File::OpenRead(L"Data001.txt"));
while ( (str = reader.ReadLine()) != nullptr ) {
if( str->IndexOf(L"メッシュ") == 0 ) {
key.mesh = str->Substring(7,8);
}
if ( str->IndexOf(L"ERROR") == 0 ) {
key.error = str->Substring(6,5);
ary[key]++;
}
}
reader.Close();
for each ( map_type::value_type item in ary) {
System::Console::WriteLine(L"{0}\t{1}\t{2}件",
item->first.mesh, item->first.error, item->second);
}
return 0;
}
残念なのはSTL/CLRの cliext::pair がコンテナの要素になれない(きっとバグ)が
ために value class key_type をこしらえてっとこ。
BCLコレクション: Dictionary 使うとこーなる:
value class key_type {
public:
System::String^ mesh;
System::String^ error;
virtual bool Equals(System::Object^ obj) override {
key_type^ rhs = safe_cast<key_type^>(obj);
return mesh == rhs->mesh && error == rhs->error;
}
virtual int GetHashCode() override {
return (mesh+error)->GetHashCode();
}
};
typedef System::Collections::Generic::Dictionary<key_type,int> map_type;
int main() {
System::String^ str;
key_type key;
map_type ary;
System::IO::StreamReader reader(System::IO::File::OpenRead(L"Data001.txt"));
while ( (str = reader.ReadLine()) != nullptr ) {
if( str->IndexOf(L"メッシュ") == 0 ) {
key.mesh = str->Substring(7,8);
}
if ( str->IndexOf(L"ERROR") == 0 ) {
key.error = str->Substring(6,5);
/* [※] きもちわりー */
if ( ary.ContainsKey(key) ) ary[key]++;
else ary.Add(key,1);
}
}
reader.Close();
for each ( System::Collections::Generic::KeyValuePair<key_type,int>^
item in ary) {
System::Console::WriteLine(L"{0}\t{1}\t{2}件",
item->Key.mesh, item->Key.error, item->Value);
}
return 0;
}
[※] ここがちょいと気になるところ。ContainsKeyによって登録済みかを
判定し、登録されてたら ary[key]++ してる。そのときも要素の検索が
行われるので、都合二回の検索が行われてることになります。
それは無駄ぢゃーんってんで
try {
ary[key]++;
} catch ( System::Collections::Generic::KeyNotFoundException^ ) {
ary.Add(key,1);
}
正常処理に例外使うのもどーかと。C++屋のアタマでは例外処理は
コストが高く、検索二回の方がまだマシかも...とか思っちゃうです。