2009年11月17日星期二

perl ASCII 码 处理日文或中文字

#!/usr/bin/perl -w
use strict;
use warnings;
#binmod(utf8);

my @strings = qw(
!?
@
#
$
%
^
&
*
(
)
{
}
[
]
`
;
:
\'
"
?
<
>
,
.
/
\
|
-
+
_
=
























?




_





);

my @char=qw(
1个好人
$
<+
<
);

my $Count=0;
my %hashmap;
my @ascii_character_numbers;
foreach(@strings)
{
@ascii_character_numbers = unpack("C*", "$_");
my $temp= "@ascii_character_numbers";
$hashmap{$temp}=$temp;
}

foreach my $k ( keys %hashmap )
{print $k,"-\t-";}

if (exists($hashmap{'163 189'})) {
#print " it exists \n";
}
print "*"x50,"\n";
my @ascii_characters;
foreach my $char (@char)
{
@ascii_characters = unpack("C*", "$char");
#print "@ascii_characters\n";
print "-"x50,"\n";
my @real=();
my $i=0;
while($i<=scalar(@ascii_characters))
{
#print $ascii_characters[$i],"\n";
if ($ascii_characters[$i]>127){
#print "是一个多字节字\n";
my $tt = $ascii_characters[$i]." ".$ascii_characters[$i+1];
push @real,$tt;
$i+=2;
}
else{
#print "是一个单字节字\n";
push @real,$ascii_characters[$i];
$i++;
}
if ($i==(scalar(@ascii_characters))) {
print "start to print real ary\n";
print join "\n",@real,"\n";
foreach my $key (@real){
if (!exists($hashmap{$key}))
{
print "No\n";
}
else{
print "YES\n";
$Count++;
}
}


}


}


}

print "All: $Count\n";

-------
下午有空做了修改
sub Check_Have_Defined{
# IN two argus: 1.productid 2.productname
# OUT 0: 所有字符都在字符列表中 1:有不在列表中的字符
my ( $pid, $pname ) = @_;
#print "$pid\t\t$pname\n";
my @ascii_characters = unpack("C*", "$pname");

my @real=();
my $i=0;
my $sign=0;
while($i<=scalar(@ascii_characters))
{
if ($ascii_characters[$i]>127){
#print "是一个多字节字\n";
my $tt = $ascii_characters[$i]." ".$ascii_characters[$i+1];
push @real,$tt;
$i+=2;
}
else{
#print "是一个单字节字\n";
push @real,$ascii_characters[$i];
$i++;
} #end else

if ($i==(scalar(@ascii_characters))){
#print "start to print real ary\n";
#print join "\n",@real,"\n";
foreach my $key (@real)
{
#print $key,"\n";
if (!exists($hashmap{$key}))
{
$sign++;
}
}
} #end if
} # while

#print "====== $sign =======\n";
if ($sign == 0)
{
#print "符合,所有字符在特殊列表中\n";
return 1;
}
else{
#print "不符合\n";
return 0;
}


} # sub

写成函数

调用:
use DBI;
my $host = "192.168.117.161";
my $db = "FrontEnd";
my $user = "dev";
my $passwd = "hereiserror";

my $Report="REPORT";
open(FHD,">$Report") || die "Can't write file";

my $dbh = DBI->connect("DBI:mysql:database=$db;host=$host",$user,$passwd) or die "connecting : $DBI::errstr\n";
my $sth;
my @chids = qw/50 56 57 58 59 60/;
my $Count=0;

foreach my $chid (@chids)
{
print FHD "ChannelID : $chid \n";
my $SQL=qq(select productid,name from C${chid}Product);
$sth = $dbh->prepare($SQL) or die "Can't prepare : $dbh->errstr\n";
$sth->execute();

while(my @array = $sth->fetchrow_array() ) {
my $needed = Check_Have_Defined($array[0],$array[1]);
if ($needed==1)
{
print FHD "ProductID: $array[0]\t ProductName: $array[1]\n";
$Count++;
}
}
}
print FHD "All: $Count\n";

2009年11月16日星期一

perl找出需要的串

#!/usr/bin/perl -w
use DBI;
use strict;

my $host = "192.168.10.118";
my $db = "BE";
my $user = "dev";
my $passwd = "3h8hs3";

my $Report="SPREPORT";
my $Rep="tempEPORT";
open(FHD,">$Report") || die "Can't write file";

open(HD,">$Rep") || die "Can't write file";

my $dbh = DBI->connect("DBI:mysql:database=$db;host=$host",$user,$passwd) or die "connecting : $DBI::errstr\n";
my $sth;


my @chids = qw/2 3 4 5 6 7 8 9 10/;
my @sum;
my %hm;
while()
{
chomp($_);
$hm{$_}=$_;
}

foreach my $chid (@chids)
{
print FHD "ChannelID : $chid \n";
print FHD "="x40,"\n";
my $SQL=qq(select productid,name from C${chid}Product);
#print "$SQL\n";
$sth = $dbh->prepare($SQL) or die "Can't prepare : $dbh->errstr\n";
$sth->execute();

my $productid;
my $name;

my $i = 0;
my $j = 0;
while(my @array = $sth->fetchrow_array() )
{
$productid=$array[0];nn
$name=$array[1];
chomp($name);
if ($productid==2536882) {
print "HERE\n";
}
if($name=~/^([!@#\$\%\^&*(){}\[\]`;:\'\"?<>,.\/\\|\-+_=])+$/)
{
$i++;
$j++;
print FHD "3. Sep characters ProductID:$productid \t Name:$name\n";
}
else{
my @sp = split //,$name;
my $sign=0;
foreach(@sp)
{
chomp($_);
$sign++ if ! exists $hm{$_};
}
if ($sign==0)
{
$i++;
$j++;
print FHD "3. Sep characters ProductID:$productid \t Name:$name\n";
}
else
{
$j++;
print HD " $j \n";
}
}
}
print FHD "ChannelID :$chid \t Count: $i\n";
push @sum,$i;
}

print "@sum\n";

$sth->finish();
$dbh->disconnect();


__DATA__





























_




2009年10月29日星期四

B+ tree and B-tree

B+ tree (BplusTree)

基本:
a balanced tree
从树的根到每个叶子结点路径长度相同
每个非叶结点有 n/2~n 个子结点
对于查询效率较高,但浪费一定的空间
每个典型的结点包含多达 n-1 个key :k1 k2 .. kn-1 和 n个指针 p1 p2 .. pn
查询的key值是顺利存储
p1 k1 p2 k2 .. pn-1 kn-1 pn
指针可以指向一个文件的某条记录或是某条指针(指向其他文件的记录)

每个叶子结点最多能够保存 (n - 1) 个值,但最少 [(n – 1) / 2] 个值
非叶结点指向树的叶结点,非叶结点至少有 n/2 个指针

更新
insert
do a search to determine what bucket the new record should go in
if the bucket is not full, add the record.
otherwise, split the bucket.
allocate new leaf and move half the bucket's elements to the new bucket
insert the new leaf's smallest key and address into the parent.
if the parent is full, split it also
now add the middle key to the parent node
repeat until a parent is found that need not split
if the root splits, create a new root which has one key and two pointers.

delete
It removes the search key value from the node.

文件存储结构
the leaf nodes of the tree stores the actual record

During insertion, the system locates the block that should contain the record. If there is enough free space in the node then the system stores it. Otherwise the system splits the record in two and distributes the records.

During deletion, the system first removes the record from the block containing it. If the block becomes less than half full as a result, the records in the block are redistributed.



perl 的B+tree实现Tree::BPTree

B - Tree Index Files
未完

处理xml一例

#!/usr/bin/perl
use strict;
use XML::Simple;
use Data::Dumper;
use warnings;

my $xmlfile = $ARGV[0];
my $ref = XMLin("$xmlfile",ForceArray=>1);
my $xmlname = `basename $xmlfile`;

my $Country ;
($Country = $xmlname ) =~ s/-\d+\.xml//g;
chop($Country);

my %prodprophash = (
"de" => "Produkteigenschaften",
"uk" => "Product properties",
"ca" => "Product properties",
"us" => "Product properties",
"es" => "Product properties",
"fr" => "Caract.ristiques du produit");

my $PROPerty = $prodprophash{"$Country"};
my $errnum = 0;my $warnnum = 0;
foreach (@{$ref->{'product'}}){
print "="x25,"\n";
print "Country : \"",$Country,"\"\n";
print "category id:";
print $_->{'category-id'}->[0],"\n";
print "Product id :"; print $_->{id}->[0],"\n";
my $ImgCheck="N";
my $ImgCheck="N";
if (exists($_->{'image-url'}->[0] ) )
{
if( !( ($_->{'image-url'}->[0]->{'content'} ne "") && ($_->{'image-url'}->[0]->{'content'} =~ /^http:\/\/www.abc.com\/product/)) )
...

[ array标记
{ hash标记

外层用SHELL调用
在特定目录下,循环利用 0000~0029 目录,利用一个文件来保存最后写入的文件夹名称

if [ x"$2" != x ]
then
tmpdir="$2"
downloadXml="N"
else
downloadXml="Y"

if ! [ -d "$batchDir" ]
then
mkdir -p "$batchDir"
echo "0" > "$batchDir"/lastBatchId.txt
fi

temp=$(expr $(cat "$batchDir"/lastBatchId.txt) + 1)
batchId=$(expr $temp % 30 )
batchIdDir=$(printf "%04d" $batchId)

if [ -d "$batchDir"/"$batchIdDir" ]
then
rm -rf "$batchDir"/"$batchIdDir"
fi

mkdir -p "$batchDir"/"$batchIdDir"
echo $(expr $batchId) > "$batchDir"/lastBatchId.txt

tmpdir="$batchDir"/"$batchIdDir"
fi

UTF-8

from wiki

設計UTF-8的理由
UTF-8的設計有以下的多字元組序列的特質:
單位元組字符的最高有效位元永遠為0。
多位元組序列中的首個字元組的幾個最高有效位元決定了序列的長度。最高有效位為110的是2位元組序列,而1110的是三位元組序列,如此類推。
多位元組序列中其餘的位元組中的首兩個最高有效位元為10。
UTF-8的這些特質,保證了一個字符的位元組序列不會包含在另一個字符的位元組序列中。這確保了以位元組為基礎的部份字串比對(sub-string match)方法可以適用於在文字中搜尋字或詞。有些比較舊的可變長度8位元編碼(如Shift JIS)沒有這個特質,故字串比對的算法變得相當複雜。雖然這增加了UTF-8編碼的字串的信息冗餘,但是利多於弊。另外,資料壓縮並非Unicode 的目的,所以不可混為一談。即使在傳送過程中有部份位元組因錯誤或干擾而完全遺失,還是有可能在下一個字符的起點重新同步,令受損範圍受到限制。
另一方面,由於其位元組序列設計,如果一個疑似為字符串的序列被驗證為UTF-8編碼,那麼我們可以有把握地說它是UTF-8字符串。一段兩位元組隨機序列碰巧為合法的UTF-8而非ASCII 的機率為32分1。對於三位元組序列的機率為256分3,對更長的序列的機率就更低了。

优点及缺点
关于字符串长度的一个注解:
总体来说,在Unicode字符串中不可能由码点数量决定显示它所需要的长度,或者显示字符串之后在文本缓冲区中光标应该放置的位置;组合字符、变宽字体、不可打印字符和从右至左的文字都是其归因。
所以尽管在UTF-8字符串中字元数量与码点数量的关系比UTF-32更为复杂,在实际中很少会遇到有不同的情形。
总体
优点
UTF-8是ASCII的一个超集。因为一个纯ASCII字符串也是一个合法的UTF-8字符串,所以现存的ASCII文本不需要转换。为传统的扩展ASCII字符集设计的软件通常可以不经修改或很少修改就能与UTF-8一起使用。
使用标准的面向字节的排序例程对UTF-8排序将产生与基于Unicode代码点排序相同的结果。(尽管这只有有限的有用性,因为在任何特定语言或文化下都不太可能有仍可接受的文字排列顺序。)
UTF-8和UTF-16都是可扩展标记语言文档的标准编码。所有其它编码都必须通过显式或文本声明来指定。[2]
任何面向字节字符串搜索算法都可以用于UTF-8的数据(只要输入仅由完整的UTF-8字符组成)。但是,对于包含字符记数的正则表达式或其它结构必须小心。
UTF-8字符串可以由一个简单的算法可靠地识别出来。就是,一个字符串在任何其它编码中表现为合法的UTF-8的可能性很低,并随字符串长度增长而减小。举例说,字元值C0,C1,F5至FF从来没有出现。为了更好的可靠性,可以使用正则表达式来统计非法过长和替代值(可以查看W3 FAQ: Multilingual Forms上的验证UTF-8字符串的正则表达式)。
缺点
一份写得很差(并且与当前标准的版本不兼容)的UTF-8解析器可能会接受一些不同的伪UTF-8表示并将它们转换到相同的Unicode输出上。这为设计用于处理八位表示的校验例程提供了一种遗漏信息的方式。

使用UTF-8的原因
ASCII轉换成UCS-2,在編碼前插入一個0x0。用這些編碼,會含括一些控制符,比如 " 或 '/',這在UNIX和一些C函數中,將會産生嚴重錯誤。因此可以肯定,UCS-2不適合作為Unicode的外部編碼,也因此誕生了UTF-8。

不利于正则表达式检索
正则表达式可以进行很多英文高级的模糊检索。例如,[a-h]表示a到h间所有字母。
同样GBK编码的中文也可以这样利用正则表达式,比如在只知道一个字的读音而不知道怎么写的情况下,也可用正则表达式检索,因为GBK编码是按读音排序的。只是UTF-8不是按读音排序的,所以会对正则表达式检索造成不利影响。但是這種使用方式並未考慮中文中的破音字,因此影響不大。Unicode是按部首排序的,因此在只知道一個字的部首而不知道如何發音的情况下,UTF-8 可用正则表达式检索而GBK不行。

其他
與其他 Unicode 編碼相比,特別是UTF-16,在 UTF-8 中 ASCII 字元佔用的空間只有一半,可是在一些字元的 UTF-8 編碼佔用的空間就要多出,特別是中文、日文和韓文(CJK)這樣的象形文字,所以具體因素因文檔而異,但不論哪種情況,差別都不可能很明顯。

utf8_unicode_ci 和 utf8_general_ci 区别
在 phpMyAdmin 中有多种字符集,其中 utf8_unicode_ci 和 utf8_general_ci 是最常用的,但是 utf8_general_ci 对某些语言的支持有一些小问题,如果可以接受,那最好使用 utf8_general_ci ,因为它速度快。否则,请使用较为精确的 utf8_unicode_ci,不过速度会慢一些。