【算法】国庆加班,火锅与Linq.AddRange的奇妙螺旋

这篇具有很好参考价值的文章主要介绍了【算法】国庆加班,火锅与Linq.AddRange的奇妙螺旋。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在国庆假期的一个傍晚,小悦正在家中享受火锅美食。她嘴里咀嚼着鲜嫩的牛肉,脸上洋溢着满足的微笑。突然,手机铃声响起,打破了这温馨的氛围。她拿起手机一看,是公司打来的电话。

“小悦,有个紧急的项目需要处理,你能来公司加一下班吗?”电话那头传来领导焦急的声音。

小悦顿时嘟起嘴,不太情愿地离开了火锅桌,踏上前往公司的路程。

一到公司,小悦就开始研究领导交给她的任务:处理一个关于小视频螺旋排序算法的问题。这个问题让她感到有些棘手,但她知道没有退缩的余地。于是,她深吸了一口气,开始认真地研究问题。

在图像处理中,螺旋排序算法是一个非常有用的工具。通过将图像按照螺旋顺序排列,可以更方便地对图像进行处理和分析。例如,可以将图像分成多个小块进行特征提取、图像压缩等操作。小悦明白,要解决这个问题,首先需要理解螺旋排序算法的原理。

她开始在纸上画出图像的分块示意图,尝试寻找规律。经过一番推导和实践,她逐渐掌握了螺旋排序算法的核心思想。接着,她开始编写代码来实现这个算法。

时间在悄然流逝,窗外的夜幕渐渐降临。尽管劳累了一天,但小悦的心情却渐渐变得愉悦起来。她在解决问题的过程中感受到了挑战的乐趣和收获的喜悦。当她最终完成代码并成功运行出结果时,她的心中充满了成就感。

“终于解决了!”小悦长出一口气,脸上露出了满意的微笑。她收拾好东西,准备离开公司。走出办公室的那一刻,她抬头看到夜空中繁星点点,心中不禁感慨万分。这个国庆假期,或许没有如愿以偿地休息和放松,但她却在工作中取得了宝贵的进步。

回到家中,小悦继续享受火锅美食。她夹起一块牛肉放进嘴里,细细品味着它的鲜美。这个国庆假期,虽然没有游山玩水的快乐,但她却收获了成长和充实。

小悦面临的问题如下:给定一个n乘n二维数组,按照从最外层元素到中间元素的顺序,排序,顺时针移动,返回排序后的一维数组。

示例:

array = [[1,2,3],
         [4,5,6],
         [7,8,9]]
snail(array) #=> [1,2,3,6,9,8,7,4,5]
图解:

【算法】国庆加班,火锅与Linq.AddRange的奇妙螺旋 


算法实现1:
 1 public static int[] Snail(int[][] array)
 2 {
 3     // 获取数组的长度
 4     int l = array[0].Length;
 5     // 创建一个用于存储排序后元素的数组
 6     int[] sorted = new int[l * l];
 7     // 递归调用 Snail 方法进行螺旋排序
 8     Snail(array, -1, 0, 1, 0, l, 0, sorted);
 9     // 返回排序后的数组
10     return sorted;
11 }
12 
13 public static void Snail(int[][] array, int x, int y, int dx, int dy, int l, int i, int[] sorted)
14 {
15     // 如果数组长度为 0,则直接返回
16     if (l == 0)
17         return;
18     // 循环遍历当前层的元素
19     for (int j = 0; j < l; j++)
20     {
21         // 更新当前元素的坐标,并将其存储到排序数组中
22         x += dx;
23         y += dy;
24         sorted[i++] = array[y][x];
25     }
26     // 递归调用 Snail 方法进行下一层的螺旋排序
27     Snail(array, x, y, -dy, dx, dy == 0 ? l - 1 : l, i, sorted);
28 }

假设我们有一个二维数组array,其中包含了3行3列的整数。数组的内容如下:

1 2 3
4 5 6
7 8 9

我们希望通过螺旋排序算法将这个二维数组按照螺旋顺序排列,并得到一个结果数组r,其中包含按照螺旋顺序排列的元素。结果数组的内容如下:

1 2 3 6 9 8 7 4 5

我们将调用Test方法来测试螺旋排序算法。在Test方法中,首先将二维数组array转换为字符串,并将结果与预期的结果数组r进行比较。如果转换后的字符串与预期结果字符串相等,则测试通过;否则,测试失败。

接下来,让我们详细解释一下螺旋排序算法的运行过程:

  1. 首先,算法会初始化一个空的结果数组snail,用于存储按照螺旋顺序排列的元素。

  2. 然后,算法会定义四个变量:topbottomleftright,分别表示当前螺旋排序的上边界、下边界、左边界和右边界。初始时,top为0,bottom为2,left为0,right为2。

  3. 接着,算法会进入一个循环,直到上边界大于下边界或左边界大于右边界为止。

  4. 在每一次循环中,算法会按照螺旋顺序遍历数组的四条边,并将遍历到的元素添加到结果数组snail中。

  5. 首先,算法会从左到右遍历上边界,并将遍历到的元素添加到结果数组snail中。在这个测试用例中,遍历到的元素为1 2 3

  6. 然后,算法会将上边界下移一行,即top++,此时上边界变为1。

  7. 接着,算法会从上到下遍历右边界,并将遍历到的元素添加到结果数组snail中。在这个测试用例中,遍历到的元素为6 9

  8. 然后,算法会将右边界左移一列,即right--,此时右边界变为1。

  9. 接着,算法会从右到左遍历下边界,并将遍历到的元素添加到结果数组snail中。在这个测试用例中,遍历到的元素为8 7

  10. 然后,算法会将下边界上移一行,即bottom--,此时下边界变为1。

  11. 接着,算法会从下到上遍历左边界,并将遍历到的元素添加到结果数组snail中。在这个测试用例中,遍历到的元素为4

  12. 最后,在这个测试用例中,算法会发现左边界大于右边界,因此跳出循环。

  13. 最后,算法会返回结果数组snail,其中包含按照螺旋顺序排列的元素。在这个测试用例中,返回的结果数组为1 2 3 6 9 8 7 4 5

  14. Test方法中,我们将转换后的结果数组与预期的结果数组进行比较。如果它们相等,则测试通过;否则,测试失败。


算法实现2:
 1     public static int[] Snail(int[][] grid)
 2     {
 3         var result = new List<int>();
 4 
 5         //通过grid.SelectMany(row => row).Any()判断二维数组grid是否为空。如果为空,则直接返回空的结果数组。
 6         if (!grid.SelectMany(row => row).Any())
 7             return result.ToArray();
 8 
 9         //将二维数组的第一行添加到结果数组中
10         result.AddRange(grid.First());
11 
12         //将二维数组的最右一列(除去第一行)添加到结果数组中
13         result.AddRange(grid.Skip(1).Select(row => row.Last()));
14 
15        //将二维数组的最后一行(除去第一行和最后一个元素)逆序添加到结果数组中
16         result.AddRange(grid.Last().Reverse().Skip(1));
17 
18        //将二维数组的最左一列(除去第一行、最后一行和第一个元素)逆序添加到结果数组中
19         result.AddRange(grid.Skip(1).SkipLast(1).Select(row => row.First()).Reverse());
20 
21         var newGrid = grid
22                 .Skip(1)
23                 .SkipLast(1)
24                 .Select(row => row
25                     .Skip(1)
26                     .SkipLast(1)
27                     .ToArray())
28                 .ToArray();
29 
30        //通过递归调用Snail方法,将去掉了二维数组的第一行、最后一行、第一列和最后一列后的新二维数组传入,并将返回的结果数组添加到当前的结果数组中
31         result.AddRange(Snail(newGrid));
32 
33         return result.ToArray();
34     }

这段代码的逻辑与算法1的功能相同,只是在创建新二维数组newGrid时,使用了链式调用的方式来去掉边界元素。

AddRange 是一个常用在 LINQ 中的方法,通常在 List<T> 或 Dictionary<TKey, TValue> 等集合类型中使用。这个方法用于将另一个集合中的元素添加到当前集合中。

首先,代码通过Skip(1)去掉了第一行,然后通过SkipLast(1)去掉了最后一行,接着通过Select(row => row.Skip(1).SkipLast(1).ToArray())去掉了每一行的第一个元素和最后一个元素,最后通过ToArray()将结果转换为新的二维数组。这样,递归调用Snail方法时传入的新二维数组就是去掉了边界的数组。


 假设我们有一个100x100像素的图像,我们想要将其分成10x10个小块进行特征提取或图像压缩。在没有使用螺旋排序算法之前,我们可以按照图像的行优先顺序将像素按顺序分成小块。这意味着我们首先将图像的第一行的前10个像素作为第一个小块,然后是第一行的下一个10个像素作为第二个小块,依此类推,直到图像的第10行。然后,我们继续将图像的第11行的前10个像素作为第11个小块,以此类推,直到图像的最后一行。

这种方法的问题是,它没有考虑到图像的局部结构。相邻的像素在图像中可能是相关的,而按行顺序分块可能会将相关的像素分散在不同的块中。这可能导致特征提取或图像压缩的结果不够准确或失真。

现在,如果我们使用螺旋排序算法来分块图像,我们可以更好地保留图像的局部结构。螺旋排序算法按照螺旋顺序遍历图像的像素,并将它们分成小块。这意味着我们首先将图像的中心像素作为第一个小块,然后按照螺旋顺序将相邻的像素添加到下一个小块,直到所有像素都被分到小块中。

通过使用螺旋排序算法,我们可以更好地保留图像的局部结构,因为相邻的像素通常在空间上也是相邻的。这有助于提高特征提取或图像压缩的准确性和质量。

所以螺旋排序算法在各个领域都有一定的应用价值,可以帮助提高数据处理和分析的效率,优化系统设计和布局,以及改善数据的可视化效果:

  1. 图像处理:在图像处理中,螺旋排序算法可以用于对图像进行分块处理。通过将图像按照螺旋顺序排列,可以更方便地对图像进行处理和分析。例如,可以将图像分成多个小块进行特征提取、图像压缩等操作。

  2. 数据存储和检索:螺旋排序算法可以用于对二维数组或矩阵进行存储和检索。通过按照螺旋顺序对数据进行排序,可以提高数据的访问效率。例如,在二维地图导航系统中,可以将地图数据按照螺旋顺序进行存储,以便快速检索和显示地图信息。

  3. 数据可视化:螺旋排序算法可以用于数据可视化,特别是对于二维数据的可视化。通过按照螺旋顺序对数据进行排序,可以将数据按照一定的规律展示出来,更直观地观察数据的分布和变化。例如,在热力图中,可以按照螺旋顺序对温度数据进行排序,以便更清晰地显示温度的变化趋势。

  4. 电路布局:在电路设计中,螺旋排序算法可以用于电路布局的优化。通过按照螺旋顺序对电路元件进行排序,可以减少电路布线的长度和复杂度,提高电路的性能和可靠性。文章来源地址https://www.toymoban.com/news/detail-710595.html


测试用例:
  1 using NUnit.Framework;
  2 using System;
  3 using System.Linq;
  4 public class SnailTest
  5 {
  6 
  7     private int[] Tsnail(int[][] array)
  8     {
  9         int[] sorted = new int[array.Length * array.Length];
 10         Tsnail(array, -1, 0, 1, 0, array.Length, 0, sorted);
 11         return sorted;
 12     }
 13 
 14     private void Tsnail(int[][] array, int x, int y, int dx, int dy, int l, int i, int[] sorted)
 15     {
 16         if (l == 0)
 17             return;
 18         for (int j = 0; j < l; j++)
 19         {
 20             x += dx;
 21             y += dy;
 22             sorted[i++] = array[y][x];
 23         }
 24         Tsnail(array, x, y, -dy, dx, dy == 0 ? l - 1 : l, i, sorted);
 25 
 26     }
 27 
 28     public string Int2dToString(int[][] a)
 29     {
 30         return $"[{string.Join("\n", a.Select(row => $"[{string.Join(",", row)}]"))}]";
 31     }
 32 
 33     public void Test(int[][] array, int[] result)
 34     {
 35         var text = $"{Int2dToString(array)}\nshould be sorted to\n[{string.Join(",", result)}]\n";
 36         Console.WriteLine(text);
 37         Assert.AreEqual(result, SnailSolution.Snail(array));
 38     }
 39 
 40     [Test]
 41     public void SnailTest1()
 42     {
 43         int[][] array =
 44         {
 45             new []{1, 2, 3},
 46             new []{4, 5, 6},
 47             new []{7, 8, 9}
 48         };
 49         var r = new[] { 1, 2, 3, 6, 9, 8, 7, 4, 5 };
 50         Test(array, r);
 51     }
 52 
 53     [Test]
 54     public void SnailTest2()
 55     {
 56         int[][] array =
 57         {
 58             new []{1, 2, 3, 9},
 59             new []{4, 5, 6, 4},
 60             new []{7, 8, 9, 1},
 61             new []{1, 2, 3, 4}
 62         };
 63         var r = new[] { 1, 2, 3, 9, 4, 1, 4, 3, 2, 1, 7, 4, 5, 6, 9, 8 };
 64         Test(array, r);
 65     }
 66 
 67     [Test]
 68     public void SnailTest2Empty()
 69     {
 70         int[][] a = { new int[] { } };
 71         Test(a, new int[0]);
 72     }
 73 
 74     [Test]
 75     public void SnailTestOne()
 76     {
 77         int[][] a = { new[] { 1 } };
 78         Test(a, new[] { 1 });
 79     }
 80 
 81 
 82     [Test]
 83     public void SnailRandomTest()
 84     {
 85         Console.WriteLine("Random Tests");
 86         Random rand = new Random();
 87         for (int n = 0; n < 100; n++)
 88         {
 89             var l = rand.Next(1, 31);
 90             var array = new int[l][];
 91             for (int i = 0; i < l; i++)
 92             {
 93                 array[i] = new int[l];
 94                 for (int j = 0; j < l; j++)
 95                     array[i][j] = rand.Next(1, 1001);
 96             }
 97             Test(array, Tsnail(array));
 98         }
 99     }
100 }

到了这里,关于【算法】国庆加班,火锅与Linq.AddRange的奇妙螺旋的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 算法leetcode|54. 螺旋矩阵(rust重拳出击)

    给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。 m == matrix.length n == matrix[i].length 1 = m, n = 10 -100 = matrix[i][j] = 100 面对这道算法题目,二当家的再次陷入了沉思。 可以每次循环移动一步,判断移到边界就变换方向,巧用数组可以减少逻辑判断

    2024年02月08日
    浏览(47)
  • Python 集合探索:解密高效数据操作和快速算法的奇妙世界

    在 Python 的众多数据结构中,集合(Sets)是一个引人注目且实用的概念。集合提供了一种存储无顺序、唯一元素的数据结构,它们不仅可以帮助我们高效处理数据,还能应用于各种算法和问题。 本博客将带您踏上一段关于 Python 集合的探索之旅。我们将深入了解集合的基本概

    2024年02月12日
    浏览(57)
  • 算法leetcode|59. 螺旋矩阵 II(rust重拳出击)

    给你一个正整数 n ,生成一个包含 1 到 n 2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。 1 = n = 20 面对这道算法题目,二当家的再次陷入了沉思。 可以每次循环移动一步,判断移到边界就变换方向,巧用数组可以减少逻辑判断的复杂性。 也可以每次循环

    2024年02月11日
    浏览(41)
  • 【算法题】螺旋矩阵 I II III IV

    目录 1. 螺旋矩阵 2. 螺旋矩阵 II 3. 螺旋矩阵 III 4. 螺旋矩阵 IV 题目描述: 给你一个m行n列的矩阵matrix,请按照顺时针螺旋顺序 ,返回矩阵中的所有元素。 提示: m == matrix.length n == matrix[i].length 1 = m, n = 10 -100 = matrix[i][j] = 100 题解: 4×5的矩阵按顺时针螺旋顺序打印如图所示。

    2024年02月15日
    浏览(42)
  • 【算法-数组3】螺旋数组(一入循环深似海啊!)

    今天,带来数组相关算法的讲解。文中不足错漏之处望请斧正! 理论基础点这里 这道题主要是模拟转圈过程,但是要处理的边界条件比较多,常见的问题就是每条边的处理都有自己的逻辑,那这就很难。如果不明确每条边该如何遍历,比如当 n=5 ,上行填充5个元素,但是右

    2024年02月05日
    浏览(33)
  • 【算法训练-数组 三】【数组矩阵】螺旋矩阵、旋转图像、搜索二维矩阵

    废话不多说,喊一句号子鼓励自己:程序员永不失业,程序员走向架构!本篇Blog的主题是螺旋矩阵,使用【二维数组】这个基本的数据结构来实现 二维数组的结构特性入手 根据题目示例 matrix = [[1,2,3],[4,5,6],[7,8,9]] 的对应输出 [1,2,3,6,9,8,7,4,5] 可以发现,顺时针打印矩阵的顺序

    2024年02月06日
    浏览(51)
  • 【算法题】螺旋矩阵II (求解n阶Z形矩阵)

    一、问题的提出 n 阶 Z 形矩阵的特点是按照之( Z ) 字形的方式排列元素。 n 阶 Z 形矩阵是指矩阵的大小为 n × n ,其中 n 为正整数。 一个  n   行  n   列的螺旋( Z 形)矩阵如图1所示,观察并找出填数规律。 图1  7行7列和8行8列的螺旋( Z 形)矩阵 现在给出矩阵大小  n ,请你输

    2024年02月13日
    浏览(32)
  • 【数据结构与算法系列5】螺旋矩阵II (C++ & Python)

    给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。 示例 1: 示例 2: 提示: 1 = n = 20 使用和二分法一样的思想,确定循环不变量,确定是左闭右开,还是左闭右闭合,本次使用的是左闭右开 C++ 实现: python 实现:

    2024年02月09日
    浏览(41)
  • 算法-有序数组的平方,长度最小的子数组,螺旋矩阵II

    伪装成一个老手! 题目 给你一个按 非递减顺序 排序的整数数组 nums,返回每个数字的平方组成的新数组,要求也按非递减顺序排序。 示例 : 输入:nums = [-4,-1,0,3,10] 输出:[0,1,9,16,100] 解释:平方后,数组变为 [16,1,0,9,100] 排序后,数组变为 [0,1,9,16,100] 来源:力扣977 思路 遍

    2024年02月11日
    浏览(41)
  • 算法训练第二天|977.有序数组的平方、209.长度最小的有序数组、59.螺旋矩阵2

    题目链接:力扣 思路:同样使用双指针的方法,这样就可以只遍历一次原数组。 可以考虑需要按照一个顺序来遍历,那就是从大到小或者从小到大,我选择的是从大到小。 不难看出,原数组将每个数平方后,呈现从两边到中间逐渐减小的规律。 所以使用一个指针指向原数组

    2023年04月22日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包