Perl中著名的Schwartzian转换问题解决实现


Posted in Python onJune 02, 2015

Perl中著名的Schwartzian转换,其产生背景主要涉及到排序问题:
比如说,根据文件名以字母顺序排序,代码如下:

use strict;  

use warnings;  

   

my @files = glob "*.xml";          #perl中文件操作符glob提供相当于shell中的通配符的功能  

my @sorted_files = sort @files;    #sort(),排序,默认是字母顺序排序

比如说,根据文件名长度排序,其代码如下:
use strict;  

use warnings;  

  

#length求长度。 太空船操作符<=>,默认变量是$a,$b,返回值为-1,0,1分别表示大于,==,小于。 sort进行排序  

my $files = ".xml";  

my @sorted_length = sort { length($a) <=> length($b) } @files; 

上面的两种情况,对很多文件操作来说,速度还不算慢,如果是下面这种情况。
比如说:要批量比较文件大小,其代码如下:
use strict;  

use warnings;  

   

my @files     = glob "*.xml";     

my @sort_size = sort { -s $a <=> -s $b } @files;  #比较大小 

上面的代码设计到三重(次)操作:
1. 从硬盘上获取文件大小(-s $b)
2. 比较文件大小(太空船操作)
3. 对其进行排序(sort操作)
考虑到要比较$a,$b大小时,要从硬盘中获取两次,所以次数是6次!也就是说,如果有1万个文件,总共是6万次。
其算法复杂度是: n*long(n),考虑到后两项(比较文件大小,进行排序)必然要进行的操作,但第一项却可以降低!
即一次性从硬盘中读取所有文件大小,将其放置到Perl中的默认的变量,并存储到内存中!于是又下面算法实现:
use strict;  

use warnings;  

  

my @files = glob "*.xml";  

  

my @unsorted_pairs = map  { [$_, -s $_] } @files;  

my @sorted_pairs   = sort { $a->[1] <=> $b->[1] } @unsorted_pairs;  

my @sorted_files   = map  { $_->[0] } @sorted_pairs; 

看上去比较复杂,分三个步骤解释下:
第一步:遍历文件列表,对每个文件创建一个数组引用。数组引用包含两个元素:
       第一个是文件名($_),第二个是文件大小(-s $_)。这样,处理每个文件只访问一次磁盘。
第二步:对二维数组排序。因比较文件大小,所以需取元素[1],比较它们的值。得到另一个二维数组。
第三步:丢掉文件大小元素,创建一个只含文件名的列表。完成目标!
上面的代码使用了两个临时数组,但这并不是必须的。我们可以一个语句就能完成所有的工作。为了达到目的,需要按照“数据从右流向左”的原理反转句子顺序,不如果将每个句子放在单独一行,并且留出足够的空间,我们依然可以写出可读性高的代码。
my @quickly_sorted_files =  

    map  { $_->[0] }  

    sort { $a->[1] <=> $b->[1] }  

    map  { [$_, -s $_] }  

    @files; 

这就是以Randal L. Schwartz命名的Schwartzian转换,对数据量特多的情况下,其速度要比前者快数倍!
下面写了小程序,包括在生成1万个xml文件,在两种情况下,完整代码如下:
#!/usr/bin/perl -w  

use strict;  

use warnings;  

use autodie;  

use v5.10;  

  

######################################  

###  创建要比较的10,000个.xml文件 ###  

######################################  

my $profix = ".xml";  

  

foreach my $num (1..10000) {  

    open(my $fh, '>', $num . $profix) || die "Can not create the file: $!\n";  

    print $fh "This is file size testing!";  

}  

  

print "All the 10_1000 files created! \n";  

  

  

######################################  

### 常规转换:      遍历20次       ###  

######################################  

my $t1  = time();  

  

foreach (1..20){   

    my @files     = glob "*.xml";  

    my @sorted    = sort { -s $a <=> -s $b } @files;  

}  

  

say "常规算法需要时间: => ", time()- $t1;  

  

  

######################################  

### Schwartzian转换: 遍历20次     ###  

######################################  

my $t2  = time();  

  

foreach (1..20){   

    my @files = glob "*.xml";  

        my @sorted =   

            map  {$_->[0]}  

            sort {$a->[1] <=> $b->[1]}  

            map  {[$_, -s $_]}  

       @files;  

} 
say "Schwartzian算法需要时间: => ", time()- $t2; 

输出结果:
All the 10_1000 files created!
常规算法需要时间:          => 185
Schwartzian算法需要时间: => 115

Python 相关文章推荐
python获得linux下所有挂载点(mount points)的方法
Apr 29 Python
在Python的Flask中使用WTForms表单框架的基础教程
Jun 07 Python
python中利用xml.dom模块解析xml的方法教程
May 24 Python
python的构建工具setup.py的方法使用示例
Oct 23 Python
Python实现识别手写数字 Python图片读入与处理
Mar 23 Python
使用python3构建文件传输的方法
Feb 13 Python
python中下标和切片的使用方法解析
Aug 27 Python
pytorch torch.nn.AdaptiveAvgPool2d()自适应平均池化函数详解
Jan 03 Python
Python基础类继承重写实现原理解析
Apr 03 Python
Python页面加载的等待方式总结
Feb 28 Python
Pytorch之扩充tensor的操作
Mar 04 Python
教你如何使用Python Tkinter库制作记事本
Jun 10 Python
python通过ssh-powershell监控windows的方法
Jun 02 #Python
Python lxml模块安装教程
Jun 02 #Python
Python脚本文件打包成可执行文件的方法
Jun 02 #Python
python统计cpu利用率的方法
Jun 02 #Python
Python2.x中文乱码问题解决方法
Jun 02 #Python
python实现的守护进程(Daemon)用法实例
Jun 02 #Python
Python中使用ElementTree解析XML示例
Jun 02 #Python
You might like
BBS(php &amp; mysql)完整版(二)
2006/10/09 PHP
Destoon旺旺无法正常显示,点击提示“会员名不存在”的解决办法
2014/06/21 PHP
浅谈PHP正则表达式中修饰符/i, /is, /s, /isU
2014/10/21 PHP
PHP引用的调用方法分析
2016/04/25 PHP
一个可以增加和删除行的table并可编辑表格中内容
2014/06/16 Javascript
Bootstrap每天必学之简单入门
2015/11/19 Javascript
第一章之初识Bootstrap
2016/04/25 Javascript
javascript实现随机生成DIV背景色
2016/06/20 Javascript
Vue.js 2.0窥探之Virtual DOM到底是什么?
2017/02/10 Javascript
javascript数组去重常用方法实例分析
2017/04/11 Javascript
Angular将填入表单的数据渲染到表格的方法
2017/09/22 Javascript
jquery获取transform里的值实现方法
2017/12/12 jQuery
vue判断input输入内容全是空格的方法
2018/03/02 Javascript
JS中Promise函数then的奥秘探究
2018/07/30 Javascript
js尾调用优化的实现
2019/05/23 Javascript
layui原生表单验证的实例
2019/09/09 Javascript
Python 变量类型及命名规则介绍
2013/06/08 Python
详解Python验证码识别
2016/01/25 Python
Python打造出适合自己的定制化Eclipse IDE
2016/03/02 Python
Python生成数字图片代码分享
2017/10/31 Python
python+selenium实现京东自动登录及秒杀功能
2017/11/18 Python
Flask框架通过Flask_login实现用户登录功能示例
2018/07/17 Python
如何在Django中添加没有微秒的 DateTimeField 属性详解
2019/01/30 Python
Python startswith()和endswith() 方法原理解析
2020/04/28 Python
Django Model层F,Q对象和聚合函数原理解析
2020/11/12 Python
用HTML5 Canvas API中的clearRect()方法实现橡皮擦功能
2016/03/15 HTML / CSS
德国50岁以上交友网站:Lebensfreunde
2020/03/18 全球购物
教你怎样写好自我评价
2013/10/05 职场文书
初三政治教学反思
2014/01/30 职场文书
石油工程专业毕业生求职信
2014/04/13 职场文书
村居抓节水倡议书
2014/05/19 职场文书
朋友聚会祝酒词
2015/08/10 职场文书
护理自荐信
2019/05/14 职场文书
2019安全宣传标语大全
2019/08/14 职场文书
PHP判断是否是json字符串
2021/04/01 PHP
Python内置的数据类型及使用方法
2022/04/13 Python