2012-09-27

SCIP in C++11 ― 3.3.1節その1


可変リスト構造と問題3.123.14

3.2節と問題3.93.11C++コードを書くわけでないので略。
環境モデルの絵はどうもわかりにくいなあ。
3.3節のリストの図は分かりやすいんだけど。

consの代入版は5章で出てくるみたいだが、
そもそも今までのconsがすでに代入版と同じ事をしているので、
ここは今までのconsでいい。

set-car!set-cdr!によって、どこからも指されていないオブジェクトが発生しうるわけで、
lispならガベージコレクションしてくれるが、C++ではそうはいかない。
set-car!set-cdr!については、一度Listの内部のlist<List>で、
1要素をpop_frontしたろ、第2要素から最後までをeraseしたりしているので、
そこで参照カウント見て、浮いたオブジェクトなら消してくれるはず、だぶん。

Listのメンバ関数に代入用のをいろいろ実装した。
Listの内部表現はだいぶSchemeと違い、内部的にはstd::listなので、
普通にlistのメンバ関数を使う。難しくはないので略。
例えばappend!last-pair経由でなく、
Listのメンバ関数として実装したappend
(内部的にはstd::listsplice)で別途実装。

これに伴い問題3.13は、
Schemeではポインタの循環になってしまって実行できないのはわかるが、
こちらの実装ではそうならず単に2つのリストが連結されるだけ。
ここの違いはあまり気にする必要がある気がしない。今のところは・・・。
なお問題3.123.14もコードだけ。
問題3.14mysteryは破壊的reverseとでもいうべきか。
最後にvの要素がひとつ残っちゃうのが惜しい感じ。

----
void setCarInsert(const List& _listTree, const List& _newCar)
{
    const_cast<List&>(_listTree)->removeFirstElement();
    const_cast<List&>(_listTree)->addElement(_newCar);
}

void setCdrInsert(const List& _listTree, const List& _newCdr)
{
    if(!_listTree->isNull()){
        _listTree->removeExceptFirstElement();
    }
    _listTree->append(_newCdr);
}

const List appendInsert(const List& x, const List& y)
{
    x->append(y);
    return(x);
}

const List makeCycle(const List& x)
{
    x->append(x);
    return(x);
}

const List mystery(const List& x)
{
    function<List(List,List)> loop;
    loop=[&loop](const List& x, const List& y)
        {
            if(isNull(x)){return(y);}
            const auto temp(cdr(x));
            setCdrInsert(x,y);
            return(loop(temp,x));
        };
    return(loop(x,makeList()));
}

//---------abstraction barrier---------
int main(int argc, char** argv)
{
    const auto x1(makeList(makeList("a","b"),"c","d"));
    const auto y1(makeList("e","f"));
    cout<<"x1 = "<<listString(x1)<<endl;
    cout<<"y1 = "<<listString(y1)<<endl;
    cout<<"(set-car! x1 y1)"<<endl;
    setCarInsert(x1,y1);
    cout<<"x1 = "<<listString(x1)<<endl;

    const auto x2(makeList(makeList("a","b"),"c","d"));
    const auto y2(makeList("e","f"));
    cout<<"x2 = "<<listString(x2)<<endl;
    cout<<"y2 = "<<listString(y2)<<endl;
    cout<<"(set-car! x2 y2)"<<endl;
    setCdrInsert(x2,y2);
    cout<<"x2 = "<<listString(x2)<<endl;

    cout<<endl<<"Excersize 3.12:"<<endl;
    const auto x3(makeList("a","b"));
    const auto y3(makeList("c","d"));
    cout<<"x3 = "<<listString(x3)<<endl;
    cout<<"y3 = "<<listString(y3)<<endl;
    const auto z3(append(x3,y3));
    cout<<"z3 = (append x3 y3) = "<<listString(z3)<<endl;
    cout<<"(cdr x3) = "<<listString(cdr(x3))<<endl;
    const auto w3(appendInsert(x3,y3));
    cout<<"w3 = (append! x3 y3) = "<<listString(w3)<<endl;
    cout<<"(cdr x3) = "<<listString(cdr(x3))<<endl;

    cout<<endl<<"Excersize 3.14:"<<endl;
    const auto v(makeList("a","b","c","d"));
    cout<<"v = "<<listString(v)<<endl;
    const auto w(mystery(v));
    cout<<"w = (mystery v) = "<<listString(w)<<endl;
    cout<<"v = "<<listString(v)<<endl;
   

    return(0);
}
----
出力
----
x1 = (('a 'b) 'c 'd)
y1 = ('e 'f)
(set-car! x1 y1)
x1 = (('e 'f) 'c 'd)
x2 = (('a 'b) 'c 'd)
y2 = ('e 'f)
(set-car! x2 y2)
x2 = (('a 'b) 'e 'f)

Excersize 3.12:
x3 = ('a 'b)
y3 = ('c 'd)
z3 = (append x3 y3) = ('a 'b 'c 'd)
(cdr x3) = ('b)
w3 = (append! x3 y3) = ('a 'b 'c 'd)
(cdr x3) = ('b 'c 'd)

Excersize 3.13:
z4 = (make-cycle (list 'a 'b 'c)) = ('a 'b 'c 'a 'b 'c)

Excersize 3.14:
v = ('a 'b 'c 'd)
w = (mystery v) = ('d 'c 'b 'a)
v = ('a)

0 件のコメント :

コメントを投稿