鉴于以下类(假设它们已填充),您如何找到val
实例的任何test1
的最小值?
public class test1
{
public int val;
public List<test2> Tests;
}
public class test2
{
public int val;
public List<test3> Tests;
}
public class test3
{
public int val;
public List<test4> Tests;
}
public class test4
{
public int val;
}
答案 0 :(得分:3)
您可以在顶级类中编写一个方法,将结构展平为IEnumerable。
public IEnumerable<int> FlattenVal()
{
yield return this.val;
foreach (var t2 in this.Tests)
{
yield return t2.val;
foreach (var t3 in t2.Tests)
{
yield return t3.val;
foreach (var t4 in t3.Tests)
{
yield return t4.val;
}
}
}
}
然后你可以这样称呼它:
var t = new Test1();
Console.WriteLine(t.FlattenVal().Min());
如果你不能将方法直接添加到类(非部分,代码生成或库中),那么你可以使用扩展方法:
public static IEnumerable<int> FlattenVal(this Test1 t1)
{
yield return t1.val;
foreach (var t2 in t1.Tests)
{
yield return t2.val;
foreach (var t3 in t2.Tests)
{
yield return t3.val;
foreach (var t4 in t3.Tests)
{
yield return t4.val;
}
}
}
}
答案 1 :(得分:2)
非递归(和非测试)解决方案:
int minVal(test1 t1) {
int min = t1.val;
foreach (test2 t2 in t1.Tests) {
min = Math.Min(min, t2.val);
foreach (test3 t3 in t2.Tests) {
min = Math.Min(min, t3.val);
foreach (test4 t4 in t3.Tests) {
min = Math.Min(min, t4.val);
}
}
}
return min;
}
答案 2 :(得分:2)
我必须承认这个问题看起来有些奇怪,但这里有一个解决方案,它引入了两个基类TestBase
和Test<T>
,因此最小查找算法可以保存在一个地方:
using System;
using System.Collections.Generic;
using System.Linq;
public abstract class TestBase {
public int Val;
public virtual int GetMin() {
return Val;
}
}
public abstract class Test<T> : TestBase where T : TestBase {
public List<T> Tests;
public override int GetMin() {
return Math.Min(Val, Tests.Select(t => t.GetMin()).Min());
}
}
public class Test1 : Test<Test2> {
}
public class Test2 : Test<Test3> {
}
public class Test3 : Test<Test4> {
}
public class Test4 : TestBase {
}
我将用于标识符的外壳更改为让我感觉更舒服的东西。
答案 3 :(得分:0)
我已经测试并编写了一个应该可行的完整控制台程序。你走了:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication3
{
public interface ITest
{
int val {get; set; }
List<ITest> Tests {get; set; }
}
public class Test1 : ITest
{
public int val { get; set; }
public List<ITest> Tests {get; set; }
public Test1()
{
Tests = new List<ITest>();
}
}
public class Test2 : ITest
{
public int val { get; set; }
public List<ITest> Tests {get; set; }
public Test2()
{
Tests = new List<ITest>();
}
}
public class Test3 : ITest
{
public int val { get; set; }
public List<ITest> Tests {get; set; }
public Test3()
{
Tests = new List<ITest>();
}
}
public class Test4 : ITest
{
public int val { get; set; }
public List<ITest> Tests {
get { return new List<ITest>(); }
set {}
}
}
class Program
{
public static int GetMinVal(ITest initialTest, out ITest testWithMinVal)
{
int minVal = initialTest.val;
testWithMinVal = initialTest;
foreach (ITest t in initialTest.Tests)
{
if (t.val < minVal)
{
minVal = GetMinVal(t, out testWithMinVal);
}
}
return minVal;
}
static void Main(string[] args)
{
Random r = new Random();
Test1 test = new Test1();
test.val = r.Next(100);
for (int i = 0; i < 5; i++)
{
Test2 test2 = new Test2();
test2.val = r.Next(100);
for (int j = 0; j < 4; j++)
{
Test3 test3 = new Test3();
test3.val = r.Next(100);
for (int k = 0; k < 3; k++)
{
Test4 test4 = new Test4();
test4.val = r.Next(100);
test3.Tests.Add(test4);
}
test2.Tests.Add(test3);
}
test.Tests.Add(test2);
}
ITest testA;
int minVal = GetMinVal(test, out testA);
Console.WriteLine(minVal);
}
}
}
我希望这会有所帮助......
答案 4 :(得分:0)
如果订单无关紧要,我强烈建议将数据存储在比List更合适的数据结构中。去玩小工具堆!
interface ILeftistHeap<T> : IEnumerable<T>
{
Func<T, T, int> Comparer { get; }
int Height { get; }
T Item { get; }
ILeftistHeap<T> Left { get; }
ILeftistHeap<T> Right { get; }
ILeftistHeap<T> Delete();
ILeftistHeap<T> Add(T item);
bool IsEmpty { get; }
}
sealed class LeftistHeap<T> : ILeftistHeap<T>
{
private static IEnumerator<T> CreateEnumerator(ILeftistHeap<T> heap)
{
while (!heap.IsEmpty)
{
yield return heap.Item;
heap = heap.Delete();
}
}
private static ILeftistHeap<T> Balance(T item, Func<T, T, int> comparer, ILeftistHeap<T> a, ILeftistHeap<T> b)
{
if (a.Height >= b.Height) { return new LeftistHeap<T>(comparer, b.Height + 1, item, a, b); }
else { return new LeftistHeap<T>(comparer, a.Height + 1, item, b, a); }
}
public static ILeftistHeap<T> Merge(ILeftistHeap<T> x, ILeftistHeap<T> y)
{
if (x.IsEmpty) { return y; }
else if (y.IsEmpty) { return x; }
else
{
Func<T, T, int> comparer = x.Comparer;
if (comparer(x.Item, y.Item) <= 0) { return Balance(x.Item, comparer, x.Left, Merge(x.Right, y)); }
else { return Balance(y.Item, comparer, y.Left, Merge(x, y.Right)); }
}
}
public static ILeftistHeap<T> Make(Func<T, T, int> comparer) { return EmptyHeap<T>.Make(comparer); }
public static ILeftistHeap<T> Make(Func<T, T, int> comparer, T item)
{
EmptyHeap<T> empty = EmptyHeap<T>.Make(comparer);
return new LeftistHeap<T>(comparer, 1, item, empty, empty);
}
public Func<T, T, int> Comparer { get; private set; }
public int Height { get; private set; }
public T Item { get; private set; }
public ILeftistHeap<T> Left { get; private set; }
public ILeftistHeap<T> Right { get; private set; }
public ILeftistHeap<T> Add(T item) { return Merge(this, Make(this.Comparer).Add(item)); }
public ILeftistHeap<T> Delete() { return Merge(this.Left, this.Right); }
public bool IsEmpty { get { return false; } }
protected LeftistHeap(Func<T, T, int> comparer, int height, T item, ILeftistHeap<T> left, ILeftistHeap<T> right)
{
this.Comparer = comparer;
this.Height = height;
this.Item = item;
this.Left = left;
this.Right = right;
}
public IEnumerator<T> GetEnumerator() { return LeftistHeap<T>.CreateEnumerator(this); }
IEnumerator IEnumerable.GetEnumerator() { return LeftistHeap<T>.CreateEnumerator(this); }
}
sealed class EmptyHeap<T> : ILeftistHeap<T>
{
private static IEnumerator<T> CreateEnumerator() { yield break; }
public static EmptyHeap<T> Make(Func<T, T, int> comparer) { return new EmptyHeap<T>(comparer); }
private EmptyHeap(Func<T, T, int> comparer) { this.Comparer = comparer; }
public Func<T, T, int> Comparer { get; protected set; }
public T Item { get { throw new Exception("Empty heap"); } }
public int Height { get { return 0; } }
public ILeftistHeap<T> Left { get { throw new Exception("Empty heap"); } }
public ILeftistHeap<T> Right { get { throw new Exception("Empty heap"); } }
public ILeftistHeap<T> Add(T item) { return LeftistHeap<T>.Make(this.Comparer, item); }
public ILeftistHeap<T> Delete() { throw new Exception("Empty Heap"); }
public bool IsEmpty { get { return true; } }
public IEnumerator<T> GetEnumerator() { return EmptyHeap<T>.CreateEnumerator(); }
IEnumerator IEnumerable.GetEnumerator() { return EmptyHeap<T>.CreateEnumerator(); }
}
向堆中添加项目是O(log n)。获得最小/最大值是O(1)。