【问题标题】:Detect transitions in a list of objects检测对象列表中的转换
【发布时间】:2016-03-11 22:58:25
【问题描述】:

我有一个有序的对象列表(名为 LO)。
每个对象(名为 Ob)是一个或多个 int 的列表?元素 (List <int?>),例如:<30> or <30, null> or <null> or <28, 30> 等。编辑:在此列表中,每个元素都是唯一的。

我需要检测(并计算)对象列表中的转换,转换是 LO 列表中对象顺序的特定序列。 (编辑:我使用-> 表示下一个对象。例如,<A> -> <B> 是对象列表中的 2 个对象 LO:假设第 3 个是 <A>,第 4 个是 <B>

<A> -> <B> :transition
<A> -> <null> -> <B> or  <A> -> <null> ->...-> <null> -> <B> : transition
<A> -> <A,B> -> <B or  <A> -> <A,B> ->...-> <A,B> ->B :transition
<A> -> <null> -> <A> : transition

&lt;A&gt; -&gt; &lt;AB&gt; -&gt; &lt;A&gt; 是个例外,它不是过渡,当然,任何重复 &lt;A&gt;-&gt;&lt;A&gt;&lt;null&gt; -&gt; &lt;null&gt;&lt;A,B&gt; -&gt; &lt;A,B&gt; 等的组合都不是过渡。

编辑:仅转换以单个对象(如)开始并以单个对象(如)结束的序列。 -> -> 不是标识转换的元素序列。

我该怎么做?我的想法是将A -&gt; (*)A -&gt; A 模式检测为异常。我应该预先过滤列表以排除重复数据吗?

【问题讨论】:

标签: c# algorithm detection


【解决方案1】:

好的,我创建了一个程序(也可以在 dotnetfiddle.com 上找到),我试图用它来满足您的要求。但我仍然认为您的规格不清楚。

这是我已经实现的:

  • 对象列表 (LO) 可以包含对象 (OB)。
  • (OB) 是 String 的列表(在您的场景中必须替换为 int?)。
  • OB 被视为Set。允许重复但忽略。
  • OBs 包含相同的Strings 时,它们是相同的。
  • LO 为空时,transitions 为 0
  • LO 只包含一个OB 时,transitions 为0
  • LO中的第一个OB或最后一个OB有多个String时,transitions为0
  • 当两个后续的OBs 不相同时,转换次数增加一。

我在输出中添加了一些注释,因为我不明白你的意思。

输出

[A] -> [B]:1 [A] -> [空] -> [B]:2 [A] -> [null] -> [null] -> [null] -> [null] -> [B] : 2 [A] -> [A,B] -> [B] : 2 [A] -> [null] -> [A]:2 [A] -> [A,B] -> [A] : 2 为什么这不是过渡而是例外? [A] -> [A,null] -> [A,null,null] -> [A] : 2 根据您的第二条评论, [A,null] 和 [A,null,null] 被认为是相等的。 [A] -> [A,B,null,C] -> [A] : 2 根据您的第一条评论。 [A] -> [A,B] -> [B,A] -> [A] : 2 根据您的第一条评论,第二个和第三个 OB 是相等的。 [A] -> [null,A] -> [B] : 2 [A] -> [A,B,C] -> [B] : 2 根据您的第四条评论,为什么这不是过渡?

源代码

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
    public static string A = "A";
    public static string B = "B";
    public static string C = "C";
    public static string NULL = "null";

    public static void Main()
    {   
        var lo = new LO();
        lo.Add(new OB{A});
        lo.Add(new OB{B});
        lo.DisplayResult();

        lo.Clear();
        lo.Add(new OB{A});
        lo.Add(new OB{NULL});
        lo.Add(new OB{B});
        lo.DisplayResult();

        lo.Clear();
        lo.Add(new OB{A});
        lo.Add(new OB{NULL});
        lo.Add(new OB{NULL});
        lo.Add(new OB{NULL});
        lo.Add(new OB{NULL});
        lo.Add(new OB{B});
        lo.DisplayResult();

        lo.Clear();
        lo.Add(new OB{A});
        lo.Add(new OB{A,B});
        lo.Add(new OB{B});
        lo.DisplayResult();

        lo.Clear();
        lo.Add(new OB{A});
        lo.Add(new OB{NULL});
        lo.Add(new OB{A});
        lo.DisplayResult();

        lo.Clear();
        lo.Add(new OB{A});
        lo.Add(new OB{A,B});
        lo.Add(new OB{A});
        lo.DisplayResult("Why is this not a transition but an exception?");


        lo.Clear();
        lo.Add(new OB{A});
        lo.Add(new OB{A,NULL});
        lo.Add(new OB{A,NULL,NULL});
        lo.Add(new OB{A});
        lo.DisplayResult("<A,NULL> and <A,NULL,NULL> are considered equal as per your second comment.");

        lo.Clear();
        lo.Add(new OB{A});
        lo.Add(new OB{A,B,NULL,C});
        lo.Add(new OB{A});
        lo.DisplayResult("As per your first comment");

        lo.Clear();
        lo.Add(new OB{A});
        lo.Add(new OB{A,B});
        lo.Add(new OB{B,A});
        lo.Add(new OB{A});
        lo.DisplayResult("Second and third OB are equal as per your first comment");

        lo.Clear();
        lo.Add(new OB{A});
        lo.Add(new OB{NULL,A});
        lo.Add(new OB{B});
        lo.DisplayResult();

        lo.Clear();
        lo.Add(new OB{A});
        lo.Add(new OB{A,B,C});
        lo.Add(new OB{B});
        lo.DisplayResult("Why is this not a transition as per your fourth comment?");
    }
}

// list of objects (LO) = list<OB>
public class LO : List<OB>
{
    public void DisplayResult(string message = null)
    {
        Console.WriteLine("{0} : {1}",this,CountTransitions());
        if(message != null)
        {
            Console.WriteLine(message);
        }
        Console.WriteLine();
    }

    private int CountTransitions()
    {
        if(this.Any()== false || this.Count == 1) return 0;

        var first = this.FirstOrDefault();
        var last = this.LastOrDefault();

        // first OB and last OB must have exactly one element.
        if(first.Count != 1 || last.Count != 1) return 0;

        var transitions = 0;
        for(var i = 0; i < this.Count - 1; i++)
        {
            // when current OB and next OB are not the same, it is a transition
            transitions = IsTransition(this[i],this[i+1]) ? transitions + 1 : transitions;
        }
        return transitions;
    }

    private bool IsTransition(OB lhs, OB rhs)
    {
        var lhsSet = new SortedSet<String>(lhs);
        var rhsSet = new SortedSet<String>(rhs);
        return lhsSet.SetEquals(rhsSet) == false;
    }

    public override string ToString()
    {
        return String.Join(" -> ", this.Select(x => x.ToString()));
    }
}

// objects (OB) = list<int?>
public class OB : List<String>
{
    public override String ToString()
    {
        return String.Format("[{0}]", String.Join(",", this));
    }
}

【讨论】:

  • 感谢您的帮助。您的回答是我实现的基础,尤其是 IsTransition 函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-02
  • 2020-07-14
  • 2021-10-01
相关资源
最近更新 更多