Weijian 的个人资料Enjoy My Life照片日志列表 工具 帮助

日志


8月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的映射表。
8月4日

很久没有使用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();