- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我的目的是将多个字符串打成一个(最短的)字符串,该字符串将包含每个字符串的所有字符。这个问题并不特定于任何语言,而是更多地涉及到 algorithm
部分。 (可能会在 Node 服务器中实现它,所以标记 nodejs/javascript
)。
所以,解释一下问题:
假设我的字符串很少
["jack", "apple", "maven", "hold", "solid", "mark", "moon", "poor", "spark", "live"]
结果字符串应该是这样的:
"sjmachppoalidveonrk"
jack :sjmachppoalidveonrk
apple: sjmachppoalidveonrk
solid:sjmachppoalidveonrk
=====================================>>>> 全部向前
这些都是手动评估,示例中的输出可能不是 100% 完美。
所以,关键是每个字符串的所有字母都必须存在于输出中FORWARD DIRECTION(这里是实际问题所在),并且可能服务器将发送最终的字符串和像 27594
这样的数字将生成并传递以提取 token ,在所需的结尾。如果我必须用尽可能少的字符串打洞它会容易得多(这种情况只有唯一的字符就足够了)。但是在这种情况下有几点:
字母可以出现多次,但我必须重复使用任何字母字母如果可能,例如:对于 solid
和 hold
o > l > d
可以重用为正向,但用于 apple
(a > p
) 和 spark
(p > a
) 我们必须重复 a
,因为在一种情况下它出现在 p
之前对于 apple
,在 p
之后对于 sparks
所以我们需要重复a
或 p
。甚至,我们不能这样做 p > a > p
因为它不会涵盖这两种情况因为我们在 a
之后需要两个 p
用于 apple
我们直接没有选择放置单个 p
并使用相同的一次提取索引两次,我们需要多个 p
没有选项留下作为输入字符串包含该
我尝试过,从一个任意字符串开始,然后分析下一个字符串并拆分所有字母,并相应地放置它们,但是经过一段时间后,似乎可以将当前字符串字母放在更好的位置方式,如果根据当前字符串放置最后一个字符串(或前一个字符串)的字母。但是,该字符串再次根据已处理的内容(多个)进行分析和放置,并且将某些内容放置在未处理的内容上似乎很困难,因为我们需要处理它。或者我是否可以维护所有已处理/未处理树的树将有助于构建最终字符串?有什么比它更好的方法,它似乎是一个蛮力?
注意:我知道还有很多其他的转换可能,请尽量不要建议使用其他任何东西,我们正在研究它。
最佳答案
我想出了一个有点蛮力的方法。这种方式会找到组合 2 个单词的最佳方式,然后对数组中的每个元素进行组合。
此策略通过尝试找到将 2 个单词组合在一起的最佳方式来发挥作用。它被认为是最好的,因为它的字母最少。每个单词都被输入到一个不断增长的“合并”单词中。每次添加新词时,都会在现有词中搜索要合并的词中存在的匹配字符。一旦找到一个,就将它们分成两组并尝试加入(使用手头的规则,如果字母已经存在则不需要添加 2 等)。该策略通常会产生良好的效果。
join_word
方法需要两个你想加入的词,第一个参数被认为是你想加入另一个词的词。然后它搜索将 into
和 word
拆分为 2 个单独部分以合并在一起的最佳方法,它通过查找任何共享的公共(public)字符来做到这一点。这就是 splits_on_letter
方法的用武之地。
splits_on_letter
方法接受一个单词和一个您希望拆分的字母,然后返回一个二维数组,该数组包含该字符上所有可能的拆分左侧和右侧。例如 splits_on_letter('boom', 'o')
将返回 [["b","oom"],["bo","om"],["boo", "m"]]
,这就是我们如何使用字母o
作为分割点的所有组合。
开头的sort()
是试图将相似的元素放在一起。合并元素的顺序通常会影响结果长度。我尝试的一种方法是根据他们(与他们的同龄人)使用的常用字母的数量对它们进行排序,但结果各不相同。然而,在我所有的测试中,我可能有 5 或 6 个不同的单词集可供测试,如果使用更大、更多样化的单词数组,您可能会发现不同的结果。
输出是
spmjhooarckpplivden
var words = ["jack", "apple", "maven", "hold", "solid", "mark", "moon", "poor", "spark", "live"];
var result = minify_words(words);
document.write(result);
function minify_words(words) {
// Theres a good sorting method somewhere which can place this in an optimal order for combining them,
// hoever after quite a few attempts i couldnt get better than just a regular sort... so just use that
words = words.sort();
/*
Joins 2 words together ensuring each word has all its letters in the result left to right
*/
function join_word(into, word) {
var best = null;
// straight brute force each word down. Try to run a split on each letter and
for(var i=0;i<word.length;i++) {
var letter = word[i];
// split our 2 words into 2 segments on that pivot letter
var intoPartsArr = splits_on_letter(into, letter);
var wordPartsArr = splits_on_letter(word, letter);
for(var p1=0;p1<intoPartsArr.length;p1++) {
for(var p2=0;p2<wordPartsArr.length;p2++) {
var intoParts = intoPartsArr[p1], wordParts = wordPartsArr[p2];
// merge left and right and push them together
var result = add_letters(intoParts[0], wordParts[0]) + add_letters(intoParts[1], wordParts[1]);
if(!best || result.length <= best.length) {
best = result;
}
}
}
}
// its possible that there is no best, just tack the words together at that point
return best || (into + word);
}
/*
Splits a word at the index of the provided letter
*/
function splits_on_letter(word, letter) {
var ix, result = [], offset = 0;;
while((ix = word.indexOf(letter, offset)) !== -1) {
result.push([word.substring(0, ix), word.substring(ix, word.length)]);
offset = ix+1;
}
result.push([word.substring(0, offset), word.substring(offset, word.length)]);
return result;
}
/*
Adds letters to the word given our set of rules. Adds them starting left to right, will only add if the letter isnt found
*/
function add_letters(word, addl) {
var rIx = 0;
for (var i = 0; i < addl.length; i++) {
var foundIndex = word.indexOf(addl[i], rIx);
if (foundIndex == -1) {
word = word.substring(0, rIx) + addl[i] + word.substring(rIx, word.length);
rIx += addl[i].length;
} else {
rIx = foundIndex + addl[i].length;
}
}
return word;
}
// For each of our words, merge them together
var joinedWords = words[0];
for (var i = 1; i < words.length; i++) {
joinedWords = join_word(joinedWords, words[i]);
}
return joinedWords;
}
关于javascript - 将多个字符串打洞/组合成一个(可能最短的)字符串,其中包括每个字符串的所有字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45269325/
我目前正在开发一款在线游戏。在游戏中,需要通过 TCP 和 UDP 将数据从服务器发送到客户端。实现 UDP 打洞很容易,但我不太确定如何实现 TCP 打洞: 服务器:ServerSocket 监听给
我正在尝试使用 mingw 工具链通过 Windows 套接字实现 TCP 打洞。我认为这个过程是正确的,但洞似乎并没有采取。我用了this作为引用。 A 和B 连接到服务器S S 发送给A,B的路由
作者引言 很高兴啊,我们来到了IceRPC之试试的新玩法"打洞",让防火墙哭去吧 试试RPCs的新玩法"打洞" 比较典型的玩法:RPC数据
我目前正在尝试通过 Internet 发送 UDP 消息,并且必须为端点 A 和 B(都位于 NAT 后面)设置防火墙。为此,我想使用 STUN 服务器进行打洞。 当 A 创建对 STUN 服务器的请
实际上,我正在编写一个 Android 应用程序,该应用程序接收连接到电脑的网络摄像头的图片。为了获得更多的 fps,我使用 udp 协议(protocol)而不是 tcp。这个想法是,pc 将图片发
我已经阅读了很多关于如何实现 UDP 打洞的书,但由于某种原因我无法让它工作。 对于那些不熟悉什么是udp打洞的人,这里是我自己的定义: 目标是能够在两个客户端(客户端 A 和客户端 B) 在服务器的
我用 Java 完成了一个在 LAN 范围内运行良好的 P2P 程序,现在我陷入了众所周知的 NAT 穿越问题。我想让我的用户通过 NAT 边界相互连接(我知道不可能 100% 做到这一点)。我已经阅
问题如下。这是我当前没有成功的测试代码。 static void Main(string[] args) { if (args.Count() != 3) { Cons
几周来我一直在尝试创建套接字聊天/文件传输应用程序。我花了几个小时在互联网上搜索一段关于 UDP 打洞的代码,但我没有找到任何有效或足够简单供我使用的代码。 我正在尝试让路由器 (NAT) 后面的两个
我正在做一个客户端-服务器语音聊天程序(非托管 C++,win32),其中客户端使用 TCP 连接到服务器,文本聊天/聊天室功能在 TCP 中完成,而所有音频传输都通过单独的 UDP/RTP 套接字发
stackoverflow 用户! 我有一个必须处理 p2p 的应用程序,这就是我使用 UDP 打洞的方式。但是我在实现时遇到了麻烦。希望你能给我一些提示。 我有服务器,它工作得很好,可以互相介绍客户
我试图用打洞协议(protocol)制作一个服务器客户端。所以我将我的客户端 IP 和客户端端口发送到我的服务器,当第二个用户连接时,服务器向两个客户端发送另一个客户端的 IP 和端口。所以当我有这个
我已经建立了一个网络项目,通过打洞在 LAN 或 WAN 上进行通信。我正在为客户端使用 GCSAsyncUdpSocket。我有一个集合点服务器,它被端口转发,可以从所有传入连接访问。我的设置是这样
我在本地机器上使用以下代码: import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream
对于我的学术项目,我正在努力实现这一目标。监听端口 3000 的 Web 服务器 Node JS 应用程序。所以如果你 curl http://localhost:3000 你会得到 Hello Wo
我想在具有静态 IP 的服务器的帮助下对两个客户端进行 UDP 打洞。服务器在端口 7070 和 7071 上等待两个客户端。之后,它向对方发送 IP 地址和端口。这部分工作正常。但是我无法在两个客户
我正在尝试使用 hyperswarm我使用 Node.js API 对我 friend 的计算机进行打洞。 但我不知道从哪里获取该方法所需的参数。 node.holepunch(peer, [call
我一直在寻找一个提供可靠性的简单 UDP C++ 库。我刚刚遇到 ENet,它看起来很完美,只是我在文档中找不到对 NAT 打洞的任何支持。网上好像有几个人在讨论这个问题,但是我还没有找到一个明确的答
我试图通过 NAT 向客户端发送一个 udp 数据包,我们都属于不同的 NAT,我们熟悉 STUN 的理论因此实现这一点的方法是“打洞”我们的通过一个简单的 STUN 服务器.. 基本上服务器只返回外
我是否可以使用部署在 AppEngine 上的 servlet 实现通过 TCP 打洞连接的客户端/服务器网络模型? 如果是这样,您如何将连接请求从客户端转发到主机并建立双向连接,一旦启动就消除服务器
我是一名优秀的程序员,十分优秀!