Perl与系统管理

Perl语言的系统运维 Perl是一种功能强大、灵活且易于使用的高级程序设计语言。最初,Perl被设计用来进行文本处理,但随着时间的推移,它被广泛应用于系统管理、网络编程、Web开发以及生物信息学等多个领域。强大的文本处理能力:Perl内置了丰富的正则表达式支持,使得字符串的搜索和替换变得十分便捷。跨平台性:Perl可以在各种操作系统上运行,包括Linux、Windows和macOS等。丰富的模块库。 阅读详情

Perl之所以能够一直在脚本程序中占有一席之地,有一些部份其实也是因为在系统管理中,Perl还能发挥着不错的效用,而且在使用上也是非常方便。它能够像shell script一样,拿了就直接用,而不需要定义一堆变量,对象,对象的方法之后才开始写程序码。你可以找到相关的模块,然后非常迅速的完成你想达到的目的。所以它保留了shell script的方便性,却又比shell script拥有更多的资源。当然优点也在某些程度上被当为缺点,例如有些人认为Perl程序码非常的不够严谨,因为相对于Java或Python,它显然太过自由了。
其实Perl对于Linux/*BSD的方便性几乎是不言可喻,很多时候在这些系统中都会预设安装了Perl,因为Perl能够相当程度的处理系统中的杂事。但是不只如此,如果你是一个系统管理员,Perl能帮你作的事情也许比你想像中的还要多。尤其当你需要对很多系统的资料进行搜寻,比对的时候,Perl就更能显示它的重要性。何况很多时候,我们可以透过日志档(log)的分析来进行系统的监控跟效率的评比,而这也正是Perl的其中一项专长。这也就对于很多系统管理的统计部份(例如MRTG跟awstats)是藉由perl来达成能做出很好的解释了。
这一章的大纲是根据Autrijus Tang在对一群准Linux系统管理员上课前,我们一起讨论出来的结果,而内容则有许多是直接使用他上课中使用的范例。这些范例在原作中以开放文本的方式释出,各位可以直接使用在测试或其他正式的产品中。

17.1 Perl在系统管理上的优势
其实就像我们前面所提的,Perl在系统管理上有着非常重要的应用跟地位,对于许多Unix-like之类的操作系统管理来说,Perl经常是他们的好帮手。可是Perl到底有甚么特别的优势呢?除了我们刚刚提到的文字比对,处理的优势外,Perl其实还有不少能够吸引人的地方。其中最特殊几点大概包括:

1. Perl的黏性特强:Perl被称为是一种黏胶程序语言,他能够用最省力的方式把各种东西绑在一起。作为一个系统管理员总是会大量接触各式各样的工具,因此需要整合这些工具的机会就非常的大,所以perl的优势在这个时候就能够容易的显现出来。
2. Perl资源丰富:我们之前多次提到的CPAN就是最丰富的数据库,不单单是网路程序,数据库处理,其实就像系统管理相关的部份,也有为数不少的模块。这些模块不但是许多系统管理员实际用来管理的工具,当然也是他们的经验。所以你看这些模块,不单单是找寻可供应用的工具,也可以藉此挖掘这些人管理系统的方式。
3. Perl的作业环境:除了Unix-like的各种操作系统能够轻易的安装,执行Perl之外,微软的Windows或是OS/2,以及苹果公司的Mac OS也都可以让Perl正常的运作。因此很多时候,当系统管理者同时必须管理一种以上的作业平台时,也能够轻易的使用相同的工具。
4. Perl几乎是一种标准:这里所谓的标准,其实是因为目前已经很多的系统管理工具都是使用Perl所开发出来的,所以如果系统管理人员如果可以拥有Perl的能力,那么自己维护或修改这些系统的可能性就可以大大增加。

17.2 Perl的单行执行模式
很多系统管理员使用Perl当然是因为Perl的顺手跟方便,就像我们说的,你总不会希望找一个文件,或置换文件的某些字串前还要先定义一大堆变量,或是先弄一个对象,然后拿来继承,再利用被继承的对象写出置换字串的对象方法。然后又没有好的正则表达式,然后你可能得用substr一个一个去找出来。最惨的可能是你写完这样的程序已经是下班时间,所以你还得加班把需要的结果搞定。而且你知道,程序写出来不一定可以那么顺利,尤其你写了那么长的程序,有bugs也在所难免,然后......。于是,下场应该是可以预料的。
虽然很多人批评Perl非常不严谨,可是换个角度看,应该是说Perl允许你「随手」写出可以解决手边工作的工具。而且Perl的「随手」还不是普通的随手。因为Perl提供单行执行模式,所以你可能可以看到这样的一行程序:


perl -MEncode -pi -e '$_ = encode_utf8(decode(big5 => $_))' *

执行完这一行之后,你该目录下的Big5文件就会全部都变成UTF8了。这实在非常神奇,不是吗?其实不只这样,你还可以利用一行的程序把文件中的某些字串一次换掉。就像这样:


perl -pi.bak -e "s,foo,bar," *

这样一来,所有文件中的foo就全部被换成bar了。希望你没有继续想像如果你手动替换或是正在用其他结构严谨的程序语言在进行中。当然,如果你现在还在这里,我们就利用那些坚持一定要有足够完整的程序架构才能执行的家伙还在奋斗的时间,来看看怎么执行单行的Perl吧。
首先,最基本的就是"-e"这个参数了,你可以使用perl -e来执行一行程序。不过请注意,我说的是一行程序,而不是一个叙述句,所以你当然可以这么写:


perl -e "$foo = 2; print $foo"

接下来,虽然只是一行的Perl程序,可是你还是可以使用Perl的其他各式各样模块,如果没有办法使用模块,那单行的执行模式大概也没有人愿意使用了吧!所以我们使用了"-M"的选项来指定所要使用的模块,就像前面的第一个例子中,我们用了"-MEncode"来指定使用Encode这个模块。
接下来,我们要让这一行程序能对所有我们指定的文件工作,所以我们使用了"-p"这个选项这个选项允许使用者以循环的方式来执行这一行程序,在这里也就让我们可以使用*这个万用字符来指定所有的文件。接下来,我们看到另一个选项是"-i",这是让perl会自动帮你进行备份,免得你对文件进行操作之后,结果非常不满意,却还得手动改回来。所以当我们指定了"-i.bak"就是让所有被修改的文件在修改前就先备份一个副档名为.bak的文件。不过这是小写i,如果你用了大写的I,那意义可就大不相同了,"-I"让你可以指定@INC的内容。

17.3 管理文件

系统管理一开始大概都要面对一大堆的文件吧,而基本的文件管理其实还没有太过复杂,只要你的shell够熟,几乎也可以应付很多状况。例如你可以轻松的利用find找到你要的文件,甚至让他们排序,就像这样:


find /home/hcchien/svn/ *.txt -print | sort 如果你用Find::File::Rule来写,可能会像这样: #!/usr/bin/perl -w use File::Find::Rule; my $rule = File::Find::Rule->new; my @files = $rule->file->name( '*.txt' )->in('/home/hcchien/'); print "$_$/" for @files;

Perl的写法不但比较长,比较复杂,而且速度比起你在shell底下真是慢了好几倍。暂时看起来,Perl在这样简单的状况下实在不特别好用。可是别忘了,像这样简单的状况,每个人都习惯随手就用shell解决,可是如果情况稍微复杂一点呢?比如我想找出文件状态是可执行的.txt文件,那么你应该怎么做呢?接下来,我想把这些文件的可执行模式取消,然后也许再修改某些内容......。如果只是单一内容,shell确实非常轻巧,快速,可是一但我们要把一堆操作集合在一起时,你就会发现perl有甚么过人之处了。


#!/usr/bin/perl -w use File::Find::Rule; my $rule = File::Find::Rule->new; $rule->file; $rule->executable; my @files = $rule->name( '*.txt' )->in('/home/hcchien/'); for my $file (@files) { open READ, $file; s/foo/bar/g while (<READ>); }

当然,你还可以对这些文件做其他的操作,例如每个文件都插入一列新的资料等等。这时候,有另外一个模块就显得非常有用了,这么模块就是IO::All。还记得我们之前怎么读入一个文件的内容吧?IO::All现在可以让你非常简单的控制文件,我们来比较看看:


用传统的作法,我们可以这么写: open FILE, "<foo.txt"; $buf.=$_ while (<FILE>); 倒也相当简洁,不过现在使用IO::All,就只要这么做: my $buf < io('foo.txt');

不过我们并不打算在这里深切的介绍IO::All这个模块,因为我们还有其他更重要的事情要做。

17.4 邮件管理

接下来让我们来看看作为伺服器的一个重要工作,也就是关于Mail的管理。也因为对于邮件的管理需求其实非常的大,所以其实相关的管理工具也不在少数。例如可以过滤广告信件,发送大量信件或是寄发一般的通知信件等等。不过由于某些工作的特殊性质,使得Perl成为这些工作中非常能够胜任重要工具,这些工作中当然有不少是字串内容的分析,而最具代表性的也就是广告信的过滤了。

17.4.1 Mail::Audit + Mail::SpamAssassin

这是一个非常具有杀手级实力的一个Perl模块,如果你已经是一个现任的网路管理人员,整天听到你所管理的邮件伺服器中不断传来广告邮件,而且你还不知道这个模块,那么应该先去CPAN上搜寻Mail::SpamAssassin这个模块。然后你还可以搭配Mail::Audit这个模块。这里的例子是许多人使用Mail::Audit跟Mail::SpamAssassin时经常会作为过滤信件第一关的检查工具:


use Mail::Audit; use Mail::SpamAssassin; my $m = Mail::Audit->new( emergency => "~/emergency_mbox", nomime => 1, ); my $sa = Mail::SpamAssassin->new; $m->pipe("listgate cle") if $m->from =~ /svk-devel/; # 送到pipe $m->accept("~/perl") if $m->from =~ /perl/; # 接进特定信箱 $m->reject("no rbl") if $m->rblcheck; # 拒绝黑名单 $m->ignore if $m->subject =~ /sex/i; # 忽略信件 my $status = $sa->check($m); # 检查垃圾信 if ($status->is_spam) { $status->rewrite_mail; # 加上档头 $m->accept("~/Mail/spam"); # 收进垃圾桶 } $m->noexit(1); $m->accept("~/Mail/%Y%m"); $m->noexit(0);# 按月汇整 $m->accept; # 其余接收

其实如果利用Mail::Audit,还可以直接套用Mail::Audit::MAPS。因为这样就可以直接把一些已经被列为黑名单的寄件者先排除在外了,而且使用上也没有甚么太大的差别。其实你只需要多做一个判断:


if ($mail->rblcheck) { ...... }

另外,Mail::Audit还有一个常用的外掛程序则是Mail::Audit::KillDups。他可以帮你删除一些ID重复的信件,其实这也是可能的广告信来源之一,所以你可以又事先过滤掉一些垃圾邮件。其实不只这些,Mail::Audit的外掛程序种类之多,实在让人觉得有趣,我自己另一个常用的是Mail::Audi::PGP,不过这就未必适合所有人了。
至于Mail::SpamAssassin,除了搭配Mail::Audit之外,其实也有命令列程序。透过命令列程序,你可以设定自己的黑名单(blacklist)跟白名单(whitelist),也可以透过手动训练的方式,来增进SpamAssassin的准确率。

17.4.2 Mail::Sendmail 与 Mail::Bulkmail

另外,perl也可以用非常方便的方式来传送mail。虽然你在系统管理时,如果需要寄发mail,可以方便的使用sendmail来传送。可是其实有些时候你会在系统中定时执行一些程序,或许是进行系统的意外检查,或许是做定时的工作。那么你可能会希望这些工作如果发生意外,你可以很快的收到电子邮件通知。这时候Mail::Sendmail就变得很有用了。


use Mail::Sendmail; %mail = ( To => 'yourmail@hostname.com', From => 'mail@server.com', Message => "救命啊!Apache不动了!!" ); sendmail(%mail) or die $Mail::Sendmail::error;

各位大概都听过「自相矛盾」的成语故事吧?而且千万别以为那是书上拿来骗小孩的故事,因为真实的就发生在perl的模块中。我们之前介绍了目前几乎被公认最好阻挡广告信的模块:SpamAssassin,可是现在我们也要介绍另一个被认为发广告信的强力模块,也就是Mail::Bulkmail。


use Mail::Bulkmail; my $bulk = Mail::Bulkmail->new( LIST => "~/listfile",   # 地址清单 From => 'admin@bulkmail.com', # 寄件人 Subject => "System Information", # 标题 Message => '~/announcement.txt' # 内文档名 message_from_file => 1 # 从文件读取内文 ); $bulk->bulkmail() or die Mail::Bulkmail->error;

在这里,你只需要把要一次传送的一大堆邮件地址逐行放进一个纯文本文件。Mail::Bulkmail就会帮你读出这些地址,而且发送邮件。至于内文,你虽然可以直接写在程序中,可是更有弹性的方式也是可以利用文字档来读入邮件内容。这样一来,如果你的邮件是每周定时发送,那么你只需要修改传送名单跟邮件内容的文件就可以轻松的让程序替你完成其他工作了。

17.4.3 POP3Client 及 IMAPClient

有些时候,你可能有一些帐号是专门用来处理一些特定的工作,那么其实这些送到该帐号的信件未必需要由一个特定的人去收,而可以利用程序去进行处理。这个时候,你可以使用Mail::POP3Client这个模块来读取这些邮件。我们先用一个简单的例子来看看这个模块的用法:


use Mail::POP3Client; my $pop = Mail::POP3Client->new( USER => "me", PASSWORD => "mypassword", HOST => "pop3.example.com", ); foreach ( 1 .. $pop->Count-1 ) { $pop->Head( $_ ) =~ /^From:/s+somebody/@example.com/ or next; open my $fh, '>', "mail-$_.txt" or die $!; $pop->RetrieveToFile($fh, $_); }

这个程序可以让某个人寄来的信都被备份到一个特定的文件中,其实主要的就是透过邮件档头中的寄件者进行比对。所以如果你可以针对主题进行比对,就可以对邮件进行分类。当然,如果你想出其他更好用的邮件过滤演算法,也许可以从这里开始进行实做(虽然我们并不建议你这么做)。其实一但可以直接取出邮件中的每一封邮件,我们可以做的应用就非常的广泛了。而有了POP3Client,好像也少不了IMAPClient。我们还是先来看另一个例子吧:


use Mail::IMAPClient; my $imap = Mail::IMAPClient->new; $imap = Mail::IMAPClient->new(    Server => $host, User => $id, Password=> $pass, ) or die "无法连上主机:$host as $id: $@";

使用IMAPClient,也因为邮件伺服器种类的特性差异,让它提供更多的操作方式给使用者。最基本的比如IMAPClient的Connected跟Unconnected,另外可以透过Range来选定某一个特定范围的邮件。例如:


$imap->Range($imap->messages);

其中$imap->messages会取得目前所在文件夹的所有邮件,然后透过$imap->Range()来把这些邮件设定成要操作的邮件范围。不过你也可以在$imap->Range()中使用逗点分隔来指定某几封特定的信件。另外,如果你考虑搬移信件,你可以使用move来进行,其实非常方便,就像这样:


my $newUid = $imap->move($newFolder, $oldUid)    or die "Could not move: $@/n"; $imap->expunge;

另外,还有一些常用的方法例如delete_messages和restore_messages就分别是用来删除邮件跟回覆被删除的邮件。或是你可以用search来搜寻邮件。其实IMAPClient非常的强大,确实需要根据自己的需求去研究相关的文件才能确实掌握。

17.5 日志档

作为一个系统管理,能确实掌握每日的记录档确实是非常重要的工作。不过如果你进入/etc/log文件夹,就会发现里面的文件其实是相当多的。也就是说,如果你身为一个系统管理员,每天要注意这些文件中有没有异常,如果你还在使用传统的工人智慧,那么每天进行这样的工作就要浪费许多时间。因此要希望能够在这部份节省更多的时间来从事其他的管理工作,我们可以使用一些工作来简化这些日常的程序,Parse::Syslog就是其中之一。
我们先来看看一个简单的例子,来了解Parse::Syslog怎么帮我们处理这些日志文件。


use Parse::Syslog; my $syslog = Parse::Syslog->new('/var/log/syslog'); while (my $entry = $syslog->next) { $entry->{program} =~ /sudo$/ or next; print localtime($entry->{timestamp})."/n", "$entry->{text}/n/n"; }

其实程序并不困难,首先我们设定要处理的文件,在这里我们针对"/var/log/syslog"这个文件来检查。接着Parse::Syslog传回一个对象,也就是$syslog。接下来我们使用next这个对象操作方法逐行处理这个文件,在文件结束之前,$syslog->next都会传回真值,因此让我们可以一行一行来进行比对的工作。我们试图找出日志档中关于有使用者使用sudo这个指令,所以我们使用了正则表达式。
接下来,Parse::Syslog可以帮你取得事件发生的时间,所以当我们比对成功之后,就可以印出使用者使用sudo这个指令的时间。
所以如果我们一次把所有要监视的文件内容利用Parse::Syslog设定好,那么其实以后的日子就会轻松愉快许多了。当然,如果你撷取出这魔一堆文件,那么要把这些让人需要特别注意的记录进行处理,才能方便管理者阅读或检查,这时候可以使用另一个模块来进行。
Log::Dispatch是不错的选择。你只要新建立一个相关的对象,并且指定要写入的档名,那么可以依照记录的等级来将相关的讯息写入文件中。


use Log::Dispatch; my $log = Log::Dispatch->new; # 建立记录对象 # 新增记录档 $log->add( Log::Dispatch::File->new( name => 'file', # 对象名称 min_level => 'debug', # 记录门槛 filename => '/var/log/test.log', # 记录档名 ) ); 接下来,我们把想要写入的讯息像这样的加入文件中: $log->log( level => 'alert', message => 'Strange data in incoming request' );

这里有一个有趣的部份,也就是记录门槛。他可以让使用者依照不同的等级来分门别类,而门槛的类别分别为:


除错 (debug) 消息 (info) 提示 (notice) 警告 (warning) 错误 (error) 关键 (critical) 警铃 (alert) 紧急事件 (emergency)

既然有了这些分别,你就可以进行更多的动作来确保系统正常的运作。例如你可以在系统遇到异常现象时发出信件给自己,就像这样:


$log->add( Log::Dispatch::Email::MailSend->new( name => 'email', # 对象名称 min_level => 'emergency', # 记录门槛 to => [ 'admin@example.com' ], # 收件地址 subject => 'HELP!!!', # 邮件标题 ) );

于是如果你的日志得到了一些紧急事件的讯息时,就会自动发出电子邮件给你。如此一来你可以在第一时间就知道系统异常,并且进行检修。当然,如果你是超级负责的系统管理员,你也许希望在你没有网路的时候也能得到相关的紧急警告,这时候手机简讯也许是另一种通知的好方法。


use Net::SMS; my $df = `df -h`;   # 取得硬盘配置资讯 $df =~ /-/d/ or exit;    # 若没有数字是负的就直接离开 my $sms = Net::SMS->new; # 简讯对象 $sms->accountId("123-456-789-12345"); # 帐号 $sms->accountPassword("mypassword"); # 密码 $sms->sourceAddr("0928-000-000"); # 来源 $sms->destAddr("0928-999-999"); # 目的 $sms->msgData("HARD DISK FULL:/n$df"); # 讯息 $sms->submit; # 送出简讯 $sms->success or die $sms->errorDesc; # 侦测错误

我们使用Net::SMS可以直接发送简讯,在这个例子中,我们使用shell指令去检查磁盘空间。并且当发现磁盘空间不足时就发出手机简讯来警告系统管理人员。虽然你写了这些程序之后,未必就可以获得老闆的赏识而加薪,不过我想让老闆少点机会找你麻烦应该还算是一项大利多吧!

17.6 报表

身为系统管理人员,尤其当你是在企业内部进行系统管理时,最容易遭到忽略。因为当大家系统非常顺畅时,几乎没人会归功于系统管理员的认真。于是要怎么拿出实际的内容来说服其他的人,这也算是系统管理人员的重大业务之一了吧!很多人使用MRTG(注一)来监测网路流量,使用awstats(注二)来看网站的各式数据。
可惜的是大多数的人对这些报表并不太有兴趣,除非你管理的是一个(或一堆)网站,而且公司的业务也就是经营这些网站。既然如此,那么一个系统管理员有些时候其实还是要呈现出自己优良的管理绩效,在没有现成的套装工具下,要怎么样快速的建立出漂亮的报表其实也是不小的学问。
如果你需要的是文字的报表,那么我们前一章使用的Template就非常适合,你可以利用Template::Toolkit画一个HTML的报表。


#!/usr/bin/perl -w use strict; use Template; use IO::All; use Mail::MboxParser; my $dir = io('/var/mail');   # 准备逐个检查信箱 my %all; while (my $io = $dir->next) {   # 一个一个看信箱的信件数目 if ($io->is_file) {   # 只检查文件 eval {   # 避免因为某些原因中断 my $mb = Mail::MboxParser->new("$io", newline => '#DELIMITER'); %all{$io} = $mb->nmsgs;   # 把结果放入杂凑 } } } my $config = {    INCLUDE_PATH => '/search/path',    POST_CHOMP => 1,    }; my $template = Template->new($config);   # 建立新的模板对象 my $vars = { messages => /%all }; my $input = 'report.html'; my $output; $template->process($input, $vars, $output)  # 处理模板内容 || die $template->error(); print $output;

这时候,你可以取得一个含有所有信箱邮件个数的一个杂凑变量(我们使用了Mail::MboxParser)。如此一来,你只要弄一个漂亮的模板,就可以让系统动态把资料填入,随时可以监控目前大家信箱内的邮件数目了。不过这样其实还没结束,因为很多老闆或主管对于文字的接受度总是比较低,所以如果你有漂亮的报表,那么给他们的印象应该也会随之提高。这时候,你也许可以认真考虑使用GD::Graph这个模块。这个模块可以让你轻松的画出漂亮的统计图表,你可以根据资料的属性以及需求的差异,画出例如圆饼图,曲线图,柱状图等等,如果你还想更绚丽,GD::Graph还可以画出立体的3D图形。
我们用另一个例子来看看怎么使用GD::Graph吧:


use GD::Graph::bars3d; my $graph = GD::Graph::bars3d->new(800, 600); # 新增柱状图 my @files = </var/log/maillog.*.bz2>; my $image = $graph->plot([   # 订出横座标,纵座标内容 [map /(/d+)/./g, @files], [map -s, @files], ]) or die $graph->error; open my $fh, '>', '3.png' or die $!; print $fh $image->png; # 储存影像

我们取得了每次的电子邮件日志档的,然后根据这些文件的大小进行统计。这时候,我们只需要订出横座标跟纵座标的内容,交给GD去画就好了,你当然也可以定时的要求程序帮你画出某些统计图表。很有用吧!你可以定时交出漂亮的工作报表,而且还是由电脑自动产生。

利用Perl来协助系统管理其实还算是非常方便的,何况已经有许多的系统管理员早就在做这些工作,也因此我们有很多方便的工具可以使用。这完全让我们省下许多时间,尤其当更多的系统管理员每天都花许多时间在这些繁琐而且又没有变化的工作上。

习题:
1. 找出maillog中被reject(退信)的资料,也就是找到日志档中以reject标明的内容。例如:

Jun 3 00:00:46 dns2 postfix/smtpd[71431]: D988D6A: reject: RCPT from smtp2.wanadoo.fr[193.252.22.29]: 450 < fnatterdobkl@hcchien.org>: User unknown in local recipient table; from=<> to=<fnatterdobkl@hcchien.org> proto=ESMTP helo=<mwinf0203.wanadoo.fr>
2. 承上题,统计当月每天的退信数字,并且画成长条图。
有关回溯的相关 排列组合遍历 目录 无相同元素 全排列            排列A(n,m)      组合C(n,m) 有相同元素 全排列 排列A(n,m) 组合C(n,m)   &lt;font size="5"&gt;最近刚刚学习了递归,回溯算法来进行深度搜索。对一些题目有一些感触,顺便写下变体的解法。&lt;/font&gt; 无相同元素 全排列   排列A(n,m)      void... 阅读详情

相关推荐

c++算法:不含重复元素的全排列和含重复元素的全排列----递归思想

一、不含重复元素的全排列 算法思路: (1)n个元素的全排列=(n-1个元素的全排列)+(另一个元素作为前缀); (2)出口:如果只有一个元素的全排列,则说明已经排完,则输出数组; (3)不断将每个元素放作第一个元素,然后将这个元素作为前缀,并将其余元素继续全排列,等到出口,出口出去后还需要还原数组 void swap(vector<int>&a, int i, int j) ...

ZHAO 2235

想做一个LINUX/UNIX下的数据库系统管理员,请问学PERL还是PYTHON更合适呢?

http://www.itpub.net/thread-1243794-1-1.html各种脚本细微区别非常大,而主管们要的是你快速开发和部署,用啥类型脚本他们根本没兴趣混着搞到头来一个都不精。注:...

cuishi2071的博客 216

排列组合问题~有重复元素的排列问题(perm)——【S神】苏嘉亿

Description 设 R=R=R={r1,r2,…,rnr_1,r_2,…,r_nr1​,r2​,…,rn​} 是要进行排列的 nnn 个元素。其中元素 r1,r2,…,rnr_1,r_2,…,r_nr1​,r2​,…,rn​ 是小写字母,且可能相同。试设计一个算法, 列出 RRR 的所有不同排列。给定 nnn 以及待排列的 nnn 个元素。计算出这 nnn 个元素的所有不同排列。 Inpu...

苏嘉亿的博客 2447

Perl与系统管理-1

Perl与系统管理 安全的临时文件 use File::Temp qw(tempfile); my ($fh, $filename)=tempfile(); print $fh "ba...la...ba...la...\n"; UNC(Universal Naming Convention) UNC用于在网络环境中访问文件和目录。UNC文件名中盘符和冒号变为: \\server\sha...

beeworkshop的博客 508

对一组数穷尽所有排列的算法

原题:将A, B, C, D, E, F 这 6 个变量排成如下三角形,这 6 个变量分别取[1, 6] 上的整数,且均不相同.求使三角形三条边上的变量之和相等的全部解. A B F C D E 分析:在程序中引入变量 a, b, c, d, e, f, 并让它们分别顺序取 1 至 6 的整数, 在它们互不相同的条件下,测试由它们排成的三角形边上的变量之和是否相等,如相等即为一种要求的排雷,把它们

愿君出走半生,归来时仍是少年 2645

使用Perl实现系统管理自动化(第二版) 中文版

使用Perl实现系统管理自动化(第二版) 中文版

对一组数排列,包含相同元素

题目:{3,2,2,6,7,8}排序输出,7不在第二位,68不在一起。     分析思考:   1.编写输出全部元素的排序组合,6位数共有6!个排序方式,即720个   2.由于有两个2,即重复元素,则最终将会有重复的排序方式,输出的个数720/2! = 360个,再去掉与7和68的限制相关的组合     全部元素排序 第一个位置有6种情况,取一个数放在第一位上,则第二...

永源blog 271

Labview程序框架介绍

当掌握LabVIEW基础知识并达到,理解单个小型模块程序会相对轻松。而若想进一步探索大型程序,就必然需要了解程序框架相关内容。LabVIEW常用的程序架构包括等。在多年工作中,我接触过的众多高级工程师所开发的大型程序,基本都基于这些架构搭建。接下来,将为大家详细介绍这些框架。

Misterlhw的博客 4620

全排列问题(不含有相同元素与含有相同元素的全排列问题)

1.给定一个数组,数组中元素均不相同,写出数组元素的全排列组合 比如: [1,2,3] Output: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ] 由于数组中不含相同元素,所有不用考虑重复问题,现在我们来解析 [1,2,3]的全排列是如何得到的: 1,2,3的全排列,我们先看后两个数[2,3]的...

Jared的博客 4308

MATLAB联合Fluent优化仿真

matlab与fluent交互

keleke_的博客 4730

AVM环视算法实战:从3D碗型投影到多场景模式切换的实现与优化

本文深入探讨了AVM环视算法在3D碗型投影和多场景模式切换中的实现与优化。通过分析3D碗型投影的核心原理和动态视角调节技术,展示了如何实现从超广角模式到转向模式的无缝切换。文章还分享了性能优化实战经验,包括实时性提升和图像拼接质量优化,为开发者提供了宝贵的AVM系统开发指南。

weixin_42573113的博客 171

7个相同小球4个不同盒子_排列组合问题(6)——元素相同隔板策略

隔板法,指在解决若干相同元素分组,要求每组至少一个元素时,采用将比所需分组数目少1的板插入元素之间形成分组的解题策略。(1)所有元素相同;(2)每组至少含有一个元素;(3)隔板包含分组+分配两步骤;(4)隔板法不是解决元素相同问题的唯一策略。【例1】有5个运动员名额,分给A、B、C共3个班,每班至少一个,有多少种分配方案?解法一(枚举法):因为5个名额没有差别,是相同元素。那么本问题转...

weixin_29985807的博客 3740

NB-IoT开发避坑指南:STM32下AT指令状态机的设计与优化

本文深入探讨了在STM32平台上为NB-IoT模组开发时,如何用状态机(FSM)设计替代传统的阻塞式AT指令处理方法。通过构建非阻塞、事件驱动的AT指令引擎,有效解决了系统卡顿、响应迟缓等问题,并详细介绍了状态机的设计、实现与高级优化技巧,助力开发者打造健壮可靠的物联网设备通信核心。

q5r6s7的博客 758

全排列问题_不含相同元素和含有相同元素_Leetcode46_Leetcode47_回溯解法+Java代码

全排列问题(不含相同元素和含有相同元素) Leetcode46 Leetcode47 回溯解法+Java代码

新新的仔仔的Blog 544

提升AI智能体回复质量:扣子平台提示词优化技巧与案例解析

本文深入探讨了在扣子平台上优化AI智能体提示词的关键技巧与实战案例。通过分析提示词设计的核心原则、业务场景适配策略以及平台高级功能应用,帮助开发者显著提升AI Agent的回复质量。文章特别强调了结构化提示词设计和A/B测试评估的重要性,并提供了电商客服场景的完整优化案例。

weixin_30897233的博客 538

逆向工程实战:解密AppleAccount的X-MMe-Nas-Qualify签名生成机制

本文通过逆向工程实战,详细解析了AppleAccount服务中X-MMe-Nas-Qualify签名的生成机制。作者利用Frida进行动态追踪定位签名源头,结合IDA Pro进行静态分析,并借助LLDB动态调试还原核心算法。文章最终分享了如何独立于苹果官方库,通过Python代码复现签名算法,为自动化测试和深度交互苹果服务的开发者提供了关键技术路径。

weixin_29323049的博客 707

一组数所有排列

public static void main(String[] args) { //准备数据 按位置设置 Map data=new HashMap(); data.put(1, 0); data.put(2,2); data.put(3, 3); data.put(4, 4); data.put(5,5); //用set主要是为了去除重复数

smalljiawa的专栏 464

Python爬虫实战:逆向解析腾讯视频API,高效获取结构化视频信息

首先,我们定义期望获取的数据结构,这有助于数据验证和代码清晰度。python"""腾讯视频信息数据模型"""title: str = Field(..., description="视频标题")vid: str = Field(..., description="视频唯一ID")play_count: Optional[int] = Field(None, description="播放量")

2201_76125261的博客 2379

有重复元素排列问题

有重复元素的排列问题 【问题描述】 设R={ r1, r2 , …, rn}是要进行排列的n个元素。其中元素r1, r2 , …, rn可能相同。试设计一个算法,列出R的所有不同排列。 【编程任务】 给定n 以及待排列的n 个元素。计算出这n 个元素的所有不同排列。 【输入格式】 文件的第1 行是元素个数n,1≤n≤500。接下来的1 行是待排列的

myazi 1万+

HTML蓝色动态爱心(完整代码)

HTML语言实现蓝色动态爱心的完整代码。

AIGC 8万+

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

python编程题——如何求一组数的全排列

此时,我们该把2加入,显然可以有两种方式,一种是插入到1之前,另一种是插入到1之后,也就是插空,得到。所以在下面的求解方法中,忽略上面的方法,以一种全新的方法来实现这个求解程序,一看便懂。如果输入内容就是列表,则不会有内容形式的变化。当然,为了更好理解python的程序机制,下面给出一种上述程序的另一种代码,只有。,也有三个空,把3分别插入,也得到三种。全排列:[1,2,3],[1,3,2],[2,1,3],有三个空,把3分别插入,也就得到三种,对于。请问问题到底出在哪?,同理,下面插入3,显然,对于。

m0_57569438的博客 2389

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

全排列、亲7数

全排序(递归实现) 从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列。 假设我们要对1234进行全排列 首先保证1不变,对234进行全排列 同样的,对234进行全排列可以保证2不变, 对34进行全排列,然后保证3不变, 对4进行全排列,因为4只有一个数,所以全排列只有一种 代码: import java.util.Arrays; public class Two { public static void

sunjiac的博客 1039

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

全排列算法以及求下一组全排列

1.全排列的算法,考虑相同的数字情况,在递归时需要判断,递归的区间有没有重复的数字。bool isNeedSwap(int *a,int l,int r){ //查找在[l,r)区间中,有没有和a[r]相同的数字 for(int i=l;i<r;i++){ if(a[i]==a[r]){ return false; } }

a342500329a的专栏 1081

有重复元素的排列问题

1.问题描述 设集合R={r1,r2,...,rn}是要进行排列的n个元素,其中r1,r2,...,rn可能相同。 试着设计一个算法,列出R的所有不同排列。 即,给定n以及待排的n个可能重复的元素。计算输出n个元素的所有不同排列。 2.算法设计 给定n及待排列的n个元素,计算出这n个元素的所有不同排列。 3.数据输入 第1行是元素个数n,1&l...

C++ 6464

给定一个字符串,要求给出重新排列的所有不相同的排列数

给定一个字符串,要求给出重新排列的所有不相同的排列数 题目描述 给定一个只包含大写英文字母的字符串S,要求你给出对S重新排列的所有不相同的排列数。 如:S为ABA,则不同的排列有ABA、AAB、BAA三种。 解题思路 先把每个字符当成唯一出现过一次,计算所有排列数;再统计重复出现的字母,除去每个字母的排列次数 例如 对于ABA,当成三个不同字符则排列数为:S总=A33S_总=A_3^3S总​=A3...

lxycar的博客 1万+
上一篇: 密钥和证书
下一篇: 用Perl实作网站程序
bz201
博客等级 码龄22年 44粉丝 131原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值