#include <iostream>
#include <fstream>
#include <list>
#include <vector>
#include <algorithm>
#include <iterator>
#include <functional>
#include <string>
#include <sstream>
using namespace std;
static int const RANGE = 5;
static int const COLSPAN = 10;
static char const DERIM = ',';
// スプリッタ
template < char T >
struct IsChar : public unary_function< char, bool > {
result_type const operator() ( argument_type const &c ) const {
// return isspace( c );
return c == T;
}
};
template < typename Out > Out &split( string const &s, Out &os ) {
typedef string::const_iterator iter;
iter i = s.begin();
while ( i != s.end() ) {
i = find_if( i, s.end(), not1( IsChar< DERIM >() ) );
iter j = find_if( i, s.end(), IsChar< DERIM >() );
if ( i != s.end() ) {
// cout << string( i, j ) << " ";
os.push_back( string( i, j ) );
}
i = j;
}
return os;
}
// 検索
template < typename T > int adept( T ci, T const &end ) {
int bw( 0 );
for ( int i = 0; i != RANGE; ++i ) {
if ( ++ci == end ) {
break;
} else {
// cout << *ci << " ";
if ( *ci > 0 ) {
bw = *ci;
break;
}
}
}
// cout << "\t候補: " << bw << endl;
return bw;
}
// 列データの読み込み
bool read( istream &in, vector< list< int > > &vls ) {
string s;
if ( getline( in, s ) ) {
vector< string > vs;
split( s, vs );
for ( int i = 0; i != COLSPAN; ++i ) {
stringstream ss;
int n;
ss.str("");
ss << vs[i];
ss >> n;
// cout << n << " ";
vls[ i ].push_back( n );
if ( vls[ i ].size() > RANGE * 2 + 1 ) {
vls[ i ].pop_front();
}
}
return true;
}
return false;
}
int main() {
ifstream in( "suuchi.csv" );
ofstream os( "result.csv" );
// 初期化
vector < list< int > > vls;
for ( int i = 0; i != COLSPAN; ++i ) {
vls.push_back( ( list< int >() ) );
}
vector < list< int >::iterator > viter;
// const_iteratorはconstなコンテナ以外には使わないほうがいい
// constなコンテナの ::end() や ::rend() const_iterator を返すが
// 非constなコンテナのそれは単なる iterator しか返さないため
// わざわざ const_iterator に変換する必要を生じるからだ
// 分析
// 分析対象行よりもRANGE行分だけ先読みする。
// このため、ファイルの終端に達したあとも、RANGE回だけ余計にループする必要がある。
int countdown = RANGE, counter( 0 );
while( countdown != 0 ) {
if ( countdown == RANGE ) {
if ( !read( in, vls ) ) {
--countdown;
}
} else {
--countdown;
}
// cout << countdown;
if ( counter < RANGE ) {
if ( counter == 0 ) {
for ( int i = 0; i != COLSPAN; ++i ) {
viter.push_back( vls[i].begin() );
}
}
++counter;
continue;
}
for ( int i = 0; i != COLSPAN; ++i ) {
// cout << "値:" << *viter[i] << "\n";
// 条件分岐
int result = *viter[i];
if ( result < 0 ) {
// iteratorのreverse_iteratorへの変換はポイント位置が一つ前に移動するので注意
int fw = adept( --list< int >::reverse_iterator( viter[i] ), vls[i].rend() );
int bw = adept( viter[i], vls[i].end() );
if ( bw == 0 ) {
if ( fw > 0 ) {
result = fw;
}
} else {
if ( fw == 0 ) {
result = bw;
} else {
result = ( fw + bw ) / 2;
}
}
}
// cout << "\t\t結果:" << result << endl;
if ( i != 0 ) { os << ","; }
os << result;
++viter[i];
}
os << "\n";
}
os << flush;
}