名前:津田伸秀
サイト: http://vivi.dyndns.org/ twitter:vivisuke
facebook:https://www.facebook.com/nobuhide.tsuda
ぼちぼちソフト作家、年齢不詳のおじさん、自宅研究員(主席)
趣味:テニス、オセロ、思考ゲーム・パズル類
Qt/C++ 使い, 一応webアプリ(PHP, JS, jQ, SQL)も出来るよ
Windows用テキストエディタ ViVi を延々開発中
最近は、世界最速「さくさくエディタ」 開発中だよ
迷走中、お仕事募集中でござるぞ


| ランダムアクセス | 挿入・削除 | |
| vector | O(1) | O(N) |
| list | O(N) | O(1) |
| 2分木 | O(Log N) | O(Log N) |
許されるのは O(N*Log N)まで

list<string> で行管理

list<string>::const_iterator View::line_iterator(int ln){auto itr = lineMgr.cbegin();for(int i = 0; i < ln; ++i) ++itr; // ここが O(L)return itr;}
void View::画面表示(){int ln = vScrollBar->value();auto itr = line_iterator(ln);while( 画面内の場合 ) {*itr を表示;++itr;}}
int ln = vScrollBar->value();while( 画面内の場合 ) {auto itr = line_iterator(ln);*itr を表示;++ln;}
list<string>::const_iterator View::line_iterator(int ln){if( ln が記憶行番行と同じ ) return 記憶イテレータ;if( ln が記憶行番行より大きい ) {if( ln が末尾から遠い )記憶行、イテレータより探す;else末尾から探す;} else {if( ln が先頭から遠い )記憶行、イテレータより探す;else先頭から探す;}itr, ln を記憶;return itr;}

template <typename T> class GapBuffer {T *m_data; // データ領域int m_gapIndex; // ギャップ位置int m_gapSize; // ギャップサイズint m_size; // データサイズ、capacity = size + gapSize };
T GapBuffer::charAt(int pos) const{if( pos >= m_gapIndex ) // pos がギャップ以降pos += m_gapSize; // ギャップサイズ分補正return m_data[pos];}
void GapBuffer::moveGapTo(int pos)
{if( pos < m_gapIndex ) {[pos, m_gapIndex) を [pos+m_gapSize, m_gapIndex+m_gapSize] に移動 m_gapIndex = pos; } else if( pos > m_gapIndex ) { [m_gapIndex+m_gapSize, pos+m_gapSize) を [m_gapIndex, pos) に移動 m_gapIndex = pos; }}

void GapBuffer:erase(int pos){moveGapTo(pos); // ギャップを pos に移動++m_gapSize; // ギャップサイズを増やすだけで文字が消える}

void GapBuffer::insert(int pos, T ch){if( ギャップが無い ) データエリアを(1.5~2倍に)拡張;moveGapTo(pos); // ギャップを pos に移動m_data[m_gapIndex++] = ch; // ギャップ先頭に文字挿入--m_gapSize;}







int lineStartPosition(int ln){if( ln > m_stepIndex )ln += m_stepSize;return m_lv[ln];}
void update(size_t ln, diffptr_t d){
if( !m_stepSize ) { // 差分が 0 の場合
m_stepIndex = ln;
} else if( ln < m_stepIndex ) { // ステップ行以前を編集した場合
while( m_stepIndex > ln ) {
m_lv[m_stepIndex--] -= m_stepSize;
}
} else if( ln > m_stepIndex ) { // ステップ行以降を編集した場合
do {
m_lv[++m_stepIndex] += m_stepSize;
} while( ln > m_stepIndex );
}
m_stepSize += d;
}

