【问题标题】:Best way to construct the algorithm of tree in C#在 C# 中构造树算法的最佳方法
【发布时间】:2013-03-07 15:59:26
【问题描述】:

我在寻找最有效的解决方案方面遇到了一个小问题。我有一个 student ids 的数字,例如 10。其中一些 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);
    
                    }
                }
            }
        }
    }
    

【问题讨论】:

  • 你只有 studentId 属性吗?
  • 你怎么知道哪些是兄弟姐妹。此外,是否所有相关项目都分组在一起?或者说,1、2 和 5 可以是兄弟姐妹,而 3 和 4 不相关?
  • 哦,是的,可能有任何情况,我只是让问题更简单

标签: c# sql algorithm sorting


【解决方案1】:

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

  1. 创建一个不能出现在输出中的项目列表
  2. 实际上删除它们

当然,这仅在每个兄弟实际上都出现在原始 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 methods,它们是 System.LINQ 命名空间的一部分
  • Select 方法将一个序列转换为另一个序列。由于families序列的序列family 将是同一家族中的兄弟序列(即,1, 2, 38, 9 在这种特殊情况下)
  • Skip 方法会跳过序列中的多个元素。在这里,我决定总是跳过第一个元素(原因见上文)
  • Aggregate 方法将序列的元素组合成单个元素。在这里,所有兄弟姐妹的家庭都只是相互连接(除了每个家庭的第一个兄弟姐妹,已通过 Skip 省略)
  • Except 方法返回序列中在作为参数给出的序列中的所有元素。

我希望这能澄清一点。

【讨论】:

  • 感谢代码,我实际上对基于方法的查询不太熟悉。但让我试试。
【解决方案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"));
}

评论请求为什么(如果需要)。

【讨论】:

  • 非常感谢您的贡献,我决定并在存储过程中完成了所有工作,因此在输出中我只有 id 表和不同的电子邮件。你的代码对我帮助很大。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-28
  • 1970-01-01
相关资源
最近更新 更多