Weijian's profileEnjoy My LifePhotosBlogLists Tools Help

Weijian Ni

Occupation
Location
Photo 1 of 10
There are no categories in use.

Enjoy My Life

September 01

很牛的顶,供大家收藏


要顶
必须顶
不得不顶
用尽全力顶
再加上千斤顶
总之把它顶到顶
接着使出葵花宝顶
就算顶到史前也要顶
老子看了会用道德经顶
孔子亲自拜你为师天天顶
秦始皇站在阿房宫上使劲顶
汉高祖挥师杀向东罗马为你顶
吕布抛弃了貂禅而选择了帮你顶
张三丰见了后用太极拳九式全力顶
左冷禅召开武林盟主大会商讨如何顶
西门吹雪从此学会了最强一招剑神一顶
龙剑飞的如来神掌最后一招改为万佛朝顶
陆小凤从此再也不管闲事了而专门来为你顶
四大神捕四面出击看天下还有没有人敢不在顶

August 11

使用perl识别中文的方法

使用perl识别中文时,一种方法是根据编码字符集的范围进行识别,但是通常编码方式和相应的编码范围都不是很好确定,在网上找了一种比较通用的方法。
基本思想是使用perl的decode(编码)和encode(解码)功能,然后使用property进行匹配:

use strict;
use Encode;

my $str = "2008中国";
my $str_c = decode('cp936', $str);
$str_c =~ m/(\p{Han}+)/;
print encode('cp936',$1);

注:cp936是简体中文和Unicode的映射表。
August 04

很久没有使用STL了,记录一些常用的STL常用操作

string的使用方法
string是一个保存字符序列的容器,除了有字符串操作的功能外,还有容器的操作功能。要列出并说明这些功能,需要太多的篇幅,这里只说明常用的字符串操作功能。
  • 说明和初值:
    string strZqdm ;
    string strZqdmJz("600446") ;
    string strZqdmZs="000003";
  • 串连接:
    可以使用+或+=连接两个或多个字符串,这些字符串,可以是const char *、char *或string型的。有多个串时,前两个串中必须有一个是string型的。
    string strSql, strSel ;
    strSel="select * ";
    strSql = strSel+" from "+" zqk";
    strSel+=" from "+" zqk";
    下面这句是错误的:
    strSql="select *"+" from zqk"; //错误
    必须连接两个char *、const char *型时,可以写成:
    strSql=string("select *")+" from zqk";
    对于两个char *或const char *数据的连接,也要有一个先转换为string。如:
    char szSel[]={"select *"};
    char szFrom[]={" from zqk"};
    strSql=string(szSel)+szFrom;
  • 串替换
    把一个串中的子串,替换为另一个串,使用replace()函数,第一个参数是替换位置,第二参数是替换长度,第三个参数是替换子串。替换串和被替换的子串长度可以不等。
    下例把一个串中的YYYYMMDD替换为一个日期串。
    int n ;
    string strFile = ".\\QS_YYYYMMDD.dat" ;
    string strDate="20070505" ;  
    n = strFile.find("YYYYMMDD") ;
    if (n >= 0)
    strFile.replace(n, 8, strDate) ;
  • 串插入
    在串的中间插入一个子串,使用insert()函数,第一个参数是插入位置,第二个是插入子串。
    strSel = "600446";
    strSel.insert(0, "ZQDM=") ;
  • 串删除
    在串的中间,删除若干个字符,使用erase()函数,第一个参数是删除位置,第二个参数是删除长度。
    strSel = "ZQDM=600446";
    strSel.erase(0, 2) ;
    注意:串的替换,插入,删除操作中,操作位置必须是0到字串长度的范围之内,超过这个范围,将会引起异常!!
  • 串查找
    string容器提供了多种查找方法,正向和反向的简单查找,第一次或最后一次出现,第一次或最后一次不出现的复杂查找,不同的查找方法函数不同。这里只介绍最简单的正反向查找。
    1. 正向查找:查找串中出现指定子串的位置,使用find()函数,第一个参数表示子串。返回一个整型值,表示出子串的位置。大于等于0(string::npos)时表示出现了子串,否则表示没有出现。
      strSel = "ZQDM=600446 446";
      int n = strSel.find("446") ;
    2. 反向查找:从后面开始,查找串中出现指定子串的位置,使用rfind()函数,第一个参数表示子串。返回一个整型值,表示出子串的位置。大于等于0(string::npos)时表示出现了子串,否则表示没有出现。
      strSel = "ZQDM=600446 446";
      int n = strSel.rfind("446") ;
  • 取子串操作
    从一个串中取子串的操作,使用substr()函数,第一个参数表示开始位置,第二个参数表示取的长度。如果不包含第二个参数,一直取到串的结束。
    strSel = "select zqdm from hqk";
    strFunc= strSel.substr(0, 6) ; //从左取6个
    strTable= strSel.substr(7, 4) ;//从第7个开始,取4个
    str1 = strSel.substr(12) ;  //从第12个开始,取到结束
    string没有提供left,right函数,来从左边和右边取子串,造成了一些不便,需要采用技巧来实现。
    取左串:strSel.substr(0, n) ;
    取右串:strSel.substr(strSel.size()-n);
  • 字串比较
    比较两个字串,使用compare函数,可以比较全字串,或串中若干个字符。相等时,返回整型值0。
    strZqdm.compare(strDm) ; //比较两个串
    strZhzj.compare(4,8,strNewZh) ;//从strZhzj位置4开始,和strNewZh比较8个字符。
    strZhzj.compare(4,8,strNewZh,2) ;//从strZhzj的位置4开始,和strNewZh的位置2开始比较8个字符。
  • 其它常用操作
    对于string,还有一些常用的操作。
    返回字串长度的size(),例:len = strSql.size();
    下标操作at(),例:c = strSql.at(1);strSql.at(2)= "5 ";
    下标操作也可以用[],例:c = strSql[1];strSql[2]= "5 ";
    返回字串C字符指针的c_str(),类型是const char *。例:
    strZqdm= "000001";
    strcpy(szDm, strZqdm.c_str()) ;
    很遗憾,string中没有提供忽略大小写的字串比较,和忽略大小写的查找。如果需要这项功能,只有使用string的c_str()函数,用C的字串操作函数来实现了。
vector的使用方法
容器vector称做向量,相当于可以动态改变大小的数组,使用方法简单。vector里,提供了大量的函数,其中许多函数,在STL的不同容器里,用法是基本相同的,熟悉了vector,再掌握其容器,会简单的多。
下面说明vector的常用方法。
  • 说明和赋值
    vector <int> viCount ;//定义一个空的整型vector
    vector <int> viLen[10] ; //定义一个大小为10的整型vector
    vector <string> vsZqdm ; //定义string型的vector
    下面定义一个struct的vector:
    typedef struct
    {
    char szZqdm[7] ;
    char szZqmc[9] ;
    } ZQXX ;
    vector <ZQXX> vZqdm ;
    在定义vector <string> 后,VC6里会有4786的警告信息,可以使用#pragma warning(disable:4786)来屏蔽。
    对于vector中存在的元素,需要更改其值时,可以使用数组的方式,或成员函数at(),例如:
    viLen[1]=10;viLen.at(2)=11;
  • 迭代器iterator
    iterator,叫做迭代器,相当于一个指针,指向容器中的元素,是STL许多操作的基础,在遍历容器等场景下必须使用的数据类型。
    iterator的说明:
    vector<int>::iteratorit;
    vector的begin()成员函数返回第一个元素的iterator指针,end()成员函数返回最后一个元素下一个位置的iterator指针。* iterator返回iterator所指的元素的值。
    下例显示vector中的所有元素:
    vector <int> viCount(5) ;
    vector<int>::iteratorit;
    viCount[2]=3;
    for(it=viCount.begin();it!= viCount.end();it++)
    cout << *it << endl ;
  • 增加元素
    在vector中增加元素,分为在尾部增加,和在中间插入元素两种情况,push_back()在尾部增加元素,insert()在vector中间插入元素。使用insert插入元素时,要用到iterator定位,不太方便。
    例:
    viCount.push_back(10) ;  //在尾部增加一个元素,值是10
    it=viCount.begin();viCount.insert(it,11);//在开始处插入一个元素,值是11。
  • 删除元素
    删除vector里的所有元素,可以使用clear()函数,可以删除一个或多个元素,使用erase()。例:
    vZqdm.clear() ;  //清空vZqdm
    viCount.erase(it);  //删除迭代器it指的元素
    viCount.erase(it0,it1); //删除迭代器it0和it1之间的元素。
  • 引用元素
    对vector中的元素引用,除了[]和at()成员函数外,也可以通过迭代器引用其中的元素。
    vector <ZQXX> vZqdm ;
    vector< ZQXX >::iteratorit;
    ZQXX zq;
    it= vZqdm.begin();
    zq = *it ;
    memcpy(&zq,it,sizeof(zq));
  • 查找
    查找可以使用STL的find()函数完成,对标准类型的vector,STL已经定义了find()函数,如果数据类型是自定义的结构,需要自己编写find()函数,来完成查找。
    标准类型的vector的查找:
    it1 = find(viCount.begin(),viCount.end(),4) ;
    上句从viCount中查找值为4的元素,如果找到,it1就指向那个元素,如果找不到,it1就是viCount.end()。
    结构vector的查找,需要自己编写find函数来完成。
  • 排序
    STL提供了多种功能强大而复杂的排序功能,通过使用迭代器,可以对某vector中所有或部分元素排序。对于标准数据类型,可以使用STL的排序函数。对于自定义的数据类型,需要编写一个比较函数,由STL调用这个比较函数,完成排序功能。
    例:对int型的vector vCount做正序排序。
    sort(vCount.begin(), vCount.end());
    在VC6里,标准数据类型的降序排序也要写比较函数。例:
    sort(vCount.begin(), vCount.end(),mycomp);
    bool mycomp(const int &a, const int &b)
    {
     return a > b;
    }
    对于struct型的vector进行排序,必须写比较函数。
    例:按股票代码正序排序
    vector <ZQXX> vZqdm ;
    sort(vZqdm.begin(), vZqdm.end(), cmp_dm) ;
    bool cmp_dm(const ZQXX &a, const ZQXX &b)
    {
     return strcmp(a.szZqdm, b.szZqdm) < 0;
    }
    需要倒序排序时,把cmp_dm函数的<改为>就可以了。
  • 其它常用操作
    取大小函数int size(),如vZqdm.size();
    是否为空函数bool empty(),如vZqdm.empty();
    在尾部增加一个元素,push_back(),如vZqdm.push_back (zqdm);
    从尾部弹出一个元素,vector大小减1,pop_back(),如count=vCount.pop_back();


May 16

vi中的替换命令总结

  • 全局替换
    •  :%s/AAA/BBB 替换所有行的第一个AAA为BBB
    •  :%s/AAA/BBB/g 替换全文中的AAA为BBB
  • 单行替换
    •  :s/AAA/BBB 替换当前行的第一个AAA为BBB
    •  :s/AAA/BBB/g 替换当前行的所有AAA为BBB
  • 多行替换
    •  :n,$s/AAA/BBB 替换从第n行到最后一行每行中的第一个AAA为BBB (n为.表示当前行)
    •  :n,$s/AAA/BBB/g 替换从第n行到最后一行每行中的所有AAA为BBB (n为.表示当前行)
  • 特殊分隔符
    •  :s#AAA#sky# 替换当前行的第一个AAA为BBB (AAA和BBB中可以包含/)
March 25

转一篇文章,读罢后心中不禁浮现起峥嵘的读博岁月

张启发院士给他的博士生的一封信zz

最近我拜读了各位送交的年度工作计划,仔细推敲后,仍感到有三个方面的问题十分严重:
第一,对课题理解不够,有的根本谈不上理解,做了不止一年,尚未进入角色。
第二,已经完成的工作量严重偏少,博士(有的是从本室硕士上来的)做了几年还未见到可以发表的东西。
第三,在计划中倾向于以最低工作量结束研究。即游击战法。以消耗最少的人力来解决战斗。
这是从纸上看到的。从实验室看到的现象是,有那么几位常不到实验室照面,似乎这里是一个可来可不来的地方。而且愈未进入角色的,愈不钻研文献;工作做得愈差的,愈少见做实验。请各位想想,你不学,怎么能变内行?你不干,怎么会有结果?不钻研与自己课题密切相关的文献,不把实验室工作放在头等重要的位置上,不能算作一个名副其实的博士生。
写一点专题读书报告,其实是一个领域内进入角色的好方法。一篇不够,可以连续写几篇,直到把与研究课题有关的方面较好地弄懂为止。如果在写读书报告的同时,加进一点自己的见解就更好了。写得好的可以送出发表。这对加强业务能力,提高写作水平,深化对自己研究工作的感情和培养事业心都大有益处。几年来我们大会小会说了很多,而至今交得很少。有人说是没有时间,我看是不愿投入时间。对博士生而言,每天工作12小时是正常的,少于这个时间就不正常了;每周工作六天半以上是正常的,少于六天半就不正常了。
我这里是基于美国PhD四年学制所得到的概念。在我们目前三年学制还要强制性学半年英语的情况下,上述时间的投入充其量也只是一个下限。人生一世,应该追求有所建树。记得有一首诗:“朝为田舍郎,暮登天子堂。将相本无种,男儿当自强”。此诗所描述的虽有些封建意识,倒也道出了人生的真谛。想稍加以补充的是在男女完全平等的时代里,女儿也应当自强。
走到了做科学这条路上,博士生阶段有无成就与将来有无建树关系十分密切。椐我观察,在我们这一代人中凡是后来有所成就者,大多在博士学习阶段就奠定了很好的基础。我理解的基础含三个方面的内容:一是广博的知识和不断求知的欲望;二是作为今后发展基础的工作成就;三是不断进取的奋斗精神和以工作作为第一需要的人生观。试想:要建功立业,博士生阶段不搏,更待何时?
我们这里几乎所有的人都希望博士毕业后到国外去做博士后,我很赞成,并愿尽我之力给予支持。我很希望我们实验室出去的人将来在国际上都成为知名人士。今后在我们室毕业的博士出国做博士后可能主要有两类途径,一类是经我提名推荐,另一类是博士生本人争取,而将以后者为主。而后者却意味着要参与国际竞争。博士论文做得好,竞争性就强,我也乐意推荐,用人方也愿意接收。博士论文做得不好的,我不愿意推荐,而且推荐起来难度也大。其实,各人的路在各人自己脚下,各人的命运在各人自己手里。成败兴衰,全在各人,请各自勉。