介绍
进入第四天,我们面前有一个网格问题,我们得到了一些网格形式的数字,即一些带有一些大写字母的行和列。我们需要做的是在任意方向(上、左、下、右、对角线)找到单词 XMAS,而在第二部分中我们需要找到形成 X 的单词 MAS。
那么,让我们看看如何在 golang 中解决这个问题。
您可以在 GitHub 上查看我的解决方案。
破坏先生
/
代码出现
代码的出现
构建网格
问题最根本的部分在于实际上将文本转换为网格或矩阵形式。我们可以将行分割成单独的行,并将每个字符作为列表中的元素附加,这样我们就可以得到一个字符串列表列表,它是一个矩阵或网格状(二维)结构。
所以,下面是谜题的输入。
MMMSXXMASM MSAMXMSMSA AMXSXMAAMM MSAMASMSMX XMASAMXAMM XXAMMXXAMA SMSMSASXSS SAXAMASAAA MAMMMXMMMM MXMXAXMASX
我们需要将其转换成这样的
[ [M M M S X X M A S M] [M S A M X M S M S A] [A M X S X M A A M M] [M S A M A S M S M X] [X M A S A M X A M M] [X X A M M X X A M A] [S M S M S A S X S S] [S A X A M A S A A A] [M A M M M X M M M M] [M X M X A X M A S X] ]
所以,这是一个字符串列表,我们可以在 golang 中说它是一个 [][]string 。我们可以通过创建这样的函数来做到这一点:
func ConstructGrid(lines []string) [][]string { grid := [][]string{} for _, line := range lines { row := []string{} for _, char := range strings.Split(line, "") { row = append(row, char) } grid = append(grid, row) } return grid }
上面的函数接受一个字符串列表并返回一个字符串列表,这些字符串是网格中的单个字母。
我们可以读取文件字节并按换行符分割字节,然后将其用作此函数的输入。
因此,一旦输入被解析为网格,我们就可以开始思考在其中查找单词 XMAS 的实际逻辑。
第 1 部分
所以,在第一部分中,我们需要在矩阵中找到可能出现的单词 XMAS:
转发(作为 XMAS)
向后(如 SAMX)
向上
S A M X
- 向下
X M A S
- 对角线向上(右或左上)
S A M X OR S A M X
- 对角线向下(右或左)
X M A S OR X M A S
所以,XMAS 可以出现在网格中的方向有 8 个,这些 XMAS 的数量可能有 n 个。我们需要找到网格中这些的数量。
为了解决这个问题,我们可以找到单词 XMAS 中的第一个字符,然后逐个搜索所有方向并检查是否找到 M,如果在任何方向上找到 M,我们继续前进那个方向,检查那个方向是否有A和S。
方法如下:
将计数器初始化为 0
-
迭代每一行
-
迭代行中的每个字符
- 检查字符是否等于X
-
如果角色是X→
-
迭代所有方向(上、下、右、左、左上、右上、左下、右下)
- 对于那个方向,如果我们发现字符是M
- 继续向同一方向前进,类似地找到A和S,如果找到所有字符XMAS,则增加计数器
- 否则选择循环中的另一个方向
-
-
这个看起来复杂又庞大,其实很简单,一次专注一件事,你就能轻松解决。
因此,为了实现这一点,我们需要首先定义一些东西:
MMMSXXMASM MSAMXMSMSA AMXSXMAAMM MSAMASMSMX XMASAMXAMM XXAMMXXAMA SMSMSASXSS SAXAMASAAA MAMMMXMMMM MXMXAXMASX
因此,我们定义了方向上的整数列表,这些整数是我们需要添加或减去才能到达所需位置的 x 和 y 坐标。它基本上就像一个单位向量,它的距离为 1,方向由 或 表示 - 表示 x 坐标向左或向右移动,y 坐标上下移动。
所以,让我更清楚地解释一下,假设我位于 4x4 维度的网格中的 (1,2)。
[ [M M M S X X M A S M] [M S A M X M S M S A] [A M X S X M A A M M] [M S A M A S M S M X] [X M A S A M X A M M] [X X A M M X X A M A] [S M S M S A S X S S] [S A X A M A S A A A] [M A M M M X M M M M] [M X M X A X M A S X] ]
所以,在 2,1 处我们有 G ,所以我们检查一些方向
向上 → 0,-1 → 2 0, 1-1 → 2,0,我们已经移动到 C
右 → 1,0 → 2 1, 1 0 → 3,1 ,我们已经移动到 H
下、左→ -1,1 → 2-1, 1 1 → 1, 2,我们已经移动到 J
所以,你明白了,我们正在使用这些坐标向某些方向移动。
我们可以使用它们来获得我们想要进行的下一个方向跳跃,以查找该元素是否具有我们正在搜索的单词中的下一个字符。
我们将编写一个函数来首先执行此操作,并抽象该函数来检查我们是否在网格中找到了该单词。
func ConstructGrid(lines []string) [][]string { grid := [][]string{} for _, line := range lines { row := []string{} for _, char := range strings.Split(line, "") { row = append(row, char) } grid = append(grid, row) } return grid }
上面的函数接受一个网格并返回一个整数,该整数将作为分数,即在网格/矩阵中找到的 XMAS 单词数。
首先,我们需要迭代网格中的每一行,对于每一行,我们迭代字符,因此我们将 x 和 y 坐标作为网格的索引。然后我们需要检查当前字符是否是 X 或 wordList[0] ,如果是这种情况,我们迭代所有方向并检查是否可以找到 XMAS,即该方向上的 MAS,如果是,我们递增计数器。 FindXMAS 函数是什么,让我们将其抽象出来,并传入 x、y,它们是当前单词的坐标,1 将是 XMAS 的单词位置,在这种情况下,我们已经找到了我们需要的 X找到那个方向的 MAS。我们传递网格和方向,因此如果该方向中有 MAS,该函数将返回 true 或 false。
因此迭代:
我们迭代网格并获取 row 和 x 作为当前行的字符串列表和索引。
对于每一行,即字符串列表,我们迭代字符串列表以获取 char 和 y 作为字符(字符串)以及该字符在字符串列表中的索引。
-
如果我们发现当前字符等于 X,即 wordList 的第 0 个索引
- 我们迭代所有方向并调用函数 FindXMAS 来检查剩余单词是否在该方向 MAS
- 如果我们找到所有单词,我们就会增加计数器。
因此,我们在计算网格/矩阵中 XMAS 的单词数时返回计数器。
现在,我们可以实现 FindXMAS 函数,它接受 x、y 坐标、单词位置、方向和网格,如果找到单词则返回。
首先,我们获取当前的 x 坐标并添加方向的 x 分量(第 0 个索引或第一个元素)
将当前 y 坐标添加到方向的 y 分量(第一个索引或第二个元素)
如果当前函数中的单词位置,即单词索引或单词本身等于wordList,则表示已经完全找到了所需的单词
我们需要通过将方向添加到 x 和 y 坐标来检查,我们没有超出网格的宽度和高度,因此如果超出,我们将返回 false
最后的 if 用于检查当前字符是否等于我们要查找的单词,它可以是 M、A 或 S 。如果是这样,我们通过传递更新的 x 和 y 坐标以及 wordList 中的下一个单词来返回递归调用 FindXMAS 函数,我们保持方向相同并传递整个网格。
MMMSXXMASM MSAMXMSMSA AMXSXMAAMM MSAMASMSMX XMASAMXAMM XXAMMXXAMA SMSMSASXSS SAXAMASAAA MAMMMXMMMM MXMXAXMASX
因此,我们已经实现了 FindXMAS 函数,如果我们通过更新坐标并检查网格中该位置的单词是否是 MAS 中的下一个单词,沿着特定方向找到 MAS 单词,则该函数将返回列表。
所以,这就是整个第一部分的样子:
[ [M M M S X X M A S M] [M S A M X M S M S A] [A M X S X M A A M M] [M S A M A S M S M X] [X M A S A M X A M M] [X X A M M X X A M A] [S M S M S A S X S S] [S A X A M A S A A A] [M A M M M X M M M M] [M X M X A X M A S X] ]
我们将行作为字符串列表,并将其传递给 ConstructGrid 并获取网格,最后,我们调用 TraverseGrid ,通过传递网格并获取分数作为网格中 XMAS 单词的计数。
这是第 1 部分的内容。
第2部分
对于第二部分,我们需要找到十字形状的 MAS,如下所示:
func ConstructGrid(lines []string) [][]string { grid := [][]string{} for _, line := range lines { row := []string{} for _, char := range strings.Split(line, "") { row = append(row, char) } grid = append(grid, row) } return grid }
所以,为了解决这个问题,我们可以采取类似的方法,但更简单,我们只需要找到 A,因为中心总是有 MAS 这个词,所以我们只需检查是否有 A 和左上角、右上角、右下角、左下角有 M 或 S 。
通过加1和减1得到右上角、左上位置、右下位置和左下位置的坐标。我们会进行基本检查,看看是否超出了网格的边界。如果我们超出界限,我们将找不到 MAS
但是如果我们在网格内,我们现在得到这 4 个位置的字符,我们检查左上角和右下角是否有 M 和 S 或 S 或 M,右上角和左下角类似分别具有M和S或S或M。这是字符 A 上方和下方的 M 和 S 的对角线搜索。
因此,如果我们的对角线都匹配,我们将返回 true。
S A M X
这就是寻找 MAS 对角线的简单实现。
现在,我们需要稍微更改一下 TraverseGrid,因为我们只是迭代网格,并检查行中的字符中是否有 A,即 wordList[2]。现在,如果我们有 A,我们需要使用当前坐标和网格调用 FindMAS 函数,如果该函数返回 true,我们将增加计数器。
MMMSXXMASM MSAMXMSMSA AMXSXMAAMM MSAMASMSMX XMASAMXAMM XXAMMXXAMA SMSMSASXSS SAXAMASAAA MAMMMXMMMM MXMXAXMASX
所以,这就是第2部分的最终实现,我们得到了横向MAS的计数。
您可以在 GitHub 上查看我的解决方案。
结论
所以,这就是 Golang 代码降临的第四天,如果您有任何建议,以及您是如何实现的,请告诉我。有更好的解决方案吗?
快乐编码:)
以上是Golang 代码日的到来:搜索 XMAS 和 X-MAS的详细内容。更多信息请关注PHP中文网其他相关文章!

Go的"strings"包提供了丰富的功能,使字符串操作高效且简单。1)使用strings.Contains()检查子串。2)strings.Split()可用于解析数据,但需谨慎使用以避免性能问题。3)strings.Join()适用于格式化字符串,但对小数据集,循环使用 =更有效。4)对于大字符串,使用strings.Builder构建字符串更高效。

Go语言使用"strings"包进行字符串操作。1)拼接字符串使用strings.Join函数。2)查找子串使用strings.Contains函数。3)替换字符串使用strings.Replace函数,这些函数高效且易用,适用于各种字符串处理任务。

资助bytespackageingoisesential foreffited byteSemanipulation,uperingFunctionsLikeContains,index,andReplaceForsearchingangingAndModifyingBinaryData.itenHancesperformanceNandCoderAceAnibility,MakeitiTavitalToolToolToolToolToolToolToolToolToolForhandLingBinaryData,networkProtocols,networkProtocoLss,networkProtocols,andetFilei

Go语言使用"encoding/binary"包进行二进制编码与解码。1)该包提供binary.Write和binary.Read函数,用于数据的写入和读取。2)需要注意选择正确的字节序(如BigEndian或LittleEndian)。3)数据对齐和错误处理也是关键,确保数据的正确性和性能。

1)usebybytes.joinforconcatenatinges,2)bytes.bufferforincrementalWriter,3)bytes.indexorbytes.indexorbytes.indexbyteforsearching bytes.bytes.readereforrednerncretinging.isnchunk.ss.ind.inc.softes.4)

theencoding/binarypackageingoiseforporptimizingBinaryBinaryOperationsDuetoitssupportforendiannessessandefficityDatahandling.toenhancePerformance:1)usebinary.nativeendiandiandiandiandiandiandiandian nessideendian toavoid avoidByteByteswapping.2)

Go的bytes包主要用于高效处理字节切片。1)使用bytes.Buffer可以高效进行字符串拼接,避免不必要的内存分配。2)bytes.Equal函数用于快速比较字节切片。3)bytes.Index、bytes.Split和bytes.ReplaceAll函数可用于搜索和操作字节切片,但需注意性能问题。

字节包提供了多种功能来高效处理字节切片。1)使用bytes.Contains检查字节序列。2)用bytes.Split分割字节切片。3)通过bytes.Replace替换字节序列。4)用bytes.Join连接多个字节切片。5)利用bytes.Buffer构建数据。6)结合bytes.Map进行错误处理和数据验证。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

SecLists
SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

PhpStorm Mac 版本
最新(2018.2.1 )专业的PHP集成开发工具

SublimeText3汉化版
中文版,非常好用

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

EditPlus 中文破解版
体积小,语法高亮,不支持代码提示功能