网络编程
位置:首页>> 网络编程>> Asp编程>> 整理一个asp多级树型分类问题的解决方法(5)

整理一个asp多级树型分类问题的解决方法(5)

 来源:csdn 发布时间:2007-10-17 18:38:00 

标签:树,分类,asp

这个算法有很多缺点。试列举几个如下:

1、由于我们需要查询FID下的所有分类,当分类非常多时,算法将非常地不经济,而且,由于要构造一个很大的strSQL,试想如果有1000个分类,这个strSQL将很大,能否执行就是一个问题。

2、我们知道,在SQL中使用In子句的效率是非常低的。这个算法不可避免地要使用In子句,效率很低。

我发现80%以上的程序员钟爱这样的算法,并在很多系统中大量地使用。细心的程序员会发现他们写出了很慢的程序,但苦于找不到原因。他们反复地检查SQL的执行效率,提高机器的档次,但效率的增加很少。

最根本的问题就出在这个算法本身。算法定了,能够再优化的机会就不多了。我们下面来介绍一种算法,效率将是上面算法的10倍以上。 

分类编码算法

问题就出在前面我们采用了顺序编码,这是一种最简单的编码方法。大家知道,简单并不意味着效率。实际上,编码科学是程序员必修的课程。下面,我们通过设计一种编码算法,使分类的编号ID中同时包含了其父类的信息。一个五级分类的例子如下:
 
此例中,用32(4+7+7+7+7)位整数来编码,其中,第一级分类有4位,可以表达16种分类。第二级到第五级分类分别有7位,可以表达128个子分类。
显然,如果我们得到一个编码为  1092787200  的分类,我们就知道:由于其编码为
 0100  0001001  0001010  0111000  0000000
所 以它是第四级分类。其父类的二进制编码是0100  0001001  0001010  0000000  0000000,十进制编号为1092780032。依次我们还可以知道,其父类的父类编码是0100  0001001  0000000  0000000  0000000,其父类的父类的父类编码是0100  0000000  0000000  0000000  0000000。(我是不是太罗嗦了:,但这一点很重要。再回头看看我们前面提到的第五个问题。哈哈,这不就已经得到了分类1092787200所在的 分类路径了吗?)。
现在我们在一般的情况下来讨论类别编码问题。设类别的层次为k,第i层的编码位数为Ni,  那么总的编码位数为N(N1+N2+..+Nk)。我们就得到任何一个类别的编码形式如下:
2^(N-(N1+N2+…+Ni))*j  +  父类编码
其中,i表示第i层,j表示当前层的第j个分类。

这样我们就把任何分类的编码分成了两个部分,其中一部分是它的层编码,一部分是它的父类编码。由下面公式定一的k个编码我们称为特征码:(因为i可以取k个值,所以有k个)
2^N-2^(N-(N1+N2+…+Ni))

对于任何给定的类别ID,如果我们把ID和k个特征码"相与",得到的非0编码,就是其所有父类的编码!

位编码算法

对任何顺序编码的Catalog表,我们可以设计一个位编码算法,将所有的类别编码规格化为位编码。在具体实现时,我们先创建一个临时表:


Create  TempCatalog(
 [OldID]  [int]  NOT  NULL,
 [NewID]  [int]  NOT  NULL,
 [OldFatherID]  [int]  NOT  NULL,
 [NewFatherID]  [int]  NOT  NULL
);


在这个表中,我们保留所有原来的类别编号OldID和其父类编号OldFatherID,以及重新计算的满足位编码要求的相应编号NewID、NewFatherID。
程序如下:



<% 
REM  oConn---数据库连接,已经打开 
REM  OldFather---原来的父类编号 
REM  NewFather---新的父类编号 
REM  N---编码总位数 
REM  Ni--每一级的编码位数数组 
REM  Level--当前的级数 
  
sub  FormatAllID(oConn,OldFather,NewFather,N,Nm,Ni  byref,Level) 
 strSQL  =  "select  CatalogID  ,  FatherID  from  Catalog  where  FatherID="  &  OldFather 
 set  rsCatalog=oConn.Execute(  strSQL  ) 
  
 j  =  1 
 do  while  not  rsCatalog.EOF 
   i  =  2  ^(N  -  Nm)  *  j 
   if  Level  then  i=  i  +  NewFather 
    
        
   OldCatalog  =  rsCatalog("CatalogID") 
   NewCatalog  =  i 
    
   REM  写入临时表 
   strSQL  =  "Insert  into  TempCatalog  (OldCatalogID  ,  NewCatalogID  ,  OldFatherID  ,  NewFatherID)" 
   strSQL  =  strSQL  &  "  values("  &  OldCatalog  &  "  ,  "  &  NewCatalog  &  "  ,  "  &  OldFather  &  "  ,  "  &  NewFather  &  ")" 
  
   Conn.Execute  strSQL 
    
   REM  递归调用FormatAllID 
   Nm  =  Nm  +  Ni(Level+1)     
   FormatAllID  oConn,OldCatalog  ,  NewCatalog  ,N,Nm,Ni,Level  +  1 
    
   rsCatalog.MoveNext 
    
   j  =  j+1 
 loop 
    
 rsCatalog.Close 
end  sub 
%>



调用这个算法的一个例子如下:



<% 
REM  定义编码参数,其中N为总位数,Ni为每一级的位数。 
 Dim  N,Ni(5) 
  
 Ni(1)  =  4 
  
 N  =  Ni(1) 
  
 for  i=2  to  5 
   Ni(i)  =  7 
   N  =  N  +  Ni(i) 
 next 
  
REM  打开数据库,创建临时表   
 strSQL  =  "Create  TempCatalog(  [OldID]  [int]  NOT  NULL,  [NewID]  [int]  NOT  NULL,  [OldFatherID]  [int]  NOT  NULL,  [NewFatherID]  [int]  NOT  NULL);" 
       Set  Conn  =  Server.CreateObject("ADODB.Connection")   
       Conn.Open  Application("strConn") 
       Conn.Execute  strSQL 
            
REM  调用规格化例程 
 FormatAllID  Conn,-1,-1,N,Ni(1),Ni,0 
  
REM  ------------------------------------------------------------------------ 
REM  在此处更新所有相关表的类别编码为新的编码即可。 
REM  ------------------------------------------------------------------------ 
  
REM  关闭数据库 
 strSQL=  "drop  table  TempCatalog;" 
 Conn.Execute  strSQL 
 Conn.Close 
%> 


 

0
投稿

猜你喜欢

  • 起源:.clearfix:after {visibility: hidden;display: block;font-size: 0;con
  • SSI是英文Server Side Includes的缩写,翻译成中文就是服务器端包含的意思。从技术角度上说,SSI就是在HTML文件中,可
  • 如果您目前拥有一个冷备份,但是缺少了其中的一个数据文件,但你目前存在所有的归档,如果您要恢复数据文件,可以参考以下的示例:[oracle@j
  • 如何用OdbcRegTool组件来创建一个数据源?OdbcRegTool是一个免费组件,在服务器上安装后,就可以来创建一个数据源:<h
  • 1.因为oracle 10g暂时没有与win7兼容的版本,我们可以通过对安装软件中某些文件的修改达到安装的目地。 a)打开“\ORACLE1
  • 一、在访客的内心深处做导航我讨厌迷失,不管是在道路上或是在线网络上。猜想一下?您的访客也是这样的。就像我们期望看到的道路上的路标一样,来帮助
  • 用asp程序进行网页设计,大多因为需要访问数据库,然后再将数据显示到页面,如果数据很多的话,页面的访问速度也就变慢了,为了解决这个问题,可以
  • 在MySQL经历了2008年Sun的收购和2009年Oracle收购Sun的过程中,基本处于停滞发展的情况,在可以预见的未来,MySQL是肯
  • 今年年初之时,微软发布了一个针对ActiveX控件的补丁,安装此补丁后的IE6中,当ActiveX控件获得焦点时,IE自动为其套上一个虚线矩
  • XML即可扩展标记语言(eXtensible Markup Language)。标记是指计算机所能理解的信息符号,通过此种标记,计算机之间可
  • Silverlight和Flash,到底谁更强?谁更有优势?很多初接触Silverlight和Flash的人总是会问这个问题,因为它们在表面
  • 参数Parameters解析响应时间resolveTimeout 数据类型:长整型。简单地说就是程序对目标主机的名字解析解析的一个过程时间。
  • 下面就是简单的例子,这里提供2中方法:test.htm            &
  • 要读懂这些代码主要是要了解ASP中操作二进制数据的对象ADODB.Stream!本程序主要用的就是Adodb.Stream,如果你有这个基础
  • CSS处理斜角导航条的一个例子,这个是写着测试用的。暂没有实际的应用。斜角处理比较麻烦,主要有两个地方。1、图片处理。2、负数的理解。这两个
  • 学习目的 学会SQL中的占位符用法 在鲸鱼这几天忙死了,好几天没写了,真对不起各位。这几天让XHTML闹得不开心,虽然以前也知道这个,但没太
  • SQL语言是一门简单易学却又功能强大的语言,它能让你快速上手并写出比较复杂的查询语句。但对于大多数开发者来说,使用SQL查询数据库并没有一个
  • 相信有很多人有用程序向Excel导数据的需求, 且做过. 一般导出一些文本数据是很方便的, 可选方法很多, 比如拼接文本字符串存.cvs格式
  • 不久之前,笔者一个在企业中从事网管工作的朋友向我求助关于SQL Server服务器内存升级后遇到的问题。原来,他们企业准备上一个企业邮箱系统
  • 今天一个同事报告一个问题,表都不能使用了,检查了一下,发现问题 db2 => select * from testACTNO ACTK
手机版 网络编程 asp之家 www.aspxhome.com