我有一个问题,我需要将小方块合并为更大的矩形.假设我有一个2D网格,填充随机1和0:
1 0 1 1 0
1 0 1 1 1
0 1 0 1 1
0 1 0 1 1
0 0 1 0 0
Run Code Online (Sandbox Code Playgroud)
1代表填充的区域,我将它们绘制成屏幕方式为正方形.但是,对于这个问题,我需要先将它们匹配成矩形.在示例节目中,左上角的1是 - >
1
1
Run Code Online (Sandbox Code Playgroud)
可以加入矩形.
我认为这应该足以解释我的需要.然而,优选的是,不在一个以上的矩形中使用特定的正方形.此外,它不一定是具有最少数量矩形的最佳情况,只是具有较少矩形的更好情况.如果它会使事情变得容易,也允许使用1x1矩形.
任何洞察我可以开始,甚至解决方案将不胜感激.
如果你想知道这个问题背后的原因,我正在为我正在研究的游戏开发一个关卡构建器,我想减少我的顶点数.我以为我会从方块开始,因为它们会很简单,但即使这样也让我难以置信.
感谢您花时间阅读!
我知道之前已经问过这个问题(我将继续研究),但我需要知道如何以线程安全的方式创建特定的链表功能.我当前的问题是我有一个循环遍历链表中所有元素的线程,另一个可能会在此列表的末尾添加更多元素.有时会发生这样的情况:一个线程尝试将另一个元素添加到列表中,而第一个元素正忙于迭代它(这会导致异常).
我想只是添加一个变量(布尔标志)来表示列表当前正在忙于迭代,但是我如何检查它并等待第二个线程(如果它等待,则可以,因为第一个线程运行很快).我能想到的唯一方法是通过使用while循环不断检查这个忙碌的标志.我意识到这是一个非常愚蠢的想法,因为它会导致CPU在没有任何用处的情况下努力工作.现在我在这里要求更好的见解.我已经阅读了关于锁等等,但它似乎与我的情况无关,但也许我错了?
与此同时,如果我找到解决方案,我将继续搜索互联网并发回.
编辑:让我知道我是否应该发布一些代码来清理,但我会尝试更清楚地解释它.
所以我有一个带有链表的类,其中包含需要处理的元素.我有一个线程通过函数调用遍历此列表(让我们称之为"processElements").我有第二个线程,以非确定的方式添加元素进行处理.但是,有时它会在processElements运行时尝试调用此addElement函数.这意味着当一个元素被第一个线程迭代时,它被添加到链表中.这是不可能的,并导致异常.希望这清除它.
我需要添加新元素的线程,直到processElements方法执行完毕.
我有一组3个不同的链表(用于保存我正在处理的游戏中的实体).列表是具有相同基本类型的所有对象,但出于处理原因,我将它们分开.请注意,IEntity,IObject和IUndead都继承自IEntity.
public class EntityBucket
{
public LinkedList<IEntity> undeadEntities;
public LinkedList<IEntity> objects;
public LinkedList<IEntity> livingEntities;
public EntityBucket()
{
undeadEntities = new LinkedList<IEntity>();
objects = new LinkedList<IEntity>();
livingEntities = new LinkedList<IEntity>();
}
public LinkedList<IEntity> GetList(IObject e)
{
return objects;
}
public LinkedList<IEntity> GetList(IUndead e)
{
return undeadEntities;
}
public LinkedList<IEntity> GetList(ILiving e)
{
return livingEntities;
}
}
Run Code Online (Sandbox Code Playgroud)
我有3种方法来检索每个列表,目前基于它们的参数.事实上有3个是好的,因为我知道每个列表将以某种方式需要它自己的访问者.传递一个实例化的对象并不理想,因为我可能想要在某个地方检索一个列表而不需要手头有类似类型的对象.请注意,此处的对象甚至不在GetList方法中使用,它们仅用于确定要使用的版本.这是一个我手头有一个实例化对象的例子:
public void Delete(IUndead e, World world)
{
.....
LinkedList<IEntity> list = buckets[k].GetList(e);
.....
}
Run Code Online (Sandbox Code Playgroud)
我不喜欢这个当前的实现,因为我可能并不总是有一个实例化的对象(例如渲染实体时).我一直在考虑这样做,但我不确定这是否可能与我想做的事情有关.有了这个,我还需要3个Delete方法(以及其他3个,例如add等等) - 每种类型一个,IUndead,IObject和ILiving.我觉得这不是正确的做法.
我会根据要求发布我到目前为止尝试做的事情,但我的仿制品相当糟糕,我觉得任何人阅读本文都是浪费.
最后,表现非常重要.我没有过早地进行优化,我已经进行了优化,因为我已经有了工作代码,但需要它更快.getlist方法将经常被调用,我想避免任何显式类型检查.
我有一个通用方法:
public bool DoSomething<T>(T item) where T: IBase
{
return DoSomethingSpecific(item);
}
public bool DoSomethingSpecific(IBase item)
{
return true;
}
public bool DoSomethingSpecific(IAdvanced item)
{
return false;
}
Run Code Online (Sandbox Code Playgroud)
请注意,IAdvanced 接口派生/继承自 IBase 接口。
我发现,如果我在项目类型为 IAdvanced 的情况下调用 DoSomething,它仍然总是返回 false。我不明白这一点。我知道,由于 IAdvanced 是 IBase 类型(因为它是此接口的子级),因此可能会导致 DoSomethingSpecific 方法的 2 个重载类型之间发生混淆。然而,据我所知,以我有限的 C# 知识,这里应该选择 IAdvanced 方法。这是我如何得出这个结论的一个例子:
public class Advanced: IAdvanced
{
public void CallMethod()
{
DoSomething(this);
}
}
Run Code Online (Sandbox Code Playgroud)
这会产生真实值。
但是,如果我这样做:
public class Advanced: IAdvanced
{
public void CallMethod()
{
DoSomethingSpecific(this);
}
}
Run Code Online (Sandbox Code Playgroud)
它返回 false,这正是我所期望的。
我不得不说我以前从未使用过泛型。我虽然尝试过,但总是陷入这样的情况,然后完全看不到使用泛型的意义(除了树和链表等数据结构之外)。
这次我决定来这里寻求一些建议。我想做的事情有明显的问题吗?尝试做我在这里忙着做的事情也许没有意义吗?
在我的应用程序中,我每帧执行一次System.Array.Resize.最初我将数组设置为最大可能的大小,然后将它们调整为更小的值.在某些情况下,它可能会小很多,在其他情况下,它可能会小一些.在我看来,虽然要调整大小的元素越多,所需的时间就越长.也许我的观察是错误的,这就是我在这里问的原因.