Questions tagged «algorithm»

算法是定义明确的问题解决方案的一系列明确定义的步骤。当您的问题与算法设计有关时,请使用此标签。


30
如何检查数组是否在JavaScript中包含值?
找出JavaScript数组是否包含值的最简洁,最有效的方法是什么? 这是我知道的唯一方法: function contains(a, obj) { for (var i = 0; i < a.length; i++) { if (a[i] === obj) { return true; } } return false; } 有没有更好,更简洁的方法来实现这一目标? 这与Stack Overflow问题密切相关。在JavaScript数组中查找项目的最佳方法?它解决了使用数组查找对象的问题indexOf。

30
如何有效地将袜子配对?
昨天我从干净的洗衣店里给袜子配对,发现我做这件事的方式不是很有效。我一直在天真地搜寻-挑选一只袜子,然后“反复”寻找那双袜子。这需要遍历的n / 2 * N / 4 = N 2平均/ 8的袜子。 作为计算机科学家,我在想我能做什么?当然会想到进行排序(根据大小/颜色/ ...)以实现O(NlogN)解决方案。 不能选择散列或其他非现场解决方案,因为我无法复制袜子(尽管如果可以的话,可能会很好)。 因此,问题基本上是: 给定一堆n袜子,其中包含2n元素(假设每只袜子都具有一对完全匹配的袜子),最好的方法是将它们有效配对并具有对数的额外空间?(我相信我可以记住该信息的数量,如果需要的话。) 我希望能从以下几个方面回答这个问题: 大量袜子的一般理论解决方案。 袜子的实际数量不是很大,我不相信我的配偶和我有超过30对。(而且很容易区分我的袜子和她的袜子;也可以使用吗?) 它等同于元素区分性问题吗?

14
2048游戏的最佳算法是什么?
我最近偶然发现了2048游戏。您可以通过在四个方向上任意移动相似的图块来合并它们,以制作“更大”的图块。每次移动后,新的图块都会出现在随机的空白位置,其值为2或4。当所有方框都已填满且没有可合并磁贴的移动,或者您创建的值为时,游戏终止2048。 第一,我需要遵循明确定义的策略才能达到目标。因此,我想到了为此编写程序。 我当前的算法: while (!game_over) { for each possible move: count_no_of_merges_for_2-tiles and 4-tiles choose the move with a large number of merges } 我做的是在任何时候,我会尽量与值合并瓷砖2和4,就是我努力2和4瓷砖,尽可能最小。如果以这种方式尝试,所有其他磁贴将自动合并,并且该策略看起来不错。 但是,当我实际使用此算法时,在游戏终止前我只能得到4000点。最高分数AFAIK略高于20,000点,这比我目前的分数还大。是否有比以上更好的算法?


24
图像处理:“可口可乐”识别的算法改进
我过去几年中最有趣的项目之一是关于图像处理的项目。目的是开发一个能够识别可口可乐“罐头”的系统(请注意,我强调的是“罐头”一词,稍后您会看到原因)。您可以在下面看到一个示例,该示例在带有刻度和旋转的绿色矩形中可以识别。 对项目的一些限制: 背景可能非常嘈杂。 该罐可以具有任何规模或旋转,甚至方向(在合理的限度内)。 图像可能有一定程度的模糊性(轮廓可能不完全笔直)。 图像中可能有可口可乐瓶,该算法只能检测到罐头! 图像的亮度可能相差很大(因此您不能“过多”依赖颜色检测)。 该罐可以部分地隐藏在两侧或中间,可能部分地隐藏了一瓶后面。 有可能是没有能在所有的图像中,在这种情况下,你必须找到什么,写一条消息这样说。 因此,您可能会遇到如下棘手的事情(在这种情况下,我的算法完全失败了): 我前一段时间做了这个项目,并且做起来很有趣,并且实现得很好。以下是有关我的实现的一些详细信息: 语言:使用OpenCV库在C ++中完成。 预处理:对于图像预处理,即将图像转换为更原始的形式以提供给算法,我使用了两种方法: 将颜色域从RGB更改为HSV,并基于“红色”色调进行过滤,饱和度高于特定阈值以避免产生类似橙色的颜色,而对低值进行过滤以避免产生深色。最终结果是一个二进制的黑白图像,其中所有白色像素将代表与该阈值匹配的像素。显然,图像中仍然有很多废话,但这减少了必须处理的尺寸数。 使用中值滤波进行噪声滤波(获取所有邻居的中值像素值,然后用该值替换像素)以减少噪声。 经过2个先验步骤后,使用Canny Edge Detection滤镜获取所有项目的轮廓。 算法:我为此任务选择的算法本身取材于这本很棒的书中有关特征提取的书,并称为通用霍夫变换(与常规霍夫变换完全不同)。它基本上说了几件事: 您可以在不知道其解析方程的情况下描述空间物体(此处就是这种情况)。 它可以抵抗缩放和旋转等图像变形,因为它将基本上测试图像的缩放因子和旋转因子的每种组合。 它使用算法将“学习”的基本模型(模板)。 轮廓图像中剩余的每个像素将投票给另一个像素,根据它从模型中学到的信息,该像素应该是对象的中心(就重力而言)。 最后,您将获得投票的热图,例如,此处罐头轮廓的所有像素都将为其重力中心投票,因此在与像素相对应的同一像素中将有很多投票居中,将会在热图中看到一个峰值,如下所示: 有了这些功能后,您就可以使用简单的基于阈值的启发式方法来确定中心像素的位置,从中可以得出比例尺和旋转角度,然后在其周围绘制一个小矩形(最终比例尺和旋转系数显然相对于您的原始模板)。理论上至少... 结果:现在,尽管此方法在基本情况下可行,但在某些领域却严重缺乏: 这是非常慢!我的压力还不够。处理30张测试图像几乎需要整整一天的时间,这显然是因为我对旋转和平移具有非常高的缩放系数,因为某些罐非常小。 当瓶子出现在图像中时,它完全丢失了,并且出于某种原因几乎总是找到瓶子而不是罐子(也许是因为瓶子更大,因此像素更多,投票更多) 模糊图像也不是很好,因为投票最终以像素为中心围绕中心的随机位置,从而以非常嘈杂的热图结束。 实现了平移和旋转的不变性,但没有实现定向,这意味着未识别未直接面对相机物镜的罐子。 您是否可以使用专有的OpenCV功能帮助我改善特定算法,以解决上述四个特定问题? 我希望有些人也能从中学到一些东西,毕竟我认为不仅提出问题的人也应该学习。:)

20
重写GetHashCode的最佳算法是什么?
在.NET中,该GetHashCode方法整个.NET基类库中的许多地方都使用。正确实施它对于在集合中或确定相等性时快速查找项目尤为重要。 有没有关于如何GetHashCode为我的自定义类实现的标准算法或最佳实践,因此我不会降低性能?

30
容易的面试问题变得更加困难:给定数字1..100,在恰好缺少k的情况下,找到缺失的数字
前一段时间我有一次有趣的面试经历。这个问题开始很容易: Q1:我们有包含数字的袋子1,2,3,..., 100。每个数字仅出现一次,因此有100个数字。现在,从袋子中随机抽取一个号码。查找丢失的号码。 我当然已经听过这个面试问题,所以我很快就回答了以下问题: A1:好吧,数字的总和1 + 2 + 3 + … + N是(N+1)(N/2)(请参阅Wikipedia:算术级数的总和)。因为N = 100,总和是5050。 因此,如果袋子中所有数字都存在,则总和为5050。由于缺少一个数字,所以总和小于这个数字,而差就是那个数字。因此,我们可以找到O(N)时间和O(1)空间上缺少的数字。 在这一点上,我认为我做得不错,但是突然之间,这个问题突然发生了变化: Q2:是的,但是现在如果缺少两个数字,您将如何处理? 我之前从未见过/听过/考虑过这种变化,所以我感到惊慌,无法回答这个问题。面试官坚持要知道我的思维过程,所以我提到也许我们可以通过与预期产品进行比较来获得更多信息,或者也许在从第一遍收集到一些信息之后再进行第二遍,等等,但是我真的只是在拍摄在黑暗中,而不是真正找到解决方案的清晰途径。 面试官的确通过说第二个方程式确实是解决问题的一种方式来鼓励我。在这一点上,我有点不高兴(因为事先不知道答案),并询问这是否是一种通用的(读作:“有用的”)编程技术,还是仅仅是一个技巧/陷阱。 面试官的回答让我感到惊讶:您可以推广该技术以找到3个缺失的数字。实际上,您可以对其进行概括以找到k个缺失数字。 Qk:如果袋子中恰好缺少k个数字,您将如何有效地找到它? 这是几个月前,但我仍然不知道这种技术是什么。显然存在一个Ω(N)时间下限,因为我们必须至少扫描一次所有数字,但是访调员坚持认为求解技术的TIME和SPACE复杂度(减去O(N)时间输入扫描)以k而非N定义。 所以这里的问题很简单: 您将如何解决Q2? 您将如何解决Q3? 您将如何解决Qk? 澄清说明 通常,从1 .. N开始有N个数字,而不仅仅是1..100。 我不是在寻找明显的基于集合的解决方案,例如,使用位集,通过指定位的值编码每个数字的存在/不存在,因此O(N)在其他空间中使用位。我们无法承受与N成正比的任何额外空间。 我也不在寻找明显的排序优先方法。这种方法和基于集合的方法在采访中值得一提(它们易于实现,并且取决于N,可能非常实用)。我正在寻找“圣杯”解决方案(可能实现或可能不实际,但仍具有所需的渐近特性)。 因此,当然,您必须再次扫描中的输入O(N),但是您只能捕获少量信息(用k而不是N定义),然后必须以某种方式找到k个缺失的数字。
1146 algorithm  math 

7
普通英语的Ukkonen后缀树算法
在这一点上我感觉有点浓。我花了几天的时间试图完全围绕后缀树构造,但是由于我没有数学背景,因此许多解释都使我难以理解,因为它们开始过度使用数学符号系统。我发现的最接近很好的解释是带有后缀树的快速字符串搜索,但是他掩盖了各个要点,并且算法的某些方面仍不清楚。 我敢肯定,在堆栈溢出上对此算法的分步说明对我以外的其他许多人来说都是无价的。 作为参考,这里是有关算法的Ukkonen论文:http : //www.cs.helsinki.fi/u/ukkonen/SuffixT1withFigs.pdf 到目前为止,我的基本了解: 我需要遍历给定字符串T的每个前缀P 我需要遍历前缀P中的每个后缀S并将其添加到树中 要将后缀S添加到树中,我需要遍历S中的每个字符,其中的迭代包括沿着以S中相同的字符集C开头的现有分支以及当我将边缘拆分成后代节点时进行在后缀中找到一个不同的字符,或者如果没有匹配的边要走。当找不到匹配的边沿C向下走时,将为C创建新的叶边。 正如大多数解释中所指出的那样,基本算法似乎是O(n 2),因为我们需要逐步处理所有前缀,然后才需要逐步处理每个前缀的每个后缀。Ukkonen的算法显然是独特的,因为他使用了后缀指针技术,尽管我认为这是我难以理解的。 我也很难理解: 准确地分配,使用和更改“活动点”的时间和方式 该算法的规范化方面发生了什么 为什么我看到的实现需要“修复”他们使用的边界变量 这是完整的C#源代码。它不仅可以正常工作,而且支持自动规范化,并呈现输出的外观更好的文本图。源代码和示例输出位于: https://gist.github.com/2373868 更新2017-11-04 多年后,我发现后缀树有了新的用途,并在JavaScript中实现了该算法。要点在下面。它应该没有错误。npm install chalk从相同位置将其转储到js文件中,然后与node.js一起运行以查看一些彩色输出。在同一个Gist中有一个精简版,没有任何调试代码。 https://gist.github.com/axefrog/c347bf0f5e0723cbd09b1aaed6ec6fc6

30
删除列表中的重复项
我几乎需要编写一个程序来检查列表中是否有重复项,如果删除了重复项,则将其删除并返回一个新列表,其中包含未重复/删除的项。这就是我所拥有的,但老实说我不知道​​该怎么办。 def remove_duplicates(): t = ['a', 'b', 'c', 'd'] t2 = ['a', 'c', 'd'] for t in t2: t.append(t.remove()) return t


9
如何找到算法的时间复杂度
问题 如何找到算法的时间复杂度? 在发布SO问题之前我做了什么? 我经历了这个,这个和许多其他链接 但是,在任何地方我都无法找到关于如何计算时间复杂度的清晰直接的解释。 我知道什么 ? 说一个简单的代码如下: char h = 'y'; // This will be executed 1 time int abc = 0; // This will be executed 1 time 说一个像下面这样的循环: for (int i = 0; i < N; i++) { Console.Write('Hello World !'); } int i = 0; 这将仅执行一次。时间实际上是计算到的,i=0而不是声明的。 …




By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.