Aug 29 2007

ip tunnel 做透明sock代理

Category: 技术ssmax @ 11:08:30

昨天要帮客服做一个电信服务器分流,最初用iptables起一个DNAT和SNAT,直接可以做到,但是却拿不到请求方的ip地址,如果用squid可能太慢,而且是ssl连接,配置麻烦,后来准备做策略路由,用iptables做一个DNAT到openvpn,哪里知道openvpn过滤了这些包,超级郁闷弄了一天,没搞定,最后网管用ip tunnel搞定了,又学到东西了。。。

 on machine A
  498  iptunnel add tun1 mode ipip remote bbb.bbb.bbb.bbb local aaa.aaa.aaa.aaa
  499  ifconfig tun1 10.7.0.1
  501  route add 10.7.0.2 dev tun1
  504  ip route add default dev tun1 table tunnel
  505  ip rule add from 10.7.0.1 table tunnel 

on machine B

  456  iptunnel add tun1 mode ipip remote aaa.aaa.aaa.aaa local bbb.bbb.bbb.bbb
  457  ifconfig tun1 10.7.0.2
  459  route add 10.7.0.1 dev tun1
  462  iptables -t nat -A PREROUTING -d bbb.bbb.bbb.bbb -p tcp -m tcp –dport 443 -j DNAT –to-destination 10.7.0.1

嘿嘿,拿到一台网通+电信双ip的机器,只做分流浪费了,看来可以拿来做点坏事了。


Jul 31 2007

终于要碰Asterisk了。。

Category: 技术ssmax @ 22:15:37

普通客服要上ip电话系统。。。难以想象他们现在还在用程控的电话系统。。貌似老板不想交给ppyy做了,要我们自己开发。。要从头看起了,这么说这也叫做第五代呼叫中心了。。。就我们2个人,到时怎么算呢,唯有见步行步啦。。。

随便找台linux先装上用软电话玩玩吧。。。唉。。。日

如何跨入“第五代呼叫中心”

呼叫中心与人们的日常生活密切相关,人们对呼叫中心的理解也是相当宽泛的。电信运营商设立的“114”特服电话,就被认为是早期一个比较典型的呼叫中心。接着,大量声讯台、寻呼台普遍采用自动应答系统提供服务,这也被称为呼叫中心服务。现在电信运营商已建成多个呼叫中心,如10000/10001和10086等,都透过其方便快捷的服务,使呼叫中心的概念深入民心。呼叫中心已经发展成为一种产业,它不仅可以为企业创造良好的社会效益,而且还可以为企业带来巨大的经济效益。随着近年通信技术与计算机技术不断融合和发展,你会发现如今呼叫中心产业的发展已经开始跨入一个新的层次和阶段,网络技术革命的脚步已悄然走来。

呼叫中心发展历程回顾

1)第一代呼叫中心:人工热线电话系统

呼叫中心,早期是指一个由两人或更多人组成的、在一个特定地方用专用设备处理电话业务的小组。这些人就是通常所说的呼叫中心代理(人)。一个呼叫中心可以只提供信息接收服务,或者只提供信息发送服务,或者是一个混合式呼叫中心,其呼叫中心代理会负责所有这两项工作。

第一代呼叫中心的特点:硬件设备为普通电话机或小交换机(排队机),简单、造价低、功能简单、自动化程度低,一般仅用于受理用户投诉、咨询;适合小企业或业务量小、用户要求不高的企业/单位使用。目前,没有正式设立呼叫中心的企业、单位一般采用这种方式。

2)第二代呼叫中心:交互式自动语音应答系统

随着计算机技术和通信技术的发展,第一代呼叫中心由于基本靠人工操作,对话务员的要求相当高,而且劳动强度大、功能差,已明显不适应时代发展的需要。因此,功能完善的第二代呼叫中心系统随即应运而生。

第二代呼叫中心特点:广泛采用了计算机技术,如通过局域网技术实现数据库数据共享;语音自动应答技术用于减轻话务员的劳动强度,减少出错率;采用自动呼叫分配器均衡座席话务量、降低呼损,提高客户的满意度等等。但第二代呼叫中心也存在一定的缺点:它需要采用专用的硬件平台与应用软件,还需要投入大量资金用于集成和客户个性化需求,灵活性差、升级不方便、风险较大、造价也较高。 

3)第三代呼叫中心:兼有自动语音和人工服务的客服系统

与第二代呼叫中心相比,第三代呼叫中心采用CTI技术实现了语音和数据同步。它主要采用软件来代替专用的硬件平台及个性化的软件,由于采用了标准化的通用的软件平台和通用的硬件平台,使得呼叫中心成为一个纯粹的数据网络。

第三代呼叫中心的优点:采用通用软硬件平台,造价较低;随着软件价格的不断下调,可以不断增加新功能,特别是中间件的采用,使系统更加灵活,系统扩容升级方便;无论是企业内部的业务系统还是企业外部的客户管理系统,不同系统间的互通性都得到了加强;同时还支持虚拟呼叫中心功能(远程代理)。

4)第四代呼叫中心:网络多媒体客服中心

接入和呼出方式多样化:电话、VOIP电话、计算机、传真机、手机短信息、WAP、寻呼机、电子邮件等。 

多种沟通方式格式互换:可实现文本到语音、语音到文本、EMAIL到语音、EMAIL到短消息、EMAIL到传真、传真到EMAIL、语音到EMAIL等的自由转换。

语音自动识别技术:可自动识别语音,并实现文本与语音自动双向转换,即可实现人与系统的自动交流。

第五代呼叫中心的核心——免插件的网络实时互动服务

与第四代呼叫中心相比,免插件的网络实时互动服务,完全基于互联网传输成为了第五代呼叫中心的特点,将互联网技术与呼叫中心完整融合,在IM(即时通讯)工具C/S结构的基础上,与B/S结构进行嫁接,基于B/S构架,但不限于B/S构架;基本功能包含IM功能,但不限于IM功能;完全意义上实现了网络上的沟通服务.互联网呼叫中心的核心是增值服务功能,即在实现客户咨询的初级目标的基础上,实现直复营销这一高级目标。第五代呼叫中心在第四代的基础上大大增强了实时的交互功能,并利用最先进的网络技术开创了网站访客免安装任何插件,就可与企业后台CSR直接在线交流的先河。企业后台CSR也能随时看到所有登陆企业网站客户的浏览轨迹,并能主动邀请客户在线直接交流,彻底改变了呼叫中心只能被动等待客户呼如入的历史。换言之,呼叫中心不再仅仅是有效的用户交流工具,更是产品、服务的营销工具。第五代呼叫中心的设计重点主要集中在应用层面上,而不单单是硬件(如PABX)上,因此更能适应企业的要求,更有效的配合企业客户关系管理(CRM)的进程。

第五代呼叫中心的应用

1)互动(Interaction)–即根据客户偏好, 即时调整服务方式,包括语音、数据、视频和多媒体业务等,既从客户那里了解他们的需求,又主动去帮助他们“发现”和“启动”自己的需求,影响他们选择的基于分组技术综合开放的网络架构。第五代呼叫中心的企业和客户间交流突破了原有的语音沟通瓶颈,进入了丰富多彩的多媒体时代,通过各种文字,语音,图片,视频和客户的直接交流,更生动全面的向客户展示企业的形象和产品,解决客户的疑问,既提升了企业品牌,同时更促进了企业销售。使呼叫中心真正成为了全方位立体化的实时服务平台

2)协同(Coordination)–不仅包括人与人之间的协作,也包括不同应用系统之间、不同数据资源之间、不同终端设备之间、不同应用情景之间、人与机器之间、科技与传统之间等全方位的协同。

第五代呼叫中心的CSR通过统一的服务平台协同服务客户时,通过对服务记录的整体转移,可以对客户实现“我把相关客服转给您”而不是“我把您转给相关客服”处处做到以客户为中心的服务。通过第五代呼叫中心协同办公功能,CSR可以是在同一办公地点集中办公,也可以是分散式办公,甚至是在家办公,他们接受统一的远程管理,共享最新的公司资讯,进行有效的分工协作,充分利用公司的各项资源。

3)管理(Mangerment)–即以人为主导,利用计算机硬件、软件、网络通信设备以及其他办公设备,进行信息的收集、传输、加工、储存、更新和维护,以企业战略竞争、提高效益和效率为目的,支持企业高层决策、中层控制、基层运作的集成化的人机系统。

对客户的管理:第五代呼叫中心可以对所有网络数据进行监测和统计,对客户上网的轨迹跟踪记录,知道客户是什么地区,通过什么途径到达公司网站,第几次登陆,对哪个页面最感兴趣,通过分析了解客户的需求,有针对性的服务。并将服务过的客户资料及服务记录存储到客户数据库当中,当访客再次登陆时即可识别,并跟踪服务,提高客户满意度及忠诚度。

对客服的管理:所有CSR的服务记录都会保存在企业的服务器中,包括每天服务的客户总数,平均处理时间,述求应答数,客户满意度等,公司的管理人员可按级别查看服务记录,且能以各种报表形式输出。

通过第五代呼叫中心互动,协同,管理((Interaction Coordination Mangerment 简称为 “ICM” ) 的功能,可以使Web呼叫中心进入一个精准制导的市场营销时代:目标群体精确并且资源集优;巧妙的推广策略与潜移默化的渗透;市场情报的收集与研究;即时的各单元间协同办公;客户数据的收集、筛选、及时更新;即时的战略调整和创新。真正使Web呼叫中心形成包括线上、线下即时互动的全方位立体型的整体营销服务管理体系。


Jul 31 2007

VPN日记

Category: 技术ssmax @ 22:09:12

最近在公司一台服务器上面装了个socks代理绕过内网防火墙上qq,加了个ssl tunnel就实现了加密代理。。。但是还不完美,我们一栋大厦每层都不同网段,想一起用局域网联机打游戏都很困难,之前玩星际的时候建了一个battle.net,但现在玩魔兽好像要配置一下才能用,一时也找不到怎么配置,于是就想起了虚拟局域网,上网找了一下,可以用VPN或者VNN实现,找了一点资料,有空在研究

  hamachi,号称0配置,加密通讯。安装十分简单,安装后会在系统里生成一个虚拟的网络适配器(虚拟网卡),确实不需要做任何专门的网络配置,只要创建建一个新的网络,设好密码,其他的hamachi就能连入,组成一个LAN。目前支持windows和linux平台,Mac平台支持正在开发中。但是,hamachi必须首先登陆到hamachi.cc服务器,网络IP会自动设置,使用5.x.x.x,这一点可能对那些无法连入internet的用户是个限制。它看上去更像一个IM。
 SoftEther,日本的软件,通过TCP隧道+HTTPS实现,可以很好的穿过防火墙、NAT,1.0版免费使用,而且已有汉化版本,安装和设置比较简单,安装完成后同样会在系统中虚拟一个网络适配器,作为HUB端还需要安装虚拟HUB支持。它的特点是通讯加密,用虚拟HUB组成一个虚拟LAN,支持客户到HUB的连接通过http代理、sock代理和SSH,使用比较灵活。但1.0版只有windows平台支持(目前1.0版有linux版的虚拟HUB),这点是一个限制,尤其对linux用户而言。更麻烦的是2.0版更名为PacketiX,界面全日文,且不再免费。
 OpenVPN,是一个开源项目,功能较强,支持平台比较多,默认使用UDP隧道(同样也可以支持TCP),基本具备前两个软件的功能,缺点是配置相对麻烦。
 这三个软件都能有效地实现VPN功能,并且可以克服传统的PPTP、L2TP/IPsec之类的VPN难于通过防火墙和NAT或路由器的缺点,通过与路由、网桥、代理等技术结合,合理使用,可以实现特殊的网络连接。


May 08 2007

在免费空间里面搞了个cron定期备份。。。

Category: 技术ssmax @ 17:32:14

因为用的是免费空间,blog的数据经常不稳定,今天一气之下搞了个email备份,尽量简单了。。。perl的base64编码可以用encode-base64代替,万恶的服务器没有uuencode。。。

要注意一下mysqldump、gzip、perl、sendmail的路径问题

还有tempfile是否是mysql可写的

为啥要创建tempfile呢,我测试的时候免费空间限制了内存的使用和/tmp的可写,所以不能用管道来传,如果能用管道就不用写这么复杂了。。。

能用uuencode和管道的情况下,一行就能搞定。。。

最后就是看看后台能不能用cgi偷入去crontab里面玩玩了,一般都可以di。。

如果crontab不能用,就搞成一个cgi,在本机搞个计划任务定期去访问,windows的cron,嘿嘿

ps:其实用php cron和mail的功能很快可以做出来,但是我懒得去研究php了。没学过,改改还行,自己写就不要搞我了。。。。

命令行用sendmail发带附件mail的代码,同时备份数据库


#!/bin/sh
datestr=`date +%Y%m%d`;
tempfile="/ooxx/database_temp";
attachname="ooxx_$datestr.gz";
dbuser="ooxx";
dbpassword="xxoo";
dbhost="localhost";
dbdatabase="ooxx";
mail_to="ooxx@xxoo.com";
mail_from="admin@ooxx.com";

#echo "mysqldump -h$dbhost -u$dbuser -p$dbpassword --default-character-set=utf8 $dbdatabase 2>&1 > $tempfile;"
mysqldump -h$dbhost -u$dbuser -p"$dbpassword" --default-character-set=utf8 $dbdatabase 2>&1 > $tempfile;
gzip -f $tempfile;
/usr/sbin/sendmail -t -f $mail_from <<!EOF!
To: $mail_to
From: $mail_from
Date: `date -R`
Subject: $datestr blog database backup
Content-Type: multipart/mixed; boundary="=====000_Dragon434046520070_====="

 

This is a multi-part message in MIME format.

--=====000_Dragon434046520070_=====
Content-Type: text/plain; charset="gb2312"

This is a blog database backup @ $datestr

--=====000_Dragon434046520070_=====
Content-Type: application/octet-stream; name="$attachname"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="$attachname"

`perl -e 'use MIME::Base64; open(FILE, $ARGV[0]); while (read(FILE, $buf, 60*57)) {print encode_base64($buf);} close(FILE);' $tempfile.gz`

--=====000_Dragon434046520070_=====--

!EOF!

 

 


Apr 29 2007

前几日搞perl的笔记

Category: 技术ssmax @ 14:36:54

前几天搞一个空间的时候,php被禁止了system命令,只有用perl cgi来做了,研究了一下perl调用命令行,弄了一个web版模拟shell。

先贴资料:

How can I capture STDERR from an external command?

There are three basic ways of running external commands:

    system $cmd;
     $output = `$cmd`;
     open (PIPE, "cmd |");

In the first case, both STDOUT and STDERR will go the same place as the script’s versions of these, unless redirected. You can always put them where you want them and then read them back when the system returns. In the second and third cases, you are reading the STDOUT only of your command. If you would like to have merged STDOUT and STDERR, you can use shell file-descriptor redirection to dup STDERR to STDOUT:

    $output = `$cmd 2>&1`;
     open (PIPE, "cmd 2>&1 |");

Another possibility is to run STDERR into a file and read the file later, as in

    $output = `$cmd 2>&some_file`;
     open (PIPE, "cmd 2>&some_file |");

Note that you cannot simply open STDERR to be a dup of STDOUT in your perl program and avoid calling the shell to do the redirection. This doesn’t work:

    open(STDERR, ">&STDOUT");
     $alloutput = `cmd args`;
  # stderr still escapes

Here’s a way to read from both of them and know which descriptor you got each line from. The trick is to pipe only STDOUT through sed, which then marks each of its lines, and then sends that back into a merged STDOUT/STDERR stream, from which your Perl program then reads a line at a time:

    open (CMD, "(cmd args | sed 's/^/STDOUT:/') 2>&1 |");
    while () {
       if (s/^STDOUT://)  {
           print "line from stdout: ", $_;
       } else {
           print "line from stderr: ", $_;
       }
     }

Be apprised that you must use Bourne shell redirection syntax in backticks, not csh! For details on how lucky you are that perl’s system() and backtick and pipe opens all use Bourne shell, fetch the file from convex.com called /pub/csh.whynot — and you’ll be glad that perl’s shell interface is the Bourne shell.

There’s an &open3 routine out there which was merged with &open2 in perl5 production.

再贴偶的模拟shell,随便写了个。。

cmd.pl

#!/usr/bin/perl
use CGI;
my $command = CGI::param(‘command’);
my $pwd = CGI::param(‘pwd’) || ‘.’;

print (“Content-Type: text/plain;\n\n”);
print “change dir: “.`cd $pwd 2>&1`.”\n”;
print “now dir: “.`pwd`.”\n”;
print “command: “.$command.”\n\n”;
print `$command 2>&1`;

cmd.html

<html>
<body>
 <form name=”cmdform” action=”cgi-bin/cmd.pl” target=”cmdframe”>
 <div>
  work dir:
  <input type=”text” value=”.” name=”pwd” />
 </div>
 <div>
  input your command here:
  <textarea name=”command” cols=”100″ rows=”5″></textarea>
 </div>
 <Input type=”submit” value=”run”/>
 </form>
 
 <iframe name=”cmdframe” height=”100%” width=”100%”></iframe>
</body>
</html>

如果遇到 500 错误,最有可能是没有设置cmd.pl为可执行(755一般是),这个在后台log应该能看到,还有可能是遇到apache的Premature end of script headers错误,一般就是没有

print (“Content-Type: text/plain;\n\n”);

这句造成的,还有可能是dos换行符号造成,把cmd.pl里面所有\r\n换成unix的\n格式就好了。。。


Feb 14 2007

南北网络加速器汇总

Category: 技术ssmax @ 10:18:41

南北网络加速器汇总

  现在为突破电信网通间限制的软件很多,无一例外都是利用vpn技术,做一个双线路中转服务器来实现加速目的。要注意的是,使用这些加速器,是不会提高你原有线路的速度,加速的只是互访速度。

知道了原理,就应该明白,这些加速器,不是要选择谁做的最好,最适合你的,就是你与加速器服务器的连接速度。

从做工上讲,有的加速器做的很精巧,有的做成虚拟网卡形式,也有纯绿色的,甚至干脆直接利用操作系统自带的拨号功能。从个人角度上讲,比较偏爱windows自带的拨号加速器。因为有的加速器尽管只有几十K,运行后却占用十几兆内存。喜爱何种风格,就根据自己喜好吧,正所谓仁者见仁智者见智了。

下面是我收集的几款加速器,简单地试了效果,因每个人所处的地域不同,测试效果对每个人都会不同,所以,实际上并无参考价值,也就不再写出来。

金山网游加速器
网址:http://js.kingsoft.com/
测试账号:kingsoft
密码:kingsoft
服务器地址:北京
好像专为游戏加速,操作相对复杂

统一加速器
www.tywg.com
测试账号:任意
密码:任意
服务器地址:浙江(早期在四川)
虚拟网卡,做工细腻,功能多,操作简单

千渡互通
www.1000du.net
测试账号:自行申请
服务器地址:河南
windows自带拨号,但又集成了浏览器,多占十余兆内存。

凤凰网关
www.pubgates.net
已收费,50元包月
服务器地址:上海
软件小巧

通通通
www.tongtongtong.com
已收费
服务器地址:湖南及国外
功能繁多,是最早出现的加速器之一

快乐行
http://www.flashmdy.com/
账号申请:http://wow.dbug.com.cn/index.php
服务器地址:浙江
windows自带拨号

通达
www.tdgateway.com
测试账号密码:www.tdgateway.com
服务器地址:河北
windows自带拨号,电信网通分别使用不同客户端

嬴政网关
Www.3XyZ.Cn
已收费,18元包月
服务器地址:重庆
windows自带拨号,电信网通分别使用不同客户端

南北网桥
www.nbwq.com
免费,测试账号密码:test
服务器地址:山东
windows自带拨号,电信网通分别使用不同客户端

另外大名鼎鼎的google也出了类似小软件,名字叫Google Secure Access,用它上网后,你的ip就转为美国的了,可以彻底解除G*C#D对某些国外站点封锁,不过,你可不要利用它去做一些违法的事。


Feb 13 2007

两个基于ssl的代理

Category: 技术ssmax @ 10:19:55

要突破GFW的内容监控,暂时最有效的方法还是使用基于ssl链接的代理,当年的[无]那个x[界]也是这个道理

第一款就是tor+privoxy啦,这个大家都比较熟悉了,直接去http://tor.eff.org/ 搞一个套装就行了,也不用怎么配置,但是由于主要走的是美国的线路,最近台海光纤不稳定的情况下,基本没法用。

第二款就是Your Freedom,主要走的是德国那边的欧洲通道,最近比tor快不少,哈哈。

这个东西是收费服务,免费的每60分钟断一次,需要在网站上面注册用户,用java写的,貌似速度还行,用着挺爽。

与伟大的[金]那个[盾]工程相比,虽然SSH/VPN Tunneling技术让内容过滤变得困难,但是毕竟路由节点是有限的,即使是戴了套套也无济于事,所以只是还没到Net Nanny发脾气的时候。同时,听说已经有人放出了psiphon服务器的诱饵,就等你上钩了。诸君做坏事的时候记得加个心眼。。。


Jul 07 2006

Jpeg Metadata Read/Write

Category: 技术ssmax @ 14:27:32

读jpeg的exif的方法:

metadata-extractor

http://www.drewnoakes.com/code/exif/

这个是比较完整的读取包了,但是没有写的功能,所以另外找了一个 

 

读/写jpeg的metadata

mediautil是sourceforge的mediachest的java api 子项目

http://mediachest.sourceforge.net/mediautil/

不过文档不是太完整,研究了半天终于找到读写的方法了

InputStream fip = new FileInputStream(filename);
LLJTran llj = new LLJTran(fip);
llj.read(LLJTran.READ_INFO,true);
llj.setComment(“test jpeg comment”);

llj.setAppx(0,LLJTran.dummyExifHeader,0,LLJTran.dummyExifHeader.length,true);
Exif exif = (Exif) llj.getImageInfo();
Entry entry = new Entry(Exif.ASCII);
entry.setValue(0,”test exif user comment”);
exif.setTagValue(Exif.USERCOMMENT,-1,entry,true);

llj.refreshAppx();

fip = new BufferedInputStream(new FileInputStream(filename));
OutputStream out = new BufferedOutputStream(new FileOutputStream(destfile));
llj.xferInfo(fip, out, LLJTran.REPLACE, LLJTran.REPLACE);
fip.close();
out.close();
llj.freeMemory();

 

首先用 LLJTran.READ_INFO 模式把jpeg的header和exif信息读入,不需要整个文件的读取。

然后编辑jpeg commnet 和exif信息

最后调用 llj.xferInfo 把header和exif信息,图象信息写入到新文件中,其中LLJTran.REPLACE 是指替换掉原来文件中的信息,可以用LLJTran.RETAIN来保持不便,第一个指定是exif,第二个是jpeg comment。

 

读取刚才写的2个信息 

InputStream fip = new FileInputStream(destfile); // No need to buffer
LLJTran llj = new LLJTran(fip);
Log.debugLevel = Log.LEVEL_NONE;
llj.read(LLJTran.READ_HEADER,true);
System.out.println(llj.getComment());

System.out.println(((Exif)llj.getImageInfo()).getTagValue(Exif.USERCOMMENT,true));
基本就是这样,当然如果要通用的话还要加一些简单的判断。

另外AcdSee生成的exif 2.2格式用这个mediautil读取好像有点问题,不过mediautil生成的exif 2.2用AcdSee读取就一点问题都没有,可能是兼容问题吧,再研究研究规范。

花了一个下午,把exif 2.2的文档看了下,原来comment里面的格式没有规定,可以用unicode格式:

UNICODE(后面是UTF16-LE字符)

前面几个是utf8 字符,考~

做这个的主要目的是在自己生成的图片上面加一些固定格式的信息,等用户上传的时候可以知道这个图片的概况。。。。如果要我做OCR分析的话我可没有这个能力。。。


Jun 22 2006

快速排序

Category: 技术ssmax @ 18:01:24

我所理解的快速排序算法(加上黄金分割就完美啦~)
      快速排序是在实践中最快的已知排序算法,它的平均运行时间是O(NlogN)。该算法之所以特别快,主要是由于非常精练和高度优化的内部循环。在队列中寻找合适的枢点元素,并按枢点元素划分序列,是快速排序算法的关键。
      为简单起见,我这里数组的第一个元素作为枢点元素,重新排列数组,使得枢点元素之前的元素都小于枢点元素,而枢点元素之后的元素都大于或等于枢点元素。
      在这里我提供算法的两种实现:
第一种:
template <class T>
int Parttion(T a[], int low, int high)
{
      T x = a[low];
          while (low < high)
      {
            while (low < high && a[high] >=  x)
                  high–;
            a[low] = a[high];
                while (low < high && a[low] <  x)
                  low++;
            a[high] = a[low];
      }
          a[low] = x;
      return low;
}
第二种:
template <class T>
int Parttion(T a[], int low, int high)
{
      T x = a[low];
      int i = low;
     
      for (int j=low+1; j<=high; j++)
      {
            if (a[j] <= x)
            {
                  i++;
                  if (i != j)
                        Swap(a[i], a[j]);
            }
      }
     
      Swap(a[low], a[i]);
      return i;
}
template <class T>
void Swap(T & a, T & b)
{
      T t = a;
      a = b;
      b = t;
}
快速排序的驱动程序:
template <class T>
void QuickSort(T a[], int len)
{
      Qsort(a, 0, len-1);
}
template <class T>
void Qsort(T a[], int low, int high)
{
      if (low < high)
      {
            int k = Parttion(a, low, high);
            Qsort(a, low, k-1);
            Qsort(a, k+1, high);
      }
}


Jun 22 2006

把一些琐碎的东西记录起来

Category: 技术ssmax @ 16:13:29

cpp已经忘记得7788了。。。突然被人问起,数组大小能不能动态指定。。。java是可以的。。。然后:

C99 之前,声明数组时,[] 中的值必须是大于零的整数常量。C99 中,声明数组时,[] 中可以是变量。这就是所谓的变长数组(variable-length array,简称 VLA)。声明 VLA 时,不能对其进行初始化。


« Previous PageNext Page »