这是我的密码:
public class NList : SExp, IEnumerable<Object>
{
private Object _car;
private NList _cdr;
IEnumerator<Object> IEnumerable<Object>.GetEnumerator()
{
return new NListEnumerator(this);
}
IEnumerator IEnumerable.GetEnumerator()
{
return new NListEnumerator(this);
}
public object car ()
{
return _car;
}
public NList cdr ()
{
return _cdr;
}
public NList cons (object o)
{
return new NList(o, this);
}
public NList() // empty list
{
}
public NList(List<Object> lst)
{
if (lst.Count == 1)
{
this._car = lst[0];
this._cdr = null;
}
else
{
this._car = lst[0];
this._cdr = new NList(lst.GetRange(1, lst.Count - 1));
}
}
public NList (Object fst)
{
this._car = fst;
this._cdr = null;
}
public NList (Object fst, NList rst)
{
this._car = fst;
this._cdr = rst;
}
public object Last()
{
NList list = this;
while(list.cdr() != null)
{
list = list.cdr();
}
return list.car();
}
public int Count { get { return this.length(); } }
public int length()
{
if (this._car == null && this._cdr == null) return 0;
NList list = this;
int len = 1;
while(list.cdr() != null)
{
list = list.cdr();
len++;
}
return len;
}
public NList cddr()
{
return this.cdr().cdr();
}
public object cadr()
{
return this.cdr().car();
}
public object elm(int k)
{
if(k == 0) return car();
NList list = cdr();
for(int i = 1; i < k; i++, list = list.cdr()) ;
return list.car();
}
public NList append(NList lst)
{
NList lst1 = this;
NList lst2 = lst;
if (this._car == null && this._cdr == null)
return lst2;
foreach(var e in Reverse(lst1))
{
lst2 = lst2.cons(e);
}
return lst2;
//return lst1.Aggregate(lst2, (NList acc, object b) => acc);
}
public static NList Reverse(NList lst)
{
NList l = lst;
NList res = null;
while(l != null)
{
res = new NList(l.car(), res);
l = l.cdr();
}
return res;
}
public override string ToString ()
{
if (this._car == null && this._cdr == null) return "()";
string s = "(";
for(int i = 0; i<this.Count-1; i++)
{
s+=this.elm(i).ToString() + " ";
}
s+=this.Last().ToString() + ")";
return s;
}
public NObj[] ToNObjArray()
{
NObj[] a = new NObj[this.Count];
int k = 0;
foreach (var e in this)
{
a[k] = (e as NObj);
k++;
}
return a;
}
public object[] ToArray()
{
object[] a = new object[this.Count];
int k = 0;
foreach(var e in this)
{
a[k] = e;
k++;
}
return a;
}
}
public class NListEnumerator : IEnumerator<Object>, IEnumerator
{
NList list;
NList tmp;
public void Dispose()
{
}
public NListEnumerator(NList list)
{
this.list = list;
this.tmp = list.cons(null);
}
public object Current
{
get { return tmp.car(); }
}
public bool MoveNext()
{
tmp = tmp.cdr();
return (tmp != null);
}
public void Reset()
{
tmp = list.cons(null);
}
}我有点担心,我没有单独的类对简单(例如:非正确终止的列表,如(1 )。2),(a )(B)。我应该创建一个单独的类(以及两个类的接口),还是应该尝试扩展这个类?
蒂娅。
发布于 2011-04-13 06:20:33
在处理空列表时存在严重缺陷。用户可能期望这些定义是等价的,但它们不是:
Nlist n1 = new NList("x");
Nlist n2 = new NList("x", new NList());我强烈建议为空列表(可能是单例)设置一个显式子类,并禁止_cdr为null。
发布于 2011-04-13 08:44:17
我应该创建一个单独的类(以及两个类的接口),还是应该尝试扩展这个类?
在实LISP中,列表没有单独的表示形式。实际上,List只是一串虚线对。因此,我认为,最好修改原始类,并允许将list的cdr分配给NList以外的任何东西。
顺便说一句,为什么不直接使用属性:
public object car ()
{
return _car;
}
public NList cdr ()
{
return _cdr;
}另外,如果您已经有了类SExp,那么在这里返回SExp而不是对象可能是个好主意。
https://codereview.stackexchange.com/questions/1830
复制相似问题