排序变换思路:施瓦茨变换(代码片段)

f-ck-need-u f-ck-need-u     2023-01-05     265

关键词:

施瓦茨变换(Schwartzian Transform)是一种排序思路。先看看它的结构:

my @output_data =
    map  EXTRACTION ,
    sort  COMPARISON 
    map [ CONSTRUCTION ],
@input_data;

施瓦茨变换:

  • construction:构造一个由原始数据以及被处理后准备用来做排序属性的元素组成的列表A
  • comparison:从列表A中取得元素进行排序,得到排序后列表B
  • expraction:从列表B中取得原始元素得到新列表C
  • 列表C就是期待的排序结果

先举个例子,文件test.txt中的内容如下:

1     mac     2000    500
2     winxp   4000    300
3     bsd     1000    600
4     linux   1000    200
5     SUSE    4000    300
6     Debian  600     200

现在需要使用perl对该文件进行排序,以第三字段为主排序依据(升序),第四字段(升序)、第一字段(降序)分别为辅助排序依据。

下面这种代码是谁都会的:

open DATA,"<","/perlapp/test.txt"
    or die "Can't open file: $!";

print sort 
                my @x = split / +/,$a;
                my @y = split / +/,$b;
                $x[2] <=> $y[2] 
                or $x[3] <=> $y[3]
                or $y[0] <=> $x[0]
            <DATA>;

上面的排序过程中,对每一行都进行了一次split函数处理,换句话说,每一次比较操作都进行了两次split。

使用施瓦茨变换,可以将每次比较过程中每一种函数的多次操作都减少为一次,正如上面的split可以减少为一次(性能并没有更优化,只是代码减少了,更漂亮了)。

以下是使用Schwartzian Transform实现上述排序需求的代码:

open DATA,"<","/perlapp/test.txt" or die "Can't open file: $!";

print map  $_->[0] 
      sort  
          $a->[3] <=> $b->[3] 
          or $a->[2] <=> $b->[2] 
          or $b->[1] <=> $a->[1] 
      map  [ $_,split / +/,$_ ]  <DATA>;

在上面施瓦茨变换代码中(从下往上看):

  • 最后一个map函数,将<DATA>中的元素重新构建成了一个新的匿名列表A,这个列表中除了原始文件中的每一行数据,还有对每一行进行split后的元素,因为每一行都是空格分隔的,所以split后的每一个元素都直接作为匿名列表的元素。大概如下:["6 Debian 600 200","6","Debian","600","200"]
  • sort函数对匿名列表A进行排序,取列表A中需要排序的元素进行排序,排序后得到一个新的排序列表B,这个列表中仍然包含了原始数据和split后的各元素,只不过它们是经过排序后的
  • 第一个map函数从排序后的列表B中取出第一个元素,也就是文件中的元素数据,得到最终的排序列表C

很多地方说施瓦茨变换会提高排序性能,但实际上并没有,原来sort的排序方式对每个$a $b都进行了split,其实就是对每一行都进行split,施瓦茨变换后对每一行都进行split,实际上它们是一样的,只不过施瓦茨变换后是对整个<DATA>预先split好,而不是每次取$a $b的时候进行split。

也就是说,施瓦茨变换仅仅只是让sort排序的时候,取数据更直接而已,并没有提升性能。

两角相等的证明思路(代码片段)

题目来源:算法竞赛进阶指南题目标签:分治,坐标变换题目链接:https://www.acwing.com/problem/content/100/思路:不断递归找到当前点是由上一层中哪个点变换而来,从第一层开始不断向上回溯,通过坐标的变换来找到当前层中的坐... 查看详情

android高级ui解密:pathmeasure截取片段与切线(新思路实现轨迹变换)(代码片段)

前面几篇文章已经按照顺序讲解了Paint画笔、Canvas画布、Path相关内容了,也许没有面面俱到,但特地强调了其重点内容。有关Path的内容只讲解了贝塞尔曲线绘制,日后再做补充。此篇文章将介绍另外一个重点内容ÿ... 查看详情

android高级ui解密:pathmeasure截取片段与切线(新思路实现轨迹变换)(代码片段)

前面几篇文章已经按照顺序讲解了Paint画笔、Canvas画布、Path相关内容了,也许没有面面俱到,但特地强调了其重点内容。有关Path的内容只讲解了贝塞尔曲线绘制,日后再做补充。此篇文章将介绍另外一个重点内容ÿ... 查看详情

czt变换(chirpz-transform)(代码片段)

作者:桂。时间:2018-05-20  12:04:24链接:http://www.cnblogs.com/xingshansi/p/9063131.html 前言相比DFT,CZT是完成频谱细化的一种思路,本文主要记录CZT的C代码实现。一、代码实现原理主要参考MATLAB接口:对应C代码实现:Complex.c/... 查看详情

基于matlab的医学图像配准算法仿真(代码片段)

...六、参考文献一、理论基础    其中h表示二维空间坐标变换,g表示灰度或辐射变换,描述因传感器类型的不同或辐射变形所引入的图像变换。配准的目的就是要找出最佳的空间和几何变换参数。·刚体变换    如果第... 查看详情

leetcodealgorithm6.z字形变换(代码片段)

6.Z字形变换Ideas这题的思路其实只要想到了就很简单,首先创建一个numRows行的矩阵,每一行用来存Z字变换后每一行的字符,然后遍历字符串s,其实就是从上往下然后从下往上填充到每一行,所以可以用一个标... 查看详情

实现背景变换的纵向导航菜单(代码片段)

思路:ul主要用来描述列表型内容,每一个<ul></ul>中的内容为一个列表块,块中的每一条列表数据用<li></li>来描述。页面优化:采用整体到局部的方式逐层设计。一、在<head>与</head>之间插入以下代码1<... 查看详情

常见的变换总结与代码:dct,stft,k-l变换等(代码片段)

文章目录前言一、从DFT到DCT二、从CTFT到STFT三、K-L变换与降维思想四、K-L变换实例:人脸识别(含代码和详细注释)五、参考资料前言  之前学信号和DSP的时候,除了常见的离散傅里叶变换之外,还看过诸如... 查看详情

标准霍夫变换识别粗直线(代码片段)

...2.对霍夫空间进行4领域内的非最大值抑制3.对极大值进行排序,极值越大,则越有可能是直线4.输出直线我的改进:1.不对图像进行边缘检测。直接对二值图像中的黑色像素点进行霍夫变换2.非最大值抑制对于粗直线来... 查看详情

标准霍夫变换识别粗直线(代码片段)

...2.对霍夫空间进行4领域内的非最大值抑制3.对极大值进行排序,极值越大,则越有可能是直线4.输出直线我的改进:1.不对图像进行边缘检测。直接对二值图像中的黑色像素点进行霍夫变换2.非最大值抑制对于粗直线来... 查看详情

halcon几何变换(仿射变换)(代码片段)

...,可参考https://blog.csdn.net/machaoyu86/article/details/51182473仿射变换前,需要获得仿射变换矩阵。关于shape_trans(Region:RegionTrans:Type:),内、外接圆、矩形,凸包。可参考https://blog.csdn.net/u012551485/article/details/7513 查看详情

华为od机试真题java实现字符串变换最小字符串真题+解题思路+代码(2022&2

字符串变换最小字符串给定一个字符串s,最多只能进行一次变换,返回变换后能得到的最小字符串(按照字典序进行比较)。变换规则:交换字符串中任意两个不同位置的字符。 查看详情

opencv中的霍夫线变换概率霍夫线变换(代码片段)

OpenCV中的霍夫线变换、概率霍夫线变换1.效果图2.原理2.1什么是霍夫变换?2.2什么是概率霍夫变换?3.源码3.1霍夫变换3.2概率霍夫变换参考这篇博客将介绍Python,OpenCV中的霍夫变换。包括什么是霍夫变换(HoughTransfor... 查看详情

p1032字串变换(代码片段)

大致题意:通过一系列的规则将A变为B,在十步以内能变成B的话就输出步数,若超过十步则输出NOANSWER!。基本思路恶毒字串加广搜,如(哔~)一般真恶心!能A这道题真不容易,真·WA了无数次啊啊啊。康康这惨不忍睹的评测记录:这**... 查看详情

初学opencvc++学习笔记透视变换--warpperspective()(代码片段)

这篇博客将用简单的口吻谈一谈透视变换是啥以及如何操作~  但是这篇博客,只要你看了,我相信会有收获~~~~~~~~~~~~~~~~  ~~~~~~~~~目录一、透视变换介绍1.基础介绍:二、透视变换apl介绍---- warpPerspective()1.官方定义2.... 查看详情

opencv中的图像变换——傅里叶变换(代码片段)

OpenCV中的图像变换——傅里叶变换1.效果图2.原理3.源码3.1Numpy实现傅里叶变换3.2OpenCV实现傅里叶变换3.3HPForLPF?参考这篇博客将介绍OpenCV中的图像变换,包括用Numpy、OpenCV计算图像的傅里叶变换,以及傅里叶变换的一些... 查看详情

图像处理灰度变换(代码片段)

1灰度变换简介  灰度变换是对图像的每个像素按照灰度映射函数进行映射的变换,其作用于每个像素。灰度变换一般用来进行图像增强,提高图像的对比度,改善图像的灰度分布等。灰度变换根据灰度变换函数的... 查看详情

图像处理灰度变换(代码片段)

1灰度变换简介  灰度变换是对图像的每个像素按照灰度映射函数进行映射的变换,其作用于每个像素。灰度变换一般用来进行图像增强,提高图像的对比度,改善图像的灰度分布等。灰度变换根据灰度变换函数的... 查看详情