C# 错误:未实现接口成员';System.IComparable.CompareTo(对象)
我有一个带有.IComparable接口的类,但在编译时出错 请帮我看一下,给我一个解决方案C# 错误:未实现接口成员';System.IComparable.CompareTo(对象),c#,compiler-errors,icomparer,C#,Compiler Errors,Icomparer,我有一个带有.IComparable接口的类,但在编译时出错 请帮我看一下,给我一个解决方案 错误1“phyl.DnaSequenceTree.Node”未实现接口成员“System.IComparable.CompareTo(对象)”的 使用系统; 使用System.Collections.Generic; 使用System.Linq; 使用系统文本; /** *类DnaSequenceTree封装了一个有根的DNA分叉树 *序列。树中的每个节点都由从0到0的索引指定 *N&负;1,其中N
错误1“phyl.DnaSequenceTree.Node”未实现接口成员“System.IComparable.CompareTo(对象)”的
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
/**
*类DnaSequenceTree封装了一个有根的DNA分叉树
*序列。树中的每个节点都由从0到0的索引指定
*N&负;1,其中N是树的长度。树的
*容量C是最大节点数(当
*这棵树已经建成)。对于包含M个尖端节点的树,该树的
*容量必须为C≥2M&负;1.
*
*@作者王克拉克
*@version 09-Feb-2015
*/
名称空间物理
{
公共类DnaSequenceTree
{
//数组中的额外填充量。
专用静态int PAD=32;
//隐藏的助手类。
//有关树中一个节点的信息。
私有类节点:IComparable
{
//父节点索引,或根节点为-1。
公共int家长;
//第一个子节点索引,或tip节点为-1。
公共卫生服务1;
//第二个子节点索引,或tip节点的-1。
公共卫生服务2;
//与此节点关联的DNA序列,如果没有,则为空。
公共数据序列;
//此节点与其父节点之间的分支长度,如果没有,则为null。
公共双车道;
//额外的填充以避免缓存干扰。
私人长p0,p1,p2,p3,p4,p5,p6,p7;
私人长p8、p9、pa、pb、pc、pd、pe、pf;
//构造一个新的空节点。
公共节点()
{
清除();
}
//清除此节点。
公共空间清除()
{
this.parent=-1;
这个.child1=-1;
这是1.2=-1;
this.seq=null;
这个.brlen=1;
}
//将此节点设置为给定节点的副本。
公共无效副本(节点)
{
this.parent=node.parent;
this.child1=node.child1;
this.child2=node.child2;
this.seq=node.seq;
this.brlen=node.brlen;
}
//将此节点与给定节点进行比较。顺序为降序
//分支长度的顺序。没有分支长度的节点使用默认值
//分支长度为0。
公共整数比较(节点)
{
double brlen1=this.brlen==null?0.0:this.brlen;
double brlen2=node.brlen==null?0.0:node.brlen;
如果(brlen1>brlen2)返回-1;
否则如果(brlen1i | i>=myLength)
{
抛出新ArgumentException(“DnaSequenceTree.parent():索引(“+i+”)超出范围”);
}
返回myNode[i]。父节点;
}
/**
*返回此树中给定节点的第一个子节点。
*
*@param i节点索引,0≤i≤N&减;1。
*
*@返回节点i的第一个子节点的索引,如果是节点,则返回&减号;1
*i是一个尖端节点。
*
*@exception IndexOutOfBoundsException
*(未选中的异常)如果我超出边界,则引发。
*/
公共int儿童1(int i)
{
如果(0>i | i>=myLength)
{
抛出新的ArgumentException(“DnaSequenceTree.child1():索引(“+i+”)超出范围”);
}
重新
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
/**
* Class DnaSequenceTree encapsulates a rooted bifurcating tree of DNA
* sequences. Each node in the tree is designated by an index from 0 to
* <I>N</I>−1, where <I>N</I> is the tree's <I>length.</I> The tree's
* <I>capacity</I> <I>C</I> is the maximum number of nodes (specified when the
* tree was constructed). For a tree to hold <I>M</I> tip nodes, the tree's
* capacity must be <I>C</I> ≥ 2<I>M</I> − 1.
*
* @author Clark Wang
* @version 09-Feb-2015
*/
namespace phyl
{
public class DnaSequenceTree
{
// Amount of extra padding in arrays.
private static int PAD = 32;
// Hidden helper classes.
// Information about one node in the tree.
private class Node : IComparable
{
// Parent node index, or -1 for the root node.
public int parent;
// First child node index, or -1 for a tip node.
public int child1;
// Second child node index, or -1 for a tip node.
public int child2;
// DNA sequence associated with this node, or null if none.
public DnaSequence seq;
// Branch length between this node and its parent, or null if none.
public Double brlen;
// Extra padding to avert cache interference.
private long p0, p1, p2, p3, p4, p5, p6, p7;
private long p8, p9, pa, pb, pc, pd, pe, pf;
// Construct a new, empty node.
public Node()
{
clear();
}
// Clear this node.
public void clear()
{
this.parent = -1;
this.child1 = -1;
this.child2 = -1;
this.seq = null;
this.brlen = 1;
}
// Set this node to be a copy of the given node.
public void copy (Node node)
{
this.parent = node.parent;
this.child1 = node.child1;
this.child2 = node.child2;
this.seq = node.seq;
this.brlen = node.brlen;
}
// Compare this node with the given node. The ordering is descending
// order of branch length. A node with no branch length uses a default
// branch length of 0.
public int compareTo(Node node)
{
double brlen1 = this.brlen == null ? 0.0 : this.brlen;
double brlen2 = node.brlen == null ? 0.0 : node.brlen;
if (brlen1 > brlen2) return -1;
else if (brlen1 < brlen2) return +1;
else return 0;
}
}
// Array of nodes.
Node[] myNode;
// Tree capacity (maximum number of nodes).
private int myCapacity;
// Tree length (actual number of nodes).
private int myLength;
// Index of root node, or -1 if tree is empty.
private int myRoot;
// Extra padding to avert cache interference.
private long p0, p1, p2, p3, p4, p5, p6, p7;
private long p8, p9, pa, pb, pc, pd, pe, pf;
public DnaSequenceTree (int C)
{
if (C < 0)
{
throw new ArgumentException
("DnaSequenceTree(): C (= " + C + ") < 0, illegal");
}
int temp = C + PAD;
myNode = new Node[temp];
for (int i = 0; i < C; ++i)
{
myNode[i] = new Node();
}
myCapacity = C;
myLength = 0;
myRoot = -1;
}
// Exported operations.
/**
* Returns the capacity of this tree.
*
* @return Capacity <I>C</I> (maximum number of nodes).
*/
public int capacity()
{
return myCapacity;
}
/**
* Returns the length of this tree.
*
* @return Length <I>N</I> (number of nodes).
*/
public int length()
{
return myLength;
}
/**
* Returns the root of this tree.
*
* @return Index of the root node, or −1 if this tree is empty.
*/
public int root()
{
return myRoot;
}
/**
* Returns the parent of the given node in this tree.
*
* @param i Node index, 0 ≤ <TT>i</TT> ≤ <I>N</I>−1.
*
* @return Index of the parent of node <TT>i</TT>, or −1 if node
* <TT>i</TT> is the root node.
*
* @exception IndexOutOfBoundsException
* (unchecked exception) Thrown if <TT>i</TT> is out of bounds.
*/
public int parent
(int i)
{
if (0 > i || i >= myLength)
{
throw new ArgumentException("DnaSequenceTree.parent(): Index (= " + i + ") out of bounds");
}
return myNode[i].parent;
}
/**
* Returns the first child of the given node in this tree.
*
* @param i Node index, 0 ≤ <TT>i</TT> ≤ <I>N</I>−1.
*
* @return Index of the first child of node <TT>i</TT>, or −1 if node
* <TT>i</TT> is a tip node.
*
* @exception IndexOutOfBoundsException
* (unchecked exception) Thrown if <TT>i</TT> is out of bounds.
*/
public int child1 (int i)
{
if (0 > i || i >= myLength)
{
throw new ArgumentException("DnaSequenceTree.child1(): Index (= " + i + ") out of bounds");
}
return myNode[i].child1;
}
/**
* Returns the second child of the given node in this tree.
*
* @param i Node index, 0 ≤ <TT>i</TT> ≤ <I>N</I>−1.
*
* @return Index of the second child of node <TT>i</TT>, or −1 if
* node <TT>i</TT> is a tip node.
*
* @exception IndexOutOfBoundsException
* (unchecked exception) Thrown if <TT>i</TT> is out of bounds.
*/
public int child2 (int i)
{
if (0 > i || i >= myLength)
{
throw new ArgumentException ("DnaSequenceTree.child2(): Index (= " + i + ") out of bounds");
}
return myNode[i].child2;
}
/**
* Returns the DNA sequence associated with the given node in this tree.
*
* @param i Node index, 0 ≤ <TT>i</TT> ≤ <I>N</I>−1.
*
* @return DNA sequence associated with node <TT>i</TT>, or null if no DNA
* sequence is associated.
*
* @exception IndexOutOfBoundsException
* (unchecked exception) Thrown if <TT>i</TT> is out of bounds.
*/
public DnaSequence seq (int i)
{
if (0 > i || i >= myLength)
{
throw new ArgumentException ("DnaSequenceTree.seq(): Index (= " + i + ") out of bounds");
}
return myNode[i].seq;
}
/**
* Set the DNA sequence associated with the given node in this tree.
* <P>
* <I>Note:</I> The tree contains a reference to (not a copy of)
* <TT>seq</TT>.
*
* @param i Node index, 0 ≤ <TT>i</TT> ≤ <I>N</I>−1.
* @param seq DNA sequence associated with node <TT>i</TT>, or null if no
* DNA sequence is associated.
*
* @exception IndexOutOfBoundsException
* (unchecked exception) Thrown if <TT>i</TT> is out of bounds.
*/
public void seq (int i,DnaSequence seq)
{
if (0 > i || i >= myLength)
{
throw new ArgumentException ("DnaSequenceTree.seq(): Index (= " + i + ") out of bounds");
}
myNode[i].seq = seq;
}
/**
* Returns the branch length associated with the given node in this tree.
*
* @param i Node index, 0 ≤ <TT>i</TT> ≤ <I>N</I>−1.
*
* @return Branch length between node <TT>i</TT> and its parent, or null if
* no branch length is associated.
*
* @exception IndexOutOfBoundsException
* (unchecked exception) Thrown if <TT>i</TT> is out of bounds.
*/
public Double branchLength (int i)
{
if (0 > i || i >= myLength)
{
throw new ArgumentException ("DnaSequenceTree.branchLength(): Index (= " + i + ") out of bounds");
}
return myNode[i].brlen;
}
/**
* Set the branch length associated with the given node in this tree.
*
* @param i Node index, 0 ≤ <TT>i</TT> ≤ <I>N</I>−1.
* @param brlen Branch length between node <TT>i</TT> and its parent, or
* null if no branch length is associated.
*
* @exception IndexOutOfBoundsException
* (unchecked exception) Thrown if <TT>i</TT> is out of bounds.
*/
public void branchLength (int i,Double brlen)
{
if (0 > i || i >= myLength)
{
throw new ArgumentException("DnaSequenceTree.branchLength(): Index (= " + i + ") out of bounds");
}
myNode[i].brlen = brlen;
}
/**
* Clear this DNA sequence tree.
*/
public void clear()
{
int C = myCapacity;
for (int i = 0; i < C; ++i)
{
myNode[i].clear();
}
myLength = 0;
myRoot = -1;
}
/**
* Set this DNA sequence tree to be a copy of the given tree. This tree's
* capacity is unchanged and must be greater than or equal to the given
* tree's length. This tree's length, DNA sequences, and branch lengths
* become the same as <TT>tree</TT>.
* <P>
* <I>Note:</I> This tree contains references to (not copies of) the DNA
* sequences in <TT>tree</TT>.
*
* @param tree DNA sequence tree.
*
* @exception NullPointerException
* (unchecked exception) Thrown if <TT>tree</TT> is null.
* @exception IllegalArgumentException
* (unchecked exception) Thrown if this tree's capacity is less than
* <TT>tree</TT>'s length.
*/
public void copy (DnaSequenceTree tree)
{
// Verify preconditions.
if (this.myCapacity < tree.myLength)
{
throw new ArgumentException ("DnaSequenceTree.copy(): Capacity (= " + this.myCapacity + ") too small");
}
int C = this.myCapacity;
int N = tree.myLength;
// Copy <tree>'s nodes to this tree.
for (int i = 0; i < N; ++i)
{
this.myNode[i].copy(tree.myNode[i]);
}
// Clear any unused nodes in this tree.
for (int i = N; i < C; ++i)
{
this.myNode[i].clear();
}
// Update this tree's length and root.
this.myLength = N;
this.myRoot = tree.myRoot;
}
/**
* Set this DNA sequence tree to be the join of the two given trees. This
* tree's capacity is unchanged and must be greater than or equal to
* <I>N</I><SUB>1</SUB> + <I>N</I><SUB>2</SUB> + 1,
* <I>Note:</I> This method may alter the index of this tree's root node.
*
* @param tree1 First DNA sequence tree.
* @param tree2 Second DNA sequence tree.
*
* @exception NullPointerException
* (unchecked exception) Thrown if <TT>tree1</TT> is null. Thrown if
* <TT>tree2</TT> is null.
* @exception IllegalArgumentException
* (unchecked exception) Thrown if this tree's capacity is less than
* <I>N</I><SUB>1</SUB> + <I>N</I><SUB>2</SUB> + 1.
*/
public void join (DnaSequenceTree tree1,DnaSequenceTree tree2)
{
// Verify preconditions.
int N1 = tree1.myLength;
int N2 = tree2.myLength;
if (this.myCapacity < N1+N2+1)
{
throw new ArgumentException ("DnaSequenceTree.join(): Capacity (= "+this.myCapacity+") too small");
}
int C = this.myCapacity;
// Set up this tree's root node at index 0.
Node root = this.myNode[0];
root.parent = -1;
root.child1 = tree1.myRoot + 1;
root.child2 = tree2.myRoot + N1 + 1;
root.seq = null;
root.brlen = 1;
// Copy <tree1>'s nodes to this tree. Must offset <tree1>'s node
// indexes by 1.
for (int i = 0; i < N1; ++ i)
{
Node thisnode = this.myNode[i+1];
Node treenode = tree1.myNode[i];
thisnode.parent =
treenode.parent == -1 ? 0 : treenode.parent + 1;
thisnode.child1 =
treenode.child1 == -1 ? -1 : treenode.child1 + 1;
thisnode.child2 =
treenode.child2 == -1 ? -1 : treenode.child2 + 1;
thisnode.seq = treenode.seq;
thisnode.brlen = treenode.brlen;
}
// Copy <tree2>'s nodes to this tree. Must offset <tree2>'s node
// indexes by N1 + 1.
for (int i = 0; i < N2; ++ i)
{
Node thisnode = this.myNode[i+N1+1];
Node treenode = tree2.myNode[i];
thisnode.parent =
treenode.parent == -1 ? 0 : treenode.parent + N1 + 1;
thisnode.child1 =
treenode.child1 == -1 ? -1 : treenode.child1 + N1 + 1;
thisnode.child2 =
treenode.child2 == -1 ? -1 : treenode.child2 + N1 + 1;
thisnode.seq = treenode.seq;
thisnode.brlen = treenode.brlen;
}
// Clear any unused nodes in this tree.
for (int i = N1 + N2 + 1; i < C; ++i)
{
this.myNode[i].clear();
}
// Update this tree's length and root.
this.myLength = N1 + N2 + 1;
this.myRoot = 0;
}
/*
* * <I>Note:</I> This tree contains a reference to (not a copy of)
* <TT>seq</TT>.
* <P>
* <I>Note:</I> This method may alter the index of this tree's root node.
*
* @param i Node index, 0 ≤ <TT>i</TT> ≤ <I>N</I>−1.
* @param seq DNA sequence associated with new tip node, or null if no DNA
* sequence is associated.
*
* @return Index of new tip node.
*
* @exception IllegalArgumentException
* (unchecked exception) Thrown if this tree's capacity is less than
* this tree's length + 2.
* @exception IndexOutOfBoundsException
* (unchecked exception) Thrown if <TT>i</TT> is out of bounds.
*/
public int add(int i,DnaSequence seq)
{
// Case 1: This tree is empty.
if (myLength == 0)
{
// Verify preconditions.
if (myCapacity < 1)
{
throw new ArgumentException ("DnaSequenceTree.add(): Capacity (= "+myCapacity+ ") < 1, illegal");
}
// Set up root node with <seq>.
Node root = this.myNode[0];
root.parent = -1;
root.child1 = -1;
root.child2 = -1;
root.seq = seq;
root.brlen = 1;
// Update this tree's length and root.
myLength = 1;
myRoot = 0;
return 0;
} else
{
// Verify preconditions.
if (myCapacity < myLength + 2)
{
throw new ArgumentException ("DnaSequenceTree.add(): Capacity (= " + myCapacity + ") too small");
}
if (0 > i || i >= myLength)
{
throw new ArgumentException ("DnaSequenceTree.add(): Index (= " + i + ") out of bounds");
}
// Set up new interior node.
int parent_i = myNode[i].parent;
Node newnode = myNode[myLength];
newnode.parent = parent_i;
newnode.child1 = i;
newnode.child2 = myLength + 1;
newnode.seq = null;
newnode.brlen = 1;
// Splice new interior node between node <i> and node <i>'s parent.
// Update this tree's root if necessary.
if (parent_i == -1)
{
myRoot = myLength;
}
else if (myNode[parent_i].child1 == i)
{
myNode[parent_i].child1 = myLength;
}
else
{
myNode[parent_i].child2 = myLength;
}
myNode[i].parent = myLength;
// Set up new tip node with <seq>.
Node newtip = myNode[myLength + 1];
newtip.parent = myLength;
newtip.child1 = -1;
newtip.child2 = -1;
newtip.seq = seq;
newtip.brlen = 1;
// Update this tree's length.
myLength += 2;
return myLength - 1;
}
}
public DnaSequenceList toList()
{
// Make a list of just the tip nodes.
List<Node> nodelist = new List<Node>();
int N = myLength;
for (int i = 0; i < N; ++ i)
{
Node node = myNode[i];
if (node.child1 == -1) nodelist.Add (node);
}
// Sort the node list.
//Collections.sort (nodelist);
var sortedList = nodelist.OrderBy(a => a.brlen);
sortedList.ToList(); //这个时候会排序
int M = nodelist.Capacity;
// Set up DNA sequence list.
DnaSequenceList seqlist = new DnaSequenceList();
seqlist.mySequence = new DnaSequence [M];
int j = 0;
foreach (Node node in nodelist)
{
seqlist.mySequence[j++] = node.seq;
}
return seqlist;
}
public String toString()
{
StringBuilder buf = new StringBuilder();
if (myLength == 0)
{
buf.Append('(');
buf.Append(')');
}
else if (myLength == 1)
{
buf.Append('(');
toString(buf, 0);
buf.Append(')');
}
else
{
toString(buf, myRoot);
}
buf.Append(';');
return toString();
}
private void toString (StringBuilder buf,int index)
{
Node node = myNode[index];
if (node.child1 != -1)
{
buf.Append('(');
toString(buf, node.child1);
buf.Append(',');
toString(buf, node.child2);
buf.Append(')');
}
buf.Append(nodeName(node));
if (node.brlen != null)
{
buf.Append(':');
buf.Append(node.brlen);
}
}
private String nodeName(Node node)
{
return node.seq == null || node.seq.myName == null ? "" : node.seq.myName.Replace("\\s+", "_");
}
}
}
public int CompareTo(object obj)
{
var node = obj as Node;
if(node == null)
throw new ArgumentException("Cannot compare objects of different type");
return CompareTo(node);
}