A. 请问数据库里的层次模型、网状模型、关系模型之间的比较
1.层次模型
层次模型是数据库系统中最早使用的模型,它的数据结构类似一颗倒置的树,每个节点表示一个记录类型,记录之间的联系是一对多的联系,基本特征是:
* 一定有一个,并且只有一个位于树根的节点,称为根节点;
* 一个节点下面可以没有节点,即向下没有分支,那么该节点称为叶节点;
* 一个节点可以有一个或多个节点,前者称为父节点,后者称为子节点;
* 同一父节点的子节点称为兄弟节点。
* 除根节点外,其他任何节点有且只有一个父节点;
图11.7是一个层次模型的例子。
层次模型中,每个记录类型可以包含多个字段,不同记录类型之间、同一记录类型的不同字段之间不能同名。如果要存取某一类型的记录,就要从根节点开始,按照树的层次逐层向下查找,查找路径就是存取路径。如图11.8所示。
层次模型结构简单,容易实现,对于某些特定的应用系统效率很高,但如果需要动态访问数据(如增加或修改记录类型)时,效率并不高。另外,对于一些非层次性结构(如多对多联系),层次模型表达起来比较繁琐和不直观。
2.网状模型
网状模型可以看作是层次模型的一种扩展。它采用网状结构表示实体及其之间的联系。网状结构的每一个节点代表一个记录类型,记录类型可包含若干字段,联系用链接指针表示,去掉了层次模型的限制。网状模型的特征是:
1. 允许一个以上的节点没有父节点;
2. 一个节点可以有多于一个的父节点;
例如,图11.9(a)和图11.9(b)都是网状模型的例子。图11.9(a)中节点3有两个父节点,即节点1和节点2;图11.9(b)中节点4有三个父节点,即节点1,节点2和节点3。
由于网状模型比较复杂,一般实际的网状数据库管理系统对网状都有一些具体的限制。在使用网状数据库时有时候需要一些转换。例如,如图11.10所示。
网状模型与层次模型相比,提供了更大的灵活性,能更直接地描述现实世界,性能和效率也比较好。网状模型的缺点是结构复杂,用户不易掌握,记录类型联系变动后涉及链接指针的调整,扩充和维护都比较复杂。
3.关系模型
关系模型是目前应用最多、也最为重要的一种数据模型。关系模型建立在严格的数学概念基础上,采用二维表格结构来表示实体和实体之间的联系。二维表由行和列组成。下面以教师信息表和课程表为例,说明关系模型中的一些常用术语:
表11.1 教师信息表(表名为:tea_info)
TNO(教师编号)
NAME(姓名)
GENDER(性别)
TITLE(职称)
DEPT(系别)
805
李奇
女
讲师
基础部
856
薛智永
男
教授
信息学院
表11.2 课程表(表名为:cur_info)
CNO(课程编号)
DESCP(课程名称)
PERIOD(学时)
TNO(主讲老师编号)
005067
微机基础
40
805
005132
数据结构
64
856
1. 关系(或表):一个关系就是一个表,如上面的教师信息表和课程表。
2. 元组:表中的一行为一个元组(不包括表头)。
3. 属性:表中的一列为一个属性。
4. 主码(或关键字):可以唯一确定一个元组和其他元组不同的属性组。
5. 域:属性的取值范围。
6. 分量:元组中的一个属性值。
7. 关系模式:对关系的描述,一般表示为:关系名(属性1,属性2,... ...,属性n)。
关系模型中没有层次模型中的链接指针,记录之间的联系是通过不同关系中的同名属性来实现的。 关系模型的基本特征是:
1. 建立在关系数据理论之上,有可靠的数据基础;
2. 可以描述一对一,一对多和多对多的联系。
3. 表示的一致性。实体本身和实体间联系都使用关系描述。
4. 关系的每个分量的不可分性,也就是不允许表中表。
关系模型概念清晰,结构简单,实体、实体联系和查询结果都采用关系表示,用户比较容易理解。另外,关系模型的存取路径对用户是透明的,程序员不用关心具体的存取过程,减轻了程序员的工作负担,具有较好的数据独立性和安全保密性。
关系模型也有一些缺点,在某些实际应用中,关系模型的查询效率有时不如层次和网状模型。为了提高查询的效率,有时需要对查询进行一些特别的优化
B. excel2003数据透视表怎么用
一、 数据透视表的目的 数据透视表能帮助用户分析、组织数据。利用它可以很快地从不同角度对数据进行分类汇总。例如:经济普查数据分乡镇、分行业汇总,各种抽样调查分组分析汇总等。不是所有工作表都有建立数据透视表的必要,记录数量众多、以流水帐形式记录、结构复杂的工作表,为了将其中的一些内在规律显现出来,可将工作表重新组合并添加算法。即,建立数据透视表。 例如,有一张经济普查工作表,字段(列)多,且记录(行)数众多。字段有法人码、单位名称、乡镇、行政区划代码、行业代码、固定资产原值、经营税金、税费、工资福利支出等。为此,需要建立数据透视表,以便将一些内在规律显现出来。 二、数据透视表的建立 1、将光标移入需建立数据透视表的工作表中,然后单击"数据"→"数据透视表和数据透视图"。 2、"数据透视表和数据透视图向导-3步骤…"对话框上,选用默认选项,“Microsoft Excel数据清单或数据库”,单击"下一步"。 3、在"数据透视表和数据透视图向导-3步骤…"对话框上,在“选定区域”框中,已经自动选定工作表的(整个)数据区域,单击"下一步"。 4、在"数据透视表和数据透视图向导-3步骤之3"对话框上,选用默认选项:"新建工作表",在当前工作的左侧创建一个新工作表。这样做,可以保证原始数据的安全以及可利用性。单击"完成"后,一张新工作表-“数据表(下图所示)”即出现在当前工作的左侧。 三、数据表中数据的关系 1、数据表上,几个区域的设定方法 (1)“请将行字段拖至此处”(相当于“左端标题行”),将作为横向分类依据的字段,从“数据透视表”工具栏上拖至此处。例如,将“乡镇(街道)”字段拖至此处。 (2)“请将列字段拖至此处”(相当于“顶端标题行”),将作为纵向分类依据的字段,从“数据透视表”工具栏上拖至此处。拖至此处的字段是计算的“依据”。 (3)“请将数据项拖至此处”(相当于“普通数据区”),将作为统计依据的字段,从“数据透视表”工具栏上拖至此处。拖入该区中的字段,Excel将用某种算法,对其进行计算,然后将计算结果(汇总数值)显示出来。例如,将“工业总产值”、“本年折旧”字段拖至此处,即可得到各乡镇的求和汇总数。见下图: (4)“请将页字段拖至此处”,将作为分类显示(筛选)依据的字段,从“数据透视表”工具栏上拖至此处。 可以将一个或多个字段拖至此处。此区域中的字段是分类筛选的“首要”条件。例如,将“县”字段拖至此处,然后在其中,选择“沙县”,则下方表格中,只统计“沙县”有关的情况。 提示:“顶端标题行”和“页字段”区中,均可有多个字段。 2、透视分析数据 改变透视表内部的透视关系,从不同的角度查看数据之间的内在关系。主要包括:改变透视关系、添加或删除项目以及数据更新 (1)改变透视关系 更改各区域中的放置字段,或改变字段的分组条件即可以改变透视关系。 添加字段的方法上面已经介绍过了,删除方法,是将需删除字段拖出数据表区域即可。 改变字段分组条件的方法:单击字段名右侧的三角形按钮,然后单击下拉式列表菜单上的相应条件 (2)改变统计字段的算法 双击透视表左上角的统计字段名,打开”数据透视表字段“对话框,在“汇总方式”框内,选定所需的算法,然后单击“确定”。 (3)透视表的更新 若原工作表中的数据(含标题行-字段名)更改后,透视表作相应更新的方法: 默认情况下,当重新打开工作薄时,透视表数据将自动更新。 在不重新打开工作薄的情况下,在原工作表的数据更改后,在透视表中单击“数据透视表”工具栏上的“更新数据”按钮即可。 提示:普通数据更改后,单击“更新数据”按钮后,即可完成更新。若更改了已经拖入透视表中的字段名,则该字段将从透视中删除,需要重新添加。 四、透视图表 将透视表制作成透视图表的方法是:单击“数据透视表”工具栏上的“图表向导”即可生成一张图表(位于左侧的新工作表上)。 透视图表的编辑方法,与普通图表相似。
C. 数据泛化是什么
06-08-21] 来源: 作者: [字体:大 中 小]
黄建国
(合肥幼儿师范 现代教育技术中心 安徽 合肥 230011 )
摘要 为了更有效的进行在线分类挖掘,提出了一种泛化算法。该算法结合了数据立方体技术和面向属性归纳方法中的泛化策略,有效降低了聚合运算的运算量,提高了运算效率,将数据库中的原始数据泛化成用户感兴趣的概念层次上的、聚合的、具有统计意义的元数据,为在线分类提供了良好的数据环境。
关键词 数据挖掘 数据泛化 数据立方体
1 引言
数据准备是KDD过程中一个很重要的过程,良好的数据准备过程能够为数据挖掘提供清洁、可靠、稳定的数据环境,以保证挖掘算法的有效实施。在线分类理想的数据环境应具备以下几个特点: (1)数据应包含丰富的属性信息,应具备可靠性和稳定性;
(2)数据的属性应具有对于分类任务的相关性。大多数的分类任务只与数据库中部分属性有关,多余的、无关的属性介入分类,常会减慢甚至错误引导分类过程,应此必须去掉无关属性。
(3)数据应具有高层数据信息,以发现清晰的、高层的、具有统计意义的分类规则。在本文的研究中,为了使数据环境达到上述要求,在数据准备阶段采用了数据泛化的策略,这个策略用概念层次作为背景,结合了OLAP技术与Jiawei Han等人的面向属性归纳的方法,明显提高了工作效率。
2 面向属性归纳中的基本泛化策略和算法
随着KDD研究的逐步深入, Jiawei Han等人提出了一种基于归纳的知识发现方法——面向属性的归纳方法[1][2][3],这方法的特点是能够根据概念层次将低概念层的数据泛化到相应的高层次的概念层,以发现多层的或高层的规则。面向属性归纳方法是一种有效的、完整的知识发现算法,该算法将机器学习中示例学习方法与数据库的操作技术相结合[1]。算法的一个关键就是攀升属性所对应的概念层次树以泛化原始数据集的数据到用户感兴趣的概念层上,减少数据集的大小,从而降低知识发现过程的计算复杂度。面向属性归纳方法的进行,必须有两个前提:
(1)必须由用户提出明确的知识发现任务。在Jiawei Han等人的研究中,采用了一种类似SQL语句的知识发现语句DMQL[4]用来让用户定义发现任务,下面便是一个分类任务的语句描述:
要说明的是在本文的研究中采用了一个可视化的向导来引导用户定义发现任务,但为了文章描述方便,在本文的描述中,借用了DMQL来描述发现任务
(2)与发现任务相关的属性应有概念层次,如上文所述,数值型的概念层次可以自动提取,给定的概念层次可以用户的兴趣和发现任务的不同而进行动态调整。
在具备以上两个前提时,面向属性归纳采用了以下一些泛化策略。
● 泛化策略
策略1 在最小分解单位上泛化
一般而言,泛化都是在数据集的单个属性上进行的。因为单个属性常常是数据集中的最小分解单位。在最小分解单位上进行泛化,更能确定泛化过程中的细微变化,从而达到适度泛化的目的,避免过度泛化。
策略2 属性去除
如果一个属性在相关数据集中有大量不同的值,但是在其对应的概念层次树上,没有比该属性更高的概念层,则该属性将被从发现任务中去除。因为这样的属性是不可能被泛化到更高的概念层的,这是符合示例学习理论的。
策略3 概念树攀升
如果一个属性在概念层次树上有更高层次的概念,那么在泛化后的数据集中将所有记录的该属性值以高层次的属性值替代。
策略4 增加属性CNT
作为策略3的执行结果,必然会有许多不同的纪录由于属性值完全相同而合并成一条纪录。为了反应这一变化,引入属性CNT来纪录最初的表中不同纪录被概括成泛化表中相同纪录的个数。属性CNT在泛化的过程中保存了最初的计数,该值在知识发现的过程中起到了重要作用。
策略5 设立阈值
利用策略2中的CNT可以定义规则的正确率P,P=(符合规则的CNT值)/(符合规则左边属性条件的CNT值)。这样可以定义一阈值L用于取舍规则,若P>L则规则有效,否则丢弃该规则。另外,对一个属性A而言,为了将数据集概括到一定层次,必须沿着A的概念层次向上爬行几次。为了控制这个过程,有必要设置一归纳阈值,若A的取值个数达到这一阈值,则无需进一步概括,否则必须进行进一步的概括。除此之外,我们还可以对泛化表设置一个归纳阈值,如果泛化表的记录树大于该归纳阈值,则进行进一步的泛化直到满足这个归纳阈值为止。以上策略可以总结成算法如下:
算法1 (基本泛化算法)
输入条件:1.一个关系数据集,2 一个学习任务,3 一套相关属性的概念层次,4 每个属性归纳阈值t[i](i=1 to n,于属性相对应)、一个泛化表归纳阈值t2。
输出:一个用户期望的泛化后的数据集。
步骤:本算法可以分为两大步:
Step1. 根据用户提交的学习任务,从原始的关系数据集中收集与任务相关的属性与数据。生成初始泛化集GR;
Step2. 运行基本的泛化算法产生泛化数据集。
注意,step2可以细化成如下算法:
begin
for GR中的每一个属性Ai do
begin
while Ai的不同值的数目>t[i] do
begin
if Ai在概念层次中有高层次的概念 THEN
将Ai的所有值以高层次的概念值取代
else
在GR中移去Ai;
合并同样的记录;
end;
end;
while GR中的记录数>t2 do
begin
选择泛化属性进一步泛化;
合并相同的记录。
end;
end.
3 基于数据立方体的泛化算法
上述泛化算法是针对关系表的,其生成的结果也是关系数据表。对泛化后关系数据表进行分类规则挖掘时仍要进行大量的聚合运算,如计数、求和等。有没有办法降低聚合运算的运算量呢?有,那就是数据立方体。我们知道数据立方体的方格内存放的就是一些聚合值,而且对数据立方体进行聚合运算,其效率远高于对关系数据库进行聚合运算。基于此,本文提出了一种基于数据立方体的算法。
● 基于数据立方体的泛化算法
本算法共分为四步:第一步,初始化。首先,根据用户提出的发现任务,收集相关数据。(这里需说明的一点是此处用户提出的发现任务的相关属性实际上是一个维的概念,它可能对应于数据库中一个或几个有层次关系的实际属性。在下面的例子中我们将看到这一点。)然后确定每维的概念层次(自动提取数值型概念层次或动态调整已有概念层次)。第二步,构造基本立方体(Basecube)。这一步中首先根据数据库的数据分布特性(对于离散属性确定不同值的个数,连续值则确定数值间的最小间隔)确定每维的最初泛化层次,然后进行聚合计算来构造基本立方体。第三步,按照基本泛化策略对每维进行泛化造作,以确定每维理想的泛化层次。第四步,在新的泛化层次上对Basecube进行再计算,以构造最终的泛化立方体Primecube。这一步中将大量使用数据立方体的操作。该算法的形式描述如下:
算法2 基于数据立方体的泛化算法
输入:
1 一个待挖掘的关系数据集;
2 一个学习任务;
3 一个概念层次集合Gen(Ai),Ai是任意维;
4 Ti,任意维Ai的泛化阈值。
输出:一个最终泛化的数据立方体。
方法:
⑴ 始化:
① 根据用户的学习任务,确定每一维对应的属性,并从初始关系数据集中收集相关的数据。
② for 每一维Ai do
begin
if Ai是数值型 and Ai没有概念层次 then 自动生成概念层次(算法2.1)
else 动态调整概念层次以适应当前学习任务;
end;
⑵ 造Basecube:
① 对于每一维的属性计算其在数据库中对应的不同值的个数,如果是数值型则计算数值间的最小间隔,根据不同值的个数或最小间隔确定每一维的最初泛化层次。
② 按最初泛化层次确定每维的维成员,并进行COUNT,SUM等聚合运算。用文[26]中算法构造基本立方体。
⑶ 确定每维的泛化层次。
① 根据每一维的泛化阈值,进行基本泛化(算法2.5)找到最终理想的层次Li。
② 找出每一维Ai的映射<v,v’>,其中v是维成员值,v’是v在泛化层上对应的概念值。
⑷ 构造Primecube。
① 将Basecube的维成员v替换成v’;
② 对Basecube进行数据立方体操作,构造Primecube。
本算法中,第一步的时间复杂度主要依赖于特定数据库的操作和提取或调整概念层次的算法的效率。第二步的主要操作在于立方体的构造上,复杂度为 。第三步和第四步都只对基本立方体进行一次扫描,加上计算量,复杂度也为 。所以本算法中二到四步总的时间复杂度应为 。
下面以一个例子来进一步描述该算法。
例1:从网上下了一个数据库CITYDATA,该数据库记录了美国地区城市的情况。其中有三个表,如下:
表1 CityLocation 记录城市所在地
表2 LaborIncome 记录城市人员的收入
表3 记录犯罪率与教育程度
我们有一个初始概念层次US_LOCATION:
…
现在我们要对数据库进行如下任务的发现:
CLASSIFY CITYDATA
ACCORDING TO UNEMPLOYMENT_RATE
IN RELEVANCE TO US_LOCATION,FAMILY_INCOME,POVERTY_PCT,
CRIME_RATE,BACHELOR_PCT
FROM LABORINCOME,CRIMEEDUCATION
注意到该发现任务中的维US_LOCATION对应着几个有层次关系的数据库属性:area-name→county→state→region→big region→country,这些属性在概念层次Us location中都对应着相应的层次。每一维的阈值为5。
根据算法,我们首先作初始化,对family income,poverty pct,crime_rate,bachelor_pct由于它们是数值型的属性,所以概念层次可以自动提取出来,下面便是自动提取出来的概念层次:
运行算法二、三、四步,得到六维的基本立方体和泛化立方体,为方便起见本文给出其中三维的立方体图。
最后的泛化结果放在了表4。注意到cityid的属性已被移去。
表4 最后的泛化结果
4 结束语
数据泛化在线分类研究中占有重要地位,它是在线分类规则挖掘算法的基础。在线分类任务的一个重要特征就是数据量庞大,且数据中含有一定量的异常信息,这样的数据是不适合直接分类的。通过数据泛化,可以将数据整理、清洁,为分类提供较好的数据环境。另外数据泛化采用了概念层次技术,可以发现高层的分类规则,从而使分类结果更易理解。
本文结合基本的面向属性归纳技术,提出了一种数据立方体的数据泛化算法,给在线分类提供了较好的数据预处理技术。
参考文献
[1] Han J, Fu Y. Exploration of the power of attribute-oriented inction in data mining. In: Fayyad U M et al eds. Advances in Knowledge Discover and Data Mining. Cambridge: AAAI/MIT Press, 1996. 399~421
[2] J. Han, Y. Cai, and N. Cercone. Knowledge discovery in databases: An attribute_Oriented approach. In Proc. 18th Int. Conf. Very Large Data Bases, pages 547--559, Vancouver, Canada, August 1992.
[3] Cheung D W, Fu A W C, Han J. Knowledge discovery in databases: a rule based attribute oriented approach. In: Zbigniew R ed. Methodologies for Intelligent systems: 8th International Symposium. Berlin: Springer-Verlag, 1994. 164~173
[4] Han, J., Chiang, J., Chee, S., Chen, J., Chen, Q., Cheng, S., Gong, W., Kamber, M., Liu, G., Koperski, K., Lu, Y., Stefanovic, N., Winstone, L., Xia, B., Zaiane, O. R., Zhang, S. & Zhu, H. (1997), DBMiner: A system for data mining in relational databases and data warehouses, in `Proc. CASCON'97: Meeting of Minds', Toronto, Canada, pp. 249--260.
作者简介:
黄建国(1974年10月-- ) ,男,安徽省合肥市人,合肥幼儿师范学校讲师,中国科技大学计算机应用工程硕士。
D. 数据分析的方法有哪些
常用的列了九种供参考:
一、公式拆解
所谓公式拆解法就是针对某个指标,用公式层层分解该指标的影响因素。
举例:分析某产品的销售额较低的原因,用公式法分解
可以看到,数据可以被分到红蓝绿三个不同的簇(cluster)中,每个簇应有其特有的性质。显然,聚类分析是一种无监督学习,是在缺乏标签的前提下的一种分类模型。当我们对数据进行聚类后并得到簇后,一般会单独对每个簇进行深入分析,从而得到更加细致的结果。
获取更多数据分析学习信息及资料,欢迎关注聚数云海同名公众号哦~
E. 求数据库关系运算中差运算的代码实现
假设关系R和S分别有n和m个元组,
R的序号为i,S的序号为j.
算法如下:
关于键k对两关系作升序排列;
i=1;j=1;
while in and jm do
比较Ri(k)与Sj(k)
若Ri(k)小,则取Ri;序号i加1;
若Sj(k)小,则序号j加1;
若相等, 则i和j均加1;
endwhile;
若in , 则输出R的剩余元组.
算法简例:设R与S都仅
有一个属性(是键)。排
序后分别是:
R:1,4,5,6 (n=4)
S:2,4 (m=2)
执行过程是:
i=j=1;
比较1和2,输出1,i改为2;
比较4和2, j改为2;
比较4和4, i=j=3;
循环停止;
输出R剩余元组5,6.
算法停止.
操作结果:1,5,6.
这个是集合的差算法,类似于数据库的。
F. 数据库和算法是什么关系
算法的范围很大。 一般应用,数据的存储都委托给数据库了。
数据库是一种应用软件,用来存放各种数据的。 数据结构是计算机存储、组织数据的方式。 数据库是程序写出来的,而程序=数据结构+算法。 不
G. 数据结构
何谓数据结构
?
数据结构是在整个计算机科学与技术领域上广泛被使用的术语。它用来反映一个数据的内部构成,即一个数据由那些成分数据构成,以什么方式构成,呈什么结构。数据结构有逻辑上的数据结构和物理上的数据结构之分。逻辑上的数据结构反映成分数据之间的逻辑关系,而物理上的数据结构反映成分数据在计算机内部的存储安排。数据结构是数据存在的形式。 数据结构是信息的一种组织方式,其目的是为了提高算法的效率,它通常与一组算法的集合相对应,通过这组算法集合可以对数据结构中的数据进行某种操作。
?
数据结构主要研究什么?
?
数据结构作为一门学科主要研究数据的各种逻辑结构和存储结构,以及对数据的各种操作。因此,主要有三个方面的内容:数据的逻辑结构;数据的物理存储结构;对数据的操作(或算法)。通常,算法的
?
设计取决于数据的逻辑结构,算法的实现取决于数据的物理存储结构。
?
什么是数据结构?什么是逻辑结构和物理结构?
?
数据是指由有限的符号(比如,"0"和"1",具有其自己的结构、操作、和相应的语义)组成的元素的集合。结构是元素之间的关系的集合。通常来说,一个数据结构DS 可以表示为一个二元组:
?
DS=(D,S), //i.e., data-structure=(data-part,logic-structure-part) 这里D是数据元素的集合(或者是“结点”,可能还含有“数据项”或“数据域”),S是定义在D(或其他集合)上的关系的集合,S = { R | R : D×D×...},称之为元素的逻辑结构。 逻辑结构有四种基本类型:集合结构、线性结构、树状结构和网络结构。表和树是最常用的两种高效数据结构,许多高效的算法可以用这两种数据结构来设计实现。表是线性结构的(全序关系),树(偏序或层次关系)和图(局部有序(weak/local orders))是非线性结构。
?
数据结构的物理结构是指逻辑结构的存储镜像(image)。数据结构 DS 的物理结构 P对应于从 DS 的数据元素到存储区M(维护着逻辑结构S)的一个映射:
?
(PD,S) -- > M 存储器模型:一个存储器 M 是一系列固定大小的存储单元,每个单元 U 有一个唯一的地址 A(U),该地址被连续地编码。每个单元 U 有一个唯一的后继单元 U'=succ(U)。 P 的四种基本映射模型:顺序(sequential)、链接(linked)、索引(indexed)和散列(hashing)映射。
?
因此,我们至少可以得到4×4种可能的物理数据结构:
?
sequential (sets)
linked lists
indexed trees
hash graphs
?
(并不是所有的可能组合都合理)
?
??? 数据结构DS上的操作:所有的定义在DS上的操作在改变数据元素(节点)或节点的域时必须保持DS的逻辑和物理结构。
?
DS上的基本操作:任何其他对DS的高级操作都可以用这些基本操作来实现。最好将DS和他的所有基本操作看作一个整体——称之为模块。我们可以进一步将该模块抽象为数据类型(其中DS的存储结构被表示为私有成员,基本操作被表示为公共方法),称之为ADT。作为ADT,堆栈和队列都是一种特殊的表,他们拥有表的操作的子集。 对于DATs的高级操作可以被设计为(不封装的)算法,利用基本操作对DS进行处理。
?
好的和坏的DS:如果一个DS可以通过某种“线性规则”被转化为线性的DS(例如线性表),则称它为好的DS。好的DS通常对应于好的(高效的)算法。这是由计算机的计算能力决定的,因为计算机本质上只能存取逻辑连续的内存单元,因此如何没有线性化的结构逻辑上是不可计算的。比如对一个图进行操作,要访问图的所有结点,则必须按照某种顺序来依次访问所有节点(要形成一个偏序),必须通过某种方式将图固有的非线性结构转化为线性结构才能对图进行操作。
?
树是好的DS——它有非常简单而高效的线性化规则,因此可以利用树设计出许多非常高效的算法。树的实现和使用都很简单,但可以解决大量特殊的复杂问题,因此树是实际编程中最重要和最有用的一种数据结构。树的结构本质上有递归的性质——每一个叶节点可以被一棵子树所替代,反之亦然。实际上,每一种递归的结构都可以被转化为(或等价于)树形结构。
?
从机器语言到高级语言的抽象
?
我们知道,算法被定义为一个运算序列。这个运算序列中的所有运算定义在一类特定的数据模型上,并以解决一类特定问题为目标。这个运算序列应该具备下列四个特征。 有限性,即序列的项数有限,且每一运算项都可在有限的时间内完成;确定性,即序列的每一项运算都有明确的定义,无二义性;可以没有输入运算项,但一定要有输出运算项;可行性,即对于任意给定的合法的输入都能得到相应的正确的输出。这些特征可以用来判别一个确定的运算序列是否称得上是一个算法。 但是,我们现在的问题不是要判别一个确定的运算序列是否称得上是一个算法,而是要对一个己经称得上是算法的运算序列,回顾我们曾经如何用程序设计语言去表达它。
?
算法的程序表达,归根到底是算法要素的程序表达,因为一旦算法的每一项要素都用程序清楚地表达,整个算法的程序表达也就不成问题。
?
作为运算序列的算法,有三个要素。 作为运算序列中各种运算的运算对象和运算结果的数据;运算序列中的各种运算;运算序列中的控制转移。这三种要素依序分别简称为数据、运算和控制。 由于算法层出不穷,变化万千,其中的运算所作用的对象数据和所得到的结果数据名目繁多,不胜枚举。最简单最基本的有布尔值数据、字符数据、整数和实数数据等;稍复杂的有向量、矩阵、记录等数据;更复杂的有集合、树和图,还有声音、图形、图像等数据。 同样由于算法层出不穷,变化万千,其中运算的种类五花八门、多姿多彩。最基本最初等的有赋值运算、算术运算、逻辑运算和关系运算等;稍复杂的有算术表达式和逻辑表达式等;更复杂的有函数值计算、向量运算、矩阵运算、集合运算,以及表、栈、队列、树和图上的运算等:此外,还可能有以上列举的运算的复合和嵌套。 关于控制转移,相对单纯。在串行计算中,它只有顺序、分支、循环、递归和无条件转移等几种。
?
我们来回顾一下,自从计算机问世以来,算法的上述三要素的程序表达,经历过一个怎样的过程。
?
最早的程序设计语言是机器语言,即具体的计算机上的一个指令集。当时,要在计算机上运行的所有算法都必须直接用机器语言来表达,计算机才能接受。算法的运算序列包括运算对象和运算结果都必须转换为指令序列。其中的每一条指令都以编码(指令码和地址码)的形式出现。与算法语言表达的算法,相差十万八千里。对于没受过程序设计专门训练的人来说,一份程序恰似一份"天书",让人看了不知所云,可读性
?
极差。
?
用机器语言表达算法的运算、数据和控制十分繁杂琐碎,因为机器语言所提供的指令太初等、原始。机器语言只接受算术运算、按位逻辑运算和数的大小比较运算等。对于稍复杂的运算,都必须一一分解,直到到达最初等的运算才能用相应的指令替代之。机器语言能直接表达的数据只有最原始的位、字节、和字三种。算法中即使是最简单的数据如布尔值、字符、整数、和实数,也必须一一地映射到位、字节和字
中,还得一一分配它们的存储单元。对于算法中有结构的数据的表达则要麻烦得多。机器语言所提供的控制转移指令也只有无条件转移、条件转移、进入子程序和从子程序返回等最基本的几种。用它们来构造循环、形成分支、调用函数和过程得事先做许多的准备,还得靠许多的技巧。 直接用机器语言表达算法有许多缺点。
?
大量繁杂琐碎的细节牵制着程序员,使他们不可能有更多的时间和精力去从事创造性的劳动,执行对他们来说更为重要的任务。如确保程序的正确性、高效性。程序员既要驾驭程序设计的全局又要深入每一个局部直到实现的细节,即使智力超群的程序员也常常会顾此失彼,屡出差错,因而所编出的程序可靠性差,且开发周期长。 由于用机器语言进行程序设计的思维和表达方式与人们的习惯大相径庭,只有经过
较长时间职业训练的程序员才能胜任,使得程序设计曲高和寡。因为它的书面形式全是"密"码,所以可读性差,不便于交流与合作。因为它严重地依赖于具体的计算机,所以可移植性差,重用性差。这些弊端造成当时的计算机应用未能迅速得到推广。
?
克服上述缺点的出路在于程序设计语言的抽象,让它尽可能地接近于算法语言。 为此,人们首先注意到的是可读性和可移植性,因为它们相对地容易通过抽象而得到改善。于是,很快就出现汇编语言。这种语言对机器语言的抽象,首先表现在将机器语言的每一条指令符号化:指令码代之以记忆符号,地址码代之以符号地址,使得其含义显现在符号上而不再隐藏在编码中,可让人望"文"生义。其次表现在这种语言摆脱了具体计算机的限制,可在不同指令集的计算机上运行,只要该计算机配上汇编语言的一个汇编程序。这无疑是机器语言朝算法语言靠拢迈出的一步。但是,它离算法语言还太远,以致程序员还不能从分解算法的数据、运算和控制到汇编才能直接表达的指令等繁杂琐碎的事务中解脱出来。 到了50年代中期,出现程序设计的高级语言如Fortran,Algol60,以及后来的PL/l, Pascal等,算法的程序表达才产生一次大的飞跃。
?
诚然,算法最终要表达为具体计算机上的机器语言才能在该计算机上运行,得到所需要的结果。但汇编语言的实践启发人们,表达成机器语言不必一步到位,可以分两步走或者可以筑桥过河。即先表达成一种中介语言,然后转成机器语言。汇编语言作为一种中介语言,并没有获得很大成功,原因是它离算法语
?
言还太远。这便指引人们去设计一种尽量接近算法语言的规范语言,即所谓的高级语言,让程序员可以用它方便地表达算法,然后借助于规范的高级语言到规范的机器语言的"翻译",最终将算法表达为机器语言。而且,由于高级语言和机器语言都具有规范性,这里的"翻译"完全可以机械化地由计算机来完成,就像汇编语言被翻译成机器语言一样,只要计算机配上一个编译程序。 上述两步,前一步由程序员去完成,后一步可以由编译程序去完成。在规定清楚它们各自该做什么之后,这两步是完全独立的。它们各自该如何做互不相干。前一步要做的只是用高级语言正确地表达给定的算法,产生一个高级语言程序;后一步要做的只是将第一步得到的高级语言程序翻译成机器语言程序。至于程序员如何用高级语言表达算法和编译程序如何将高级语言表达的算法翻译成机器语言表达的算法,显然毫不相干。
?
处理从算法语言最终表达成机器语言这一复杂过程的上述思想方法就是一种抽象。汇编语言和高级语言的出现都是这种抽象的范例。 与汇编语言相比,高级语言的巨大成功在于它在数据、运算和控制三方
?
面的表达中引入许多接近算法语言的概念和工具,大大地提高抽象地表达算法的能力。 在运算方面,高级语言如Pascal,除允许原封不动地运用算法语言的四则运算、逻辑运算、关系运算、算术表达式、逻辑表达式外,还引入强有力的函数与过程的工具,并让用户自定义。这一工具的重要性不仅在于它精简了重复的程序文本段,而且在于它反映出程序的两级抽象。
?
在函数与过程调用级,人们只关心它能做什么,不必关心它如何做。只是到函数与过程的定义时,人们才给出如何做的细节。用过高级语言的读者都知道,一旦函数与过程的名称、参数和功能被规定清楚,那么,在程序中调用它们便与在程序的头部说明它们完全分开。你可以修改甚至更换函数体与过程体,而不影响它们的被调用。如果把函数与过程名看成是运算名,把参数看成是运算的对象或运算的结果,那么
?
,函数与过程的调用和初等运算的引用没有两样。利用函数和过程以及它们的复合或嵌套可以很自然地表达算法语言中任何复杂的运算。
?
在数据方面,高级语言如Pascal引人了数据类型的概念,即把所有的数据加以分类。每一个数据(包括表达式)或每一个数据变量都属于其中确定的一类。称这一类数据为一个数据类型。 因此,数据类型是数据或数据变量类属的说明,它指示该数据或数据变量可能取的值的全体。对于无结构的数据,高级语言如Pascal,除提供标准的基本数据类型--布尔型、字符型、整型和实型外,还提供用户可自定义的枚举类、子界类型和指针类型。这些类型(除指针外),其使用方式都顺应人们在算法语言中使用的习惯。对于有结构的数据,高级语言如Pascal,提供了数组、记录、有限制的集合和文件等四种标准的结构数据类型。其中,数组是科学计算中的向量、矩阵的抽象;记录是商业和管理中的记录的抽象;有限制的集合是数学中足够小的集合的势集的抽象;文件是诸如磁盘等外存储数据的抽象。
?
人们可以利用所提供的基本数据类型(包括标准的和自定义的),按数组、记录、有限制的集合和文件的构造规则构造有结构的数据。 此外,还允许用户利用标准的结构数据类型,通过复合或嵌套构造更复杂更高层的结构数据。这使得高级语言中的数据类型呈明显的分层。 高级语言中数据类型的分层是没有穷尽的,因而用它们可以表达算法语言中任何复杂层次的数据。 在控制方面,高级语言如Pascal,提供了表达算法控制转移的六种方式。
?
(1)缺省的顺序控制";"。
?
(2)条件(分支)控制:"if表达式(为真)then S1 else S2;" 。
?
(3)选择(情况)控制:
?
"Case 表达式 of
?
值1: S1
值2: S2
...
值n: Sn
end"
?
(4)循环控制:
?
"while 表达式(为真) do S;" 或
"repeat S until 表达式(为真);" 或
"for变量名:=初值 to/downto 终值do S;"
?
(5)函数和过程的调用,包括递归函数和递归过程的调用。
?
(6)无条件转移goto。
这六种表达方式不仅覆盖了算法语言中所有控制表达的要求,而且不再像机器语言或汇编语言那样原始、那样繁琐、那样隐晦,而是如上面所看到的,与自然语言的表达相差无几。 程序设计语言从机器语言到高级语言的抽象,带来的主要好处是: 高级语言接近算法语言,易学、易掌握,一般工程技术人员只要几周时间的培训就可以胜任程序员的工作;高级语言为程序员提供了结构化程序设计的环境和工具,使得设计出来的程序可读性好,可维护性强,可靠性高;高级语言远离机器语言,与具体的计算机硬件关系不大,因而所写出来的程序可移植性好,重用率高; 由于把繁杂琐碎的事务交给了编译程序去做,所以自动化程度高,开发周期短,且程、序员得到解脱,可以集中时间和精力去从事对于他们来说更为重要的创造性劳动,以提高、程序的质量。
?
数据结构、数据类型和抽象数据类型
?
数据结构、数据类型和抽象数据类型,这三个术语在字面上既不同又相近,反映出它们在含义上既有区别又有联系。
?
数据结构是在整个计算机科学与技术领域上广泛被使用的术语。它用来反映一个数据的内部构成,即一个数据由哪些成分数据构成,以什么方式构成,呈什么结构。数据结构有逻辑上的数据结构和物理上的数据结构之分。逻辑上的数据结构反映成分数据之间的逻辑关系,物理上的数据结构反映成分数据在计算机内的存储安排。数据结构是数据存在的形式。
?
数据是按照数据结构分类的,具有相同数据结构的数据属同一类。同一类数据的全体称为一个数据类型。在程序设计高级语言中,数据类型用来说明一个数据在数据分类中的归属。它是数据的一种属性。这个属性限定了该数据的变化范围。为了解题的需要,根据数据结构的种类,高级语言定义了一系列的数据类型。不同的高级语言所定义的数据类型不尽相同。Pascal语言所定义的数据类型的种类。
?
其中,简单数据类型对应于简单的数据结构;构造数据类型对应于复杂的数据结构;在复杂的数据结构里,允许成分数据本身具有复杂的数据结构,因而,构造数据类型允许复合嵌套;指针类型对应于数据结构中成分数据之间的关系,表面上属简单数据类型,实际上都指向复杂的成分数据即构造数据类型中的数据,因此这里没有把它划入简单数据类型,也没有划入构造数据类型,而单独划出一类。
?
数据结构反映数据内部的构成方式,它常常用一个结构图来描述:数据中的每一项成分数据被看作一个结点,并用方框或圆圈表示,成分数据之间的关系用相应的结点之间带箭号的连线表示。如果成分数据本身又有它自身的结构,则结构出现嵌套。这里嵌套还允许是递归的嵌套。
?
由于指针数据的引入,使构造各种复杂的数据结构成为可能。按数据结构中的成分数据之间的关系,数据结构有线性与非线性之分。在非线性数据结构中又有层次与网状之分。 由于数据类型是按照数据结构划分的,因此,一类数据结构对应着一种数据类型。数据类型按照该类型中的数据所呈现的结构也有线性与非线性之分,层次与网状之分。一个数据变量,在高级语言中的类型说明必须是读变量所具有的数据结构所对应的数据类型。最常用的数据结构是数组结构和记录结构。数组结构的特点是:
?
成分数据的个数固定,它们之间的逻辑关系由成分数据的序号(或叫数组的下标)来体现。这些成分数据按照序号的先后顺序一个挨一个地排列起来。每一个成分数据具有相同的结构(可以是简单结构,也可以是复杂结构),因而属于同一个数据类型(相应地是简单数据类型或构造数据类型)。这种同一的数据类型称为基类型。所有的成分数据被依序安排在一片连续的存储单元中。 概括起来,数组结构是一个线性的、均匀的、其成分数据可随机访问的结构。
?
由于这、种结构有这些良好的特性,所以最常被人们所采用。在高级语言中,与数组结构相对应的、数据类型是数组类型,即数组结构的数据变量必须说明为array [i] of T0 ,其中i是数组、结构的下标类型,而T0是数组结构的基类型。 记录结构是另一种常用的数据结构。它的特点是:与数组结构一样,成分数据的个数固定。但成分数据之间没有自然序,它们处于平等地位。每一个成分数据被称为一个域并赋予域名。不同的域有不同的域名。不同的域允许有不同的结构,因而允许属于不同的数据类型。与数组结构一样,它们可以随机访问,但访问的途径靠的是域名。在高级语言中记录结构对应的数据类型是记录类型。记录结构的数据的变量必须说明为记录类型。
?
抽象数据类型的含义在上一段已作了专门叙述。它可理解为数据类型的进一步抽象。即把数据类型和数据类型上的运算捆在一起,进行封装。引入抽象数据类型的目的是把数据类型的表示和数据类型上运算的实现与这些数据类型和运算在程序中的引用隔开,使它们相互独立。对于抽象数据类型的描述,除了必须描述它的数据结构外,还必须描述定义在它上面的运算(过程或函数)。抽象数据类型上定义的过程和函
数以该抽象数据类型的数据所应具有的数据结构为基础。
?
泛型设计和数据结构与算法
?
下面我想再说说关于泛型程序设计模型对于数据结构和算法方面的最新推动,泛型思想已经把数据结
?
构和算法方面的基本思想抽象到了一个前所未有的高度,现在有多种程序设计语言支持泛型设计,比如
ADA,C++,而且据说在JAVA的下一版本和C#中也将对泛型设计进行全面的支持。
?
先说说泛型设计的基本思想:泛型编程(generic programming,以下直接以GP称呼)是一种全新的程序设计思想,和OO,OB,PO这些为人所熟知的程序设计想法不同的是GP抽象度更高,基于GP设计的组件之间偶合度底,没有继承关系,所以其组件间的互交性和扩展性都非常高。我们都知道,任何算法都是作用在一种特定的数据结构上的,最简单的例子就是快速排序算法最根本的实现条件就是所排序的对象是存
贮在数组里面,因为快速排序就是因为要用到数组的随机存储特性,即可以在单位时间内交换远距离的对象,而不只是相临的两个对象,而如果用联表去存储对象,由于在联表中取得对象的时间是线性的既O[n],这样将使快速排序失去其快速的特点。也就是说,我们在设计一种算法的时候,我们总是先要考虑其应用的数据结构,比如数组查找,联表查找,树查找,图查找其核心都是查找,但因为作用的数据结构不同
?
将有多种不同的表现形式。数据结构和算法之间这样密切的关系一直是我们以前的认识。泛型设计的根本思想就是想把算法和其作用的数据结构分离,也就是说,我们设计算法的时候并不去考虑我们设计的算法将作用于何种数据结构之上。泛型设计的理想状态是一个查找算法将可以作用于数组,联表,树,图等各种数据结构之上,变成一个通用的,泛型的算法。这样的理想是不是很诱惑人?
?
泛型编程带来的是前所未有的弹性以及不会损失效率的抽象性,GP和OO不同,它不要求你通过额外的间接层来调用函数:它让你撰写完全一般化并可重复使用的算法,其效率与针对特定数据结构而设计的算法旗鼓相当。我们大家都知道数据结构在C++中可以用用户定义类型来表示,而C++中的模板技术就是以类型作为参数,那么我可以想象利用模板技术可以实现我们开始的GP思想,即一个模板函数可以对于各种传递进来的类型起作用,而这些类型就可以是我们定义的各种数据结构。
?
泛型算法抽离于特定类型和特定数据结构之外,使得其适应与尽可能的一般化类型,算法本身只是为了实现算法其需要表达的逻辑本质而不去被为各种数据结构的实现细节所干扰。这意味着一个泛型算法实际具有两部分。1,用来描叙算法本质逻辑的实际指令;2,正确指定其参数类型必须满足的性质的一组需求条件。到此,相信有不少人已经开始糊涂了,呵呵,不要紧。毕竟GP是一种抽象度非常高的程序设计思想,里面的核心就是抽象条件成为成为程序设计过程中的核心,从而取代了类型这在OO里面的核心地位,正是因为类型不在是我们考虑的重点,类型成为了抽象条件的外衣,所以我们称这样的程序思想为泛型思想------把类型泛化。
H. 怎样用excel图表功能同时进行横向和纵向的数据分析
1建立数据透视表(图)的目的数据透视表能帮助用户分析、组织数据。利用它可以很快地从不同角度对数据进行分类汇兑。首先应该明确的是:不是所有工作表都有建立数据透视表(图)的必要。记录数量众多、以流水帐形式记录、结构复杂的工作表,为了,将其中的一些内在规律显现出来,可将工作表重新组合并添加算法。即,建立数据透视表(图)。例如,有一张工作表,是一个大公司员工(姓名、性别、出生年月、所在部门、工作时间、政治面貌、学历、技术职称、任职时间、毕业院校、毕业时间等)信息一览表,不但,字段(列)多,且记录(行)数众多。为此,需要建立数据透视表,以便将一些内在规律显现出来。2创建数据透视表⑴将光标移入需建立数据透视表的工作表中,然后单击"数据"·"数据透视表和图表报告"。⑵"数据透视表和数据透视图向导-3步骤1"对话框上,单击"下一步"(选用默认选项,“Microsoft Excel数据清单或数据库”)。⑶在"数据透视表和数据透视图向导-3步骤2"对话框上,“选定区域”框中,已经自动选定工作表的(整个)数据区域,单击"下一步"。⑷在"数据透视表和数据透视图向导-3步骤3"对话框上,选用默认选项:"新建工作表",在当前工作的左侧创建一个新工作表。这样做,可以保证原始数据的安全以及可利用性。单击"完成"后,一张新工作表-“数据表(下图所示)”即出现在当前工作的左侧。3设置数据表中数据的关系3.1数据表上,几个区域的设定方法1、“请将行字段拖至此处”(相当于“左端标题行”),将作为横向分类依据的字段,从“数据透视表”工具栏上拖至此处。例如,将“所在部门”字段拖至此处。2、“请将列字段拖至此处”(相当于“顶端标题行”),将作为纵向分类依据的字段,从“数据透视表”工具栏上拖至此处。拖至此处的字段是计数的“依据”。例如,将“性别”字段拖至此处,计数的依据就是“男”和“女”两项。3、“请将数据项拖至此处”(相当于“普通数据区”),将作为统计依据的字段,从“数据透视表”工具栏上拖至此处。拖入该区中的字段,Excel将用某种算法,对其进行计算,然后将计算结果(汇总数值)显示出来(如何设置算法见3.2)。4、“请将页字段拖至此处”,将作为分类显示(筛选)依据的字段,从“数据透视表”工具栏上拖至此处。可以将一个或多个字段拖至此处。此区域中的字段是分类筛选的“首要”条件。例如,将“政治面貌”字段拖至此处,然后在其中,选择“党员”,则下方表格中,只统计“党员”有关的情况。提示:“顶端标题行”和“页字段”区中,均可有多个字段。3.2透视分析数据改变透视表内部的透视关系,从不同的角度查看数据之间的内在关系。主要包括:改变透视关系、添加或删除项目以及数据更新1、改变透视关系更改各区域中的放置字段,或改变字段的分组条件即可以改变透视关系。添加字段的方法上面已经介绍过了,删除方法,是将需删除字段拖出数据表区域即可。改变字段分组条件的方法:单击字段名右侧的三角形按钮,然后单击下拉式列表菜单上的相应条件2、改变统计字段的算法双击透视表左上角的统计字段名,打开”数据透视表字段“对话框(右图)。在“汇总方式”框内,选定所需的算法,然后单击“确定”。提示:对日期型字段求和时,以1990年1月1日起算。3、透视表的更新若原工作表中的数据(含标题行-字段名)更改后,透视表作相应更新的方法:默认情况下,当重新打开工作薄时,透视表数据将自动更新。在不重新打开工作薄的情况下,在原工作表的数据更改后,在透视表中单击“数据透视表”工具栏上的“更新数据”按钮即可。提示:普通数据更改后,单击“更新数据”按钮后,即可完成更新。若更改了已经拖入透视表中的字段名,则该字段将从透视中删除,需要重新添加。4透视图表将透视表制作成透视图表的方法是:单击“数据透视表”工具栏上的“图表向导”即可生成一张图表(位于左侧的新工作表上)。透视图表的编辑方法,与普通图表相似。
I. 如何创建数据透视表
1建立数据透视表(图)的目的 数据透视表能帮助用户分析、组织数据。利用它可以很快地从不同角度对数据进行分类汇兑。 首先应该明确的是:不是所有工作表都有建立数据透视表(图)的必要。 记录数量众多、以流水帐形式记录、结构复杂的工作表,为了,将其中的一些内在规律显现出来,可将工作表重新组合并添加算法。即,建立数据透视表(图)。 例如,有一张工作表,是一个大公司员工(姓名、性别、出生年月、所在部门、工作时间、政治面貌、学历、技术职称、任职时间、毕业院校、毕业时间等)信息一览表,不但,字段(列)多,且记录(行)数众多。为此,需要建立数据透视表,以便将一些内在规律显现出来。 2创建数据透视表 ⑴将光标移入需建立数据透视表的工作表中,然后单击"数据"·"数据透视表和图表报告"。 ⑵"数据透视表和数据透视图向导-3步骤1"对话框上,单击"下一步"(选用默认选项,“Microsoft Excel数据清单或数据库”)。 ⑶在"数据透视表和数据透视图向导-3步骤2"对话框上,“选定区域”框中,已经自动选定工作表的(整个)数据区域,单击"下一步"。 ⑷在"数据透视表和数据透视图向导-3步骤3"对话框上,选用默认选项:"新建工作表",在当前工作的左侧创建一个新工作表。这样做,可以保证原始数据的安全以及可利用性。单击"完成"后,一张新工作表-“数据表(下图所示)”即出现在当前工作的左侧。 3设置数据表中数据的关系 3.1数据表上,几个区域的设定方法 1、“请将行字段拖至此处”(相当于“左端标题行”),将作为横向分类依据的字段,从“数据透视表”工具栏上拖至此处。例如,将“所在部门”字段拖至此处。 2、“请将列字段拖至此处”(相当于“顶端标题行”),将作为纵向分类依据的字段,从“数据透视表”工具栏上拖至此处。 拖至此处的字段是计数的“依据”。例如,将“性别”字段拖至此处,计数的依据就是“男”和“女”两项。 3、“请将数据项拖至此处”(相当于“普通数据区”),将作为统计依据的字段,从“数据透视表”工具栏上拖至此处。 拖入该区中的字段,Excel将用某种算法,对其进行计算,然后将计算结果(汇总数值)显示出来(如何设置算法见3.2)。 4、“请将页字段拖至此处”,将作为分类显示(筛选)依据的字段,从“数据透视表”工具栏上拖至此处。 可以将一个或多个字段拖至此处。此区域中的字段是分类筛选的“首要”条件。例如,将“政治面貌”字段拖至此处,然后在其中,选择“党员”,则下方表格中,只统计“党员”有关的情况。 提示:“顶端标题行”和“页字段”区中,均可有多个字段。 3.2透视分析数据 改变透视表内部的透视关系,从不同的角度查看数据之间的内在关系。主要包括:改变透视关系、添加或删除项目以及数据更新 1、改变透视关系 更改各区域中的放置字段,或改变字段的分组条件即可以改变透视关系。 添加字段的方法上面已经介绍过了,删除方法,是将需删除字段拖出数据表区域即可。 改变字段分组条件的方法:单击字段名右侧的三角形按钮,然后单击下拉式列表菜单上的相应条件 2、改变统计字段的算法 双击透视表左上角的统计字段名,打开”数据透视表字段“对话框(右图)。 在“汇总方式”框内,选定所需的算法,然后单击“确定”。 提示:对日期型字段求和时,以1990年1月1日起算。 3、透视表的更新 若原工作表中的数据(含标题行-字段名)更改后,透视表作相应更新的方法: 默认情况下,当重新打开工作薄时,透视表数据将自动更新。 在不重新打开工作薄的情况下,在原工作表的数据更改后,在透视表中单击“数据透视表”工具栏上的“更新数据”按钮即可。 提示:普通数据更改后,单击“更新数据”按钮后,即可完成更新。若更改了已经拖入透视表中的字段名,则该字段将从透视中删除,需要重新添加。 4透视图表 将透视表制作成透视图表的方法是:单击“数据透视表”工具栏上的“图表向导”即可生成一张图表(位于左侧的新工作表上)。 透视图表的编辑方法,与普通图表相似。
J. 数据结构算法 两线性表A,B求交集。。。请高手指点!!!
将A与B分别排序,然后求交。
例如:将A与B按升序排列,设A表头为P,B表头为Q,若A[P]>B[Q]那么Q++,若A[P]<B[Q]那么P++;如果A[P]=B[Q],Q++、P++,Count++,And[Count]=B[Q-1];当P或者Q其中一个达到了A或者B的表尾 算法结束。
以下是参考程序:
//----------------------------------------
#include <stdio.h>
int A[100001],B[100001];
int Ans[100001],Count,N,M;
void Swap(int &a,int &b)
{
int Temp=a;
a=b;
b=Temp;
}
void Sort(int L,int R,int A[])
{
int p,q,Mid;
if (L==R) return ;
Mid=A[(L+R)/2];
p=L-1;q=R+1;
do
{
p++;q--;
while (A[p]<Mid) p++;
while (A[q]>Mid) q--;
if (p<q) Swap(A[p],A[q]);
}while (p<q);
Sort(L,q,A);
Sort(q+1,R,A);
}
void Init()
{
int p,q;
p=q=1;
for (int i=2;i<=N;i++)
{
if (A[i]!=A[p])
{
p++;
A[p]=A[i];
}
}
for (int i=2;i<=M;i++)
{
if (A[i]!=B[q])
{
q++;
B[q]=A[i];
}
}
}
int main(void)
{
int p,q;
scanf("%d %d",&N,&M);//输入两个集合的元素的个数
for (int i=1;i<=N;i++)
scanf("%d",&A[i]);// 读取A集合
for (int i=1;i<=M;i++)
scanf("%d",&B[i]);//读取B集合
Sort(1,N,A);//A集合排序
Sort(1,M,B);//B集合排序
Init();//剔除同一集合的相同元素
p=q=1;
Count=0;
while (p<=N&&q<=M)//求解.
{
if (A[p]<B[q])
{
p++;
continue;
}
if (A[p]>B[q])
{
q++;
continue;
}
if (A[p]==B[q])
{
p++;q++;
Count++;
Ans[Count]=B[q-1];
continue;
}
}
for (int i=1;i<=Count;i++)
printf("%d ",Ans[i]);
return 0;
}