在C#中构造树算法的最佳方法

时间:2013-03-19 04:47:38

标签: c# sql algorithm sorting

我在找到最有效的解决方案时遇到了一个小问题。我有一个数字,例如10, student ids 。其中一些ID是彼此相对的(兄弟姐妹)。对于那些兄弟姐妹只留下其中一个进行识别的人来说,并不重要,首先是好的。

例如,学生ID

  • 原创

    1,2,3,4,5,6,7,8,9,10

其中1, 2, 3是一个家庭的兄弟姐妹,8, 9是另一个。最后我应该:

  • 预期

    1 ,4,5,6,7, 8 ,10

我是通过循环来完成的。


更新:

我刚刚停止实施它,因为它变得越来越大。这是我脑海中的一幅大图。我只是逐行收集每个给定id的所有兄弟id,然后我将逐个迭代。但就像我说的那样浪费时间。

  • 代码(概念上)

    static string Trimsiblings(string ppl) {
        string[] pids=ppl.Split(',');
        Stack<string> personid=new Stack<string>();
    
        foreach(string pid in pids) {
            // access database and check for all sibling 
            // is for each individual pid 
            // such as in example above 
            // row 1: field 1=1, field2=2, field3=3 
            // row 2: field 1=8, field2=9 
    
            query = Select..where ..id = pid; // this line is pesudo code
    
            for(int i=0; i<query.Length; i++) {
                foreach(string pid in pids) {
                    if(query.field1==pid) {
                        personid.Push(pid);
    
                    }
                }
            }
        }
    }
    

2 个答案:

答案 0 :(得分:2)

对于有效的代码,必须注意每个兄弟姐妹家族的一个成员(例如,第一个)是无关紧要的,因为它将留在输出中。也就是说,我们只需要

  1. 创建一个不得出现在输出中的项目列表
  2. 实际删除它们
  3. 当然,这只能假设每个兄弟都真正出现在原始的ID列表中。

    在代码中:

    int[] ids = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    int families = new int[2][] {
        new int [] {1, 2, 3},
        new int [] {8, 9}
    };
    var itemsToOmit = siblings.
        Select(family => family.Skip(1)).
        Aggregate((family1, family2) => family1.Concat(family2));
    var cleanedIds = ids.Except(itemsToOmit);
    

    编辑:既然你提到你不太熟悉语法,我会给出一些进一步的解释

    • 我使用的表达式extension methodsSystem.LINQ命名空间的一部分
    • Select方法将一个序列转换为另一个序列。由于families序列序列family将是同一系列中的兄弟姐妹序列(即1, 2, 38, 9情况下)
    • Skip方法会跳过序列的多个元素。在这里,我决定总是跳过第一个元素(原因,见上文)
    • Aggregate方法将序列的元素组合成单个元素。在这里,兄弟姐妹的所有家庭只是相互连接(除了通过Skip省略的每个家庭的第一个兄弟姐妹)
    • Except方法返回序列中作为参数给出的序列中的所有元素。

    我希望这会澄清一些事情。

答案 1 :(得分:2)

这是如何

public static String Trimsiblings(String ppl) {
    var table=GetSiblingTable();
    var pids=ppl.Split(',');

    return
        String.Join(", ", (
            from id in pids.Select(x => int.Parse(x))
            where (
                from row in table.AsEnumerable()
                select
                    from DataColumn column in table.Columns
                    let data=row[column.ColumnName]
                    where DBNull.Value!=data
                    select int.Parse((String)data)
                ).All(x => false==x.Contains(id)||x.First()==id)
            select id.ToString()).ToArray()
            );
}

// emulation of getting table from database
public static DataTable GetSiblingTable() {
    var dt=new DataTable();

    // define field1, ..., fieldn
    for(int n=3, i=1+n; i-->1; dt.Columns.Add("field"+i))
        ;

    dt.Rows.Add(new object[] { 1, 2, 3 });
    dt.Rows.Add(new object[] { 8, 9 });
    return dt;
}

public static void TestMethod() {
    Console.WriteLine("{0}", Trimsiblings("1, 2, 3, 4, 5, 6, 7, 8, 9, 10"));
}

发表评论以请求为什么(如果您需要)。