检测对象列表中的转换
Detect transitions in a list of objects
我有一个有序的对象列表(名为 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
中的<A> -> <AB> -> <A>
是例外,不是过渡,当然也不是重复<A>-><A>
、<null> -> <null>
、<A,B> -> <A,B>
等任意组合过渡。
编辑:仅转换以单个对象(如 )开始并以单个对象结束(如 )的序列。 -> -> 不是标识转换的元素序列。
我该怎么做?我的想法是将 A -> (*)A -> A
模式检测为异常。我应该预先过滤列表以排除重复数据吗?
好的,我创建了一个程序(也可以在 dotnetfiddle.com 上找到),我试图用它来满足您的要求。但是我还是觉得你的规格不清楚。
这是我实现的:
- 对象列表 (
LO
) 可以包含对象 (OB
)。
- An (
OB
) 是 String
的列表(在您的场景中必须替换为 int?
)。
OB
被视为 Set
。允许重复但忽略。
当 OB
包含相同的 Strings
. 时,它们是相同的
- 当
LO
为空时,transitions为0
- 当
LO
只包含一个OB
时,transitions为0
- 当
LO
中第一个OB
或最后一个OB
有多个String
时,transitions为0
- 当两个后续
OB
不相同时,转换次数加一。
我在输出中添加了一些注释,因为我不明白你的意思。
输出
[A] -> [B] : 1
[A] -> [null] -> [B] : 2
[A] -> [null] -> [null] -> [null] -> [null] -> [B] : 2
[A] -> [A,B] -> [B] : 2
[A] -> [null] -> [A] : 2
[A] -> [A,B] -> [A] : 2
Why is this not a transition but an exception?
[A] -> [A,null] -> [A,null,null] -> [A] : 2
[A,null] and [A,null,null] are considered equal as per your second comment.
[A] -> [A,B,null,C] -> [A] : 2
As per your first comment.
[A] -> [A,B] -> [B,A] -> [A] : 2
Second and third OB are equal as per your first comment.
[A] -> [null,A] -> [B] : 2
[A] -> [A,B,C] -> [B] : 2
Why is this not a transition as per your fourth comment?
源代码
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));
}
}
我有一个有序的对象列表(名为 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
中的<A> -> <AB> -> <A>
是例外,不是过渡,当然也不是重复<A>-><A>
、<null> -> <null>
、<A,B> -> <A,B>
等任意组合过渡。
编辑:仅转换以单个对象(如 )开始并以单个对象结束(如 )的序列。 -> -> 不是标识转换的元素序列。
我该怎么做?我的想法是将 A -> (*)A -> A
模式检测为异常。我应该预先过滤列表以排除重复数据吗?
好的,我创建了一个程序(也可以在 dotnetfiddle.com 上找到),我试图用它来满足您的要求。但是我还是觉得你的规格不清楚。
这是我实现的:
- 对象列表 (
LO
) 可以包含对象 (OB
)。 - An (
OB
) 是String
的列表(在您的场景中必须替换为int?
)。 OB
被视为Set
。允许重复但忽略。
当 OB
包含相同的Strings
. 时,它们是相同的
- 当
LO
为空时,transitions为0 - 当
LO
只包含一个OB
时,transitions为0 - 当
LO
中第一个OB
或最后一个OB
有多个String
时,transitions为0 - 当两个后续
OB
不相同时,转换次数加一。
我在输出中添加了一些注释,因为我不明白你的意思。
输出
[A] -> [B] : 1 [A] -> [null] -> [B] : 2 [A] -> [null] -> [null] -> [null] -> [null] -> [B] : 2 [A] -> [A,B] -> [B] : 2 [A] -> [null] -> [A] : 2 [A] -> [A,B] -> [A] : 2 Why is this not a transition but an exception? [A] -> [A,null] -> [A,null,null] -> [A] : 2 [A,null] and [A,null,null] are considered equal as per your second comment. [A] -> [A,B,null,C] -> [A] : 2 As per your first comment. [A] -> [A,B] -> [B,A] -> [A] : 2 Second and third OB are equal as per your first comment. [A] -> [null,A] -> [B] : 2 [A] -> [A,B,C] -> [B] : 2 Why is this not a transition as per your fourth comment?
源代码
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));
}
}