可変リスト構造と問題3.12~3.14
3.2節と問題3.9~3.11はC++コードを書くわけでないので略。
環境モデルの絵はどうもわかりにくいなあ。
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::listのsplice)で別途実装。
これに伴い問題3.13は、
Schemeではポインタの循環になってしまって実行できないのはわかるが、
こちらの実装ではそうならず単に2つのリストが連結されるだけ。
ここの違いはあまり気にする必要がある気がしない。今のところは・・・。
なお問題3.12、3.14もコードだけ。
問題3.14のmysteryは破壊的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 件のコメント :
コメントを投稿