C程序设计(第五版) 第三章(1)数据的表现形式及其运算


一、顺序程序设计举例

【例3.1】有人用温度计测量出华氏法表示的温度(如64°F),今要求把它转换为以摄氏法表示的温度(如17.8°C)。
在这里插入图片描述
编写程序:有了N-S图,很容易用C语言表示,写出求此问题的C程序。

#include<stdio.h>
int main()
{
    float f, c;                         //定义f和c为单精度浮点型变量
    f = 64.0;                           //指定f的值
    c = (5.0/9) *(f-32);                //利用公式计算c的值
    printf("f = %f\nc = %f\n", f, c);   //输出f和c的值
    return 0;
}

运行结果

f = 64.000000
c = 17.777779

【例3.2】计算存款利息。有1000元要存一年。有三种方法:(1)活期,年利率为r1;(2)一年期定期,年利率r2;(3)存两次半年定期,年利率为r3。请分别计算出一年后按三种方法所得到的本息和。
在这里插入图片描述
编写程序

#include <stdio.h>
int main()
{
    float p0 = 1000, r1 = 0.0036, r2 = 0.0225, r3 = 0.0198, p1, p2, p3;     //定义变量
    p1 = p0 * (r1 + 1);                                                     //计算三种方式的本息和
    p2 = p0 * (r2 + 1);
    p3 = p0 * (r3 + 1);
    printf("p1 = %f\np2 = %f\np3 = %f\n",p1, p2, p3);                       //输出结果
    return 0;
}

运行结果

p1 = 1003.599976
p2 = 1022.500061
p3 = 1019.799927

二、数据的表现形式及其运算

2.1 常量和变量

在计算机高级语言中,数据有两种表现形式:常量和变量。

2.1.1 常量

在程序运行过程中,其值不能被改变的量称为常量。数值常量就是数学中的常数。
(1)整型常量。如1000,12345,0,-345等都是整型常量。

(2)实型常量。有两种表示形式:
①十进制小数形式,由数字和小数点组成。如123.456,0.345,0.0,12.0等。
②指数形式。如12.34e3,-346.87e-25,0.145E-25等。计算机输入输出无法表示上角或下角故规定用字母E或e表示以10为底的指数。E或e之前必须有数字,之后必须为整数(有待考证)。

(3)字符常量。有两种形式的字符串常量:
①普通字符。用单引号括起来的一个字符,如’a’,‘b’,‘3’,‘?’。单引号只是界限符,字符常量只能是一个字符,不包括单引号。‘a’与‘A’是不同的字符。字符常量存储在计算机单元里并不是存储字符本身,而是以ASCII码的形式存储。例如‘a’的ASCII码是97,故存储单元存放的就是97(以二进制的形式存放)。
②转义字符。以字符“\”开头的字符序列。例如’\n’代表换行符。‘\t’代表输出的位置跳到下一个Tab位置(制表位置),一个Tab位置为8列。这是一种在屏幕上无法显示的控制字符,在程序中也无法用一般形式的字符来表示,只能采取转义字符这种特殊形式。常用的以’'开头的转义字符见表3.1。
在这里插入图片描述
转义字符意思是将“\”后面的字符转换成另外的意义。如“\n”中的“n”不代表字母n而作为换行符。

(4)字符串常量。如“boy”,"123"等用双引号把若干字符括起来,字符串常量是双引号中的全部字符但不包括双引号。单引号只能包含一个字符表示字符常量。

(5)符号常量。用#define 指令,指定用一个符号名称代表一个常量。如:

#define PI 3.1416		//注意行末没有分号

经过以上的指定后,本文件中从此行开始所有的PI都代表3.1416。对程序进行编译前,预处理器先对PI进行处理,把所有PI全部置换为3.1416。这种用一个符号名代表一个常量的,称为符号常量。在预编译后,所有符号常量都变成字面常量/直接常量。使用符号常量有以下好处:
①含义清楚,见名知义。
②可以同时改变程序中多处用到的同一个常量。
注意:符号常量不是变量。符号常量不占内存,只是一个临时符号代表一个值,预编译后这个符号就不存在了,故不能对符号常量赋新值。为与变量区分,符号常量常用大写表示,如PI,PRICE等。

2.1.2 变量

变量代表一个有名字的、具有特定属性的一个存储单元。它用来存放数据,也就是存放变量的值。在程序运行期间,变量的值是可以改变的。

变量必须先定义后使用。在定义时指定该变量的名字和类型。名字便于引用。变量值是存储的数据,变量名是名字代表的存储地址。在对程序编译连接时由编译系统给每一个变量名分配对应的内存地址。从变量中取值,实际上是通过变量名找到相应的内存地址,从该存储单元中读取数据。

2.1.3 常变量

C99允许使用常变量,方法是在定义变量时,在前面加一个关键字const。如:

const int a = 3;

定义a为一个整型变量,其值为3,而且在变量存在期间其值不能改变。常变量与常量的异同是:常变量有变量的基本属性:有类型占存储空间只是不允许改变其值;常变量是有名字的不变量,而常量是没有名字的不变量。有名字就便于在程序中被引用。

那符号常量和常变量有什么不同呢?

#define pi 3.1415926		//定义符号常量
const float pi = 3.1415926	//定义常变量

符号常量pi和常变量pi都代表3.1415926。但二者性质不同:符号常量是预编译指令,在预编译时仅进行字符替换,预编译之后符号常量就不存在了,所以是不分配存储空间的;而变常量是要占用存储单元的,有变量值但是值不改变。从使用角度常变量有符号常量的优点,而且使用方便。

2.1.4 标识符

在计算机高级语言中,用来对变量、符号常量名、函数、数组、类型等命名的有效字符序列统称标识符(identifier)。简单来说,标识符就是一个对象的名字。前面用到的变量名p1,p2,c,f,符号常量名PI,PRICE,函数名printf都是标识符。

C语言规定标识符只能由字母、数字和下划线3种字符组成,且第一个字符必须是字母或者下划线。且C语言区分大小写。用户自定义标识符不能与关键字(if)和预定义标识符(printf)相同。


2.2 数据类型

C语言要求定义所有变量时都要指定变量的类型。常量也是区分类型的。用计算机进行的计算不是抽象的理论值的计算,而是用工程的方法实现计算,在许多情况下只能得到近似的结果。

所谓类型就是对数据分配存储单元的安排,包括存储单元的长度(占多少字节)以及数据的存储形式。不同的类型分配不同的长度和存储形式。C语言允许使用的类型如图3.4,图中带有*的是C99所增加的。
在这里插入图片描述
其中基本类型(包括整型和浮点型)和枚举类型的变量都是数值,统称为算术类型。算术类型和指针类型统称为纯量类型,因为其变量的值都是以数字表示的。枚举类型是用户定义的整数类型。数组类型和结构体类型统称为组合类型,共用体不属于组合类型,因为在同一时间内只有一个成员具有值。函数类型用来定义函数,描述函数的接口返回值的数据类型和参数类型。

不同类型的数据在内存中占用的存储单元长度是不同的。


2.3 整型数据

2.3.1 整型数据的分类

(1)基本整型(int型)
编译系统分配给int型数据2个或4个字节。在存储单元中的存储方式是:用整数的补码(complement)形式存放。一个正数的补码正是此数二进制形式,如5的二进制形式是101,如果用两个字节存放,如图3.5;如果是一个负数,则应先求出负数的补码:想写出绝对值二进制形式,然后对其按位取反,再加1,如图3.6。
在这里插入图片描述
在存放整数的存储单元中,最左面的一位是用来表示符号的,0为正,1为负。所以表示范围:0000 0000 0000 0001 到 0111 1111 1111 1111为+1 ~ +32767;1000 0000 0000 0000 到1111 1111 1111 1111为-32768 ~ -1。0000 0000 0000 0000是0。故总范围是-32768 ~ 32767。4个字节的话是-2 ^31 ~ (2 ^31 -1)。

(2)短整型(short int)
类型名为short int或short。一般存储单位为整型的一般。存储方式与整型相同。

(3)长整型(long int)
类型名为long int 或 long。一般分配4个字节。取值范围是-2 ^31 ~ (2 ^31 -1)。

(4)双长整型(long long int)
类型名为long long int 或 long long,一般分配8个字节。C99新增,有些编译系统未实现。

C标准没有具体规定各种数据类型所占用的存储单元的长度,这是由各个编译系统自行决定的。C标准只要求long型数据长度不短于int型,short型不长于int型。即

//sizeof(short)<=sizeof(int)<=sizeof(long)<=sizeof(long long)

2.3.2 整型变量的符号属性

以上这些类型在存储单元中都是以补码的形式存储的,存储单元的第一个二进制位代表符号。整型变量的范围包括负数到正数。(见表3.2)

在这里插入图片描述
在实际应用中,有的数据的范围常常是只有正值。为了充分利用变量的值,可以将变量定义为无符号正数类型,在类型符号前加上修饰符unsigned,表示指定该变量为无符号整数类型。如果加上修饰符signed,则是有符号类型。因此以上四种整型数据可以扩展为8中整型数据。
在这里插入图片描述
说明
(1)只有整型(包括字符型)数据可以加signed或unsigned修饰符,实型数据不能加。
(2)对无符号整型数据用“%u”格式输出。


2.4 字符型数据

由于字符是按其代码(整数)形式存储的,因此C99把字符型数据作为整数类型的一种。但是字符型数据在使用上也有自己的特点。

2.4.1 字符与字符代码

字符和字符代码并不是任意写一个字符程序都能识别,例如圆周率π在程序中就不能识别,只能使用系统字符集中的字符,目前大多是系统都采用ASCII字符集。各种字符集都基本包括了127个字符。其中包括:

  • 字母:A ~ Z ,a ~ b
  • 数字:0 ~ 9
  • 专门符号:!#*[]<>~等 29个
  • 空格符:空格、水平制表符(tab)、换行、换页
  • 不能显示的字符:空字符(‘\0’)、警告(‘\a’)、退格(‘\b’)、回车(‘\r’)等。

字符是以整数形式(ASCII代码)存放在内存单元中的。如图所示。
在这里插入图片描述
ASCII码是7位或8位二进制表示,所以在C语言中指定一个字节(8位)存储一个字符(所有系统都不例外)。如小写字母‘a’在内存中的存储情况见图3.9。
在这里插入图片描述
字符‘1’按ASCII码形式存储,占一个字节;而整数1是以整数存储方式(二进制补码)存储,占二或四个字节。

2.4.2 字符变量

字符变量用类型符char定义字符变量。char 是character字符的缩写。

char c = '?';

定义c为字符型常量并使初值为字符‘?’。?的ASCII代码是63,系统将整数63赋给变量c。
c是字符变量,实质上是一个字节的整型变量,由于它用来存放字符,所以成为字符变量。在输出字符变量时,可以选择十进制整数形式输出,或以字符形式输出,如:

printf("%d %c", c, c)

输出结果是

63 ?

即用%d格式输出十进制整数,用%c格式输出字符。字符类型也属于整型,也可以用unsigned,signed修饰。存储空间和范围见表3.3。
在这里插入图片描述
在使用有符号字符型变量时,允许存储的值为-128 ~ 127,但是字符的代码不可能为负值,所以在存储字符时只用到0 ~ 127这一部分,其第一位都是0。


2.5 浮点型数据

浮点型数据是用来表示具有小数点的实数的。为什么称为浮点数呢?在C语言中,实数是以指数形式存放在存储单元的。一个实数表示为指数可以有不止一种形式,如3.14159×10 ^0, 0.314159×10 ^1, 0.0314159×10 ^2等,它们代表同一个值。可以看出,小数点的位置在314159几个数字之间浮动,只要小数点浮动的同时改变指数的值,就可以保证它的值不会改变。由于小数点的位置可以浮动,所以实数的指数形式称为浮点数。

浮点数类型包括float(单精度浮点型)、double(双精度浮点型)、long double(长双精度浮点型)。

(1)float(单精度浮点型)。编译系统为每一个float型变量分配4个字节,数值以规范化的二进制指数形式存放在存储单元中。分为小数部分和指数部分分别存放。小数部分前面的数是0。如3.14159存放如图3.11所示。
在这里插入图片描述
图中使用十进制数示意的,实际上计算机中用二进制数来表示小数部分以及用2的幂次来表示指数部分的。4个字节的空间分别用多少位来表示小数部分和指数部分,C标准没有规定,由C语言编译系统自定。由于是用二进制,且长度有限,故不可能得到完全精确的值,只能存储成有限的精确度。小数部分数值范围越多,数的有效位数就越多,精度也就越高。指数部分位数越多,表示数的范围就越大。float型数据能得到6位有效数字,数值范围-3.4×10^ -38 ~ 3.4×10 ^38。

(2)double(双精度浮点型)
为了扩大能表示的数值范围,用8个字节存储一个double型数据,可得到15位有效数字,数值范围-1.7×10^ -308 ~ 1.7×10 ^308。为了提高运算精度,C语言进行浮点数算术运算时,将float型数据都自动转换为double型,然后进行运算。

(3)long double(长双精度浮点型)
不同编译系统对long double 型的数据处理方法不同,Turbo C分配16个字节。Visual C++分配8个字节。
在这里插入图片描述
在这里插入图片描述


2.6 怎样确定常量的类型

整型常量。不带小数点的数值是整型常量,但要注意有效范围。123L,123l,在整数末尾加上字母表示长整型。
浮点型常量。凡以小数形式或指数形式出现的实数均是浮点型常量,在内存中都以指数形式存储。10是整型,10.0是浮点型。C编译系统把浮点型常量都按双精度处理,分配8个字节。
如果有:

float a = 3.14159;

则在编译时会发出警告:warning:truncation from ‘const double’ to ‘float’。意为把一个双精度常量转换为单精度事务警告。可以在常量末尾加专用字符,强调常量类型。

float a = 3.14159f;
long double = 3.14159L;

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
C#版本数据结构,用C#的同志们有福啦 本书节选: 第1章 绪论 数据是外部世界信息的计算机化,是计算机加工处理的对象。运用计算机处 理数据时,必须解决四个方面的问题:一是如何在计算机中方便、高效地表示和 组织数据;二是如何在计算机存储器(内存和外存)中存储数据;三是如何对存 储在计算机中的数据进行操作,可以有哪些操作,如何实现这些操作以及如何对 同一问题的不同操作方法进行评价;四是必须理解每种数据结构的性能特征,以 便选择一个适合于某个特定问题的数据结构。这些问题就是数据结构这门课程所 要研究的主要问题。本章首先说明学习数据结构的必要性和本书的目的,然后解 释数据结构及其有关概念,接着讨论算法的相关知识,最后简单介绍本书所要用 到的相关数学知识和C#知识。 1.1 数据结构 1.1.1 学习数据结构的必要性 我们知道,虽然每个人都懂得英语的语法与基本类型,但是对于同样的题目, 每个人写出的作文,水平却高低不一。程序设计也和写英语作文一样,虽然程序 员都懂得语言的语法与语义,但是对于同样的问题,程序员写出来的程序不一样。 有的人写出来的程序效率很高,有的人却用复杂的方法来解决一个简单的问题。 当然,程序设计水平的提高仅仅靠看几本程序设计书是不行的。只有多思索、 多练习,才能提高自己的程序设计水平;否则,书看得再多,提高也不大。记得 刚学程序设计时,常听人说程序设计水平要想提高,最重要的是多看别人写的程 序,多去思考问题。从别人写的程序中,我们可以发现效率更高的解决方法;从 思考问题的过程中,我们可以了解解决问题的方法常常不只一个。运用先前解决 问题的经验,来解决更复杂更深入的问题,是提高程序设计水平的最有效途径。 数据结构正是前人在思索问题的过程中所想出的解决方法。一般而言,在学 习程序设计一段时间后,学习“数据结构”便能让你的程序设计水平上一个台阶。 如果只学会了程序设计的语法和语义,那么你只能解决程序设计三分之一的问 题,而且运用的方法并不是最有效的。但如果学会了数据结构的概念,就能在程 序设计上,运用最有效的方法来解决绝大多数的问题。 《数据结构》这门课程的目的有三个。第一个是讲授常用的数据结构,这些 数据结构形成了程序员基本数据结构工具箱(toolkit)。对于许多常见的问题,工 具箱里的数据结构是理想的选择。就像.NET Framework 中Windows应用程序开 发中的工具箱,程序员可以直接拿来或经过少许的修改就可以使用,非常方便。 第二个是讲授常用的算法,这和数据结构一样,是人们在长期实践过程中的总结, 程序员可以直接拿来或经过少许的修改就可以使用。可以通过算法训练来提高程 序设计水平。第三个目的是通过程序设计的技能训练促进程序员综合能力的提 高。 1.1.2 基本概念和术语 在本小节中,将对一些常用的概念和术语进行介绍,这些概念和术语在以后 的章节中会多次出现。 1、数据(Data) 数据是外部世界信息的载体,它能够被计算机识别、存储和加工处理,是计 算机程序加工的原料。计算机程序处理各种各样的数据,可以是数值数据,如整 数、实数或复数;也可以是非数值数据,如字符、文字、图形、图像、声音等。 2、数据元素(Data Element)和数据项(Data Item) 数据结构(C#语言版) 1.1 数据结构2 数据元素是数据的基本单位,在计算机程序中通常被作为一个整体进行考虑 和处理。数据元素有时也被称为元素、结点、顶点、记录等。一个数据元素可由 若干个数据项(Data Item)组成。数据项是不可分割的、含有独立意义的最小数据 单位,数据项有时也称为字段(Field)或域(Domain)。例如,在数据库信息处理系 统中,数据表中的一条记录就是一个数据元素。这条记录中的学生学号、姓名、 性别、籍贯、出生年月、成绩等字段就是数据项。数据项分为两种,一种叫做初 等项,如学生的性别、籍贯等,在处理时不能再进行分割;另一种叫做组合项, 如学生的成绩,它可以再分为数学、物理、化学等更小的项。 3、数据对象(Data Object) 数据对象是性质相同的数据元素的集合,是数据的一个子集。例如,整数数 据对象是{0,±1,±2,±3,…},字符数据对象是{a,b,c,…}。 4、数据类型(Data Type) 数据类型是高级程序设计语言中的概念,是数据的取值范围和对数据进行操 作的总和。数据类型规定了程序中对象的特性。程序中的每个变量、常量或表达 式的结果都应该属于某种确定的数据类型。例如,C#语言中的字符类型(String, 经常写为string)。一 个String表示一个恒定不变的字符序列集合,所有的字符序 列集合构成String的取值范围。我们可以对String进行求长度、复制、连接两个 字符串等操作。 数据类型可分为两类:一类是非结构的原子类型,如C#语言中的基本类型整型、实型、字符型等);另一类是结构类型,它的成分可以由多个结构类型 组成,并可以分解。结构类型的成分可以是非结构的,也可以是结构的。例如, C#语言中数组的成分可以是整型等基本类型,也可以是数组等结构类型。 5、数据结构(Data Structure) 数据结构是相互之间存在一种或多种特定关系的数据元素的集合。在任何问 题中,数据元素之间都不是孤立的,而是存在着一定的关系,这种关系称为结构 (Structure)。根据数据元素之间关系的不同特性,通常有4类基本数据结构: (1) 集合(Set):如图1.1(a)所示,该结构中的数据元素除了存在“同属于一个集 合”的关系外,不存在任何其它关系。 (2) 线性结构(Linear Structure):如图1.1(b)所示,该结构中的数据元素存在着一 对一的关系。 (3) 树形结构(Tree Structure):如图1.1(c)所示,该结构中的数据元素存在着一对 多的关系。 (4) 图状结构(Graphic Structure):如图1.1(d)所示,该结构中的数据元素存在着 多对多的关系。 (a) 集合 (b) 线性结构 (c) 树形结构 (d)图状结构 图 1.1 4 类基本数据结构关系图 由于集合中的元素的关系极为松散,可用其它数据结构来表示,所以本书不 做专门介绍。关于集合的概念在1.3.1小节中有介绍。 数据结构的形式化定义为: 数据结构(C#语言版) 1.1 数据结构3 数据结构(Data Structure)简记为DS,是一个二元组, DS = (D,R) 其中:D是数据元素的有限集合, R是数据元素之间关系的有限集合。 下面通过例题来进一步理解后3类数据结构。 【例1-1】 学生信息表(如表1.1所示.)是一个线性的数据结构,表中的每 一行是一个记录(在数据库信息处理系统中,表中的一个数据元素称为一个记 录)。一条记录由学号、姓名、行政班级、性别和出生年月等数据项组成。表中 数据元素之间的关系是一对一的关系。 表 1.1 学生信息表 学号 姓名 行政班级 性别 出生年月 040303001 雷洪 软件04103 男 1986.12 040303002 李春 软件04103 女 1987.3 040303003 周刚 软件04103 男 1986.9 【例1-2】 家族关系是典型的树形结构,图1.2是一个三代的家族关系。在 图中,爷爷、儿子、女儿、孙子、孙女或外孙女是一个结点(在树形结构中,数 据元素称为结点),他们之间是一对多的关系。其中,爷爷有两个儿子和一个女 儿,这是一对三的关系;一个儿子有两个儿子(爷爷的孙子),这是一对二的关 系;另一个儿子有一个儿子(爷爷的孙子)和一个女儿(爷爷的孙女),这是一 对二的关系;女儿有三个女儿(爷爷的外孙女),这是一对三的关系。树形结构 具有严格的层次关系,爷爷在树形结构的最上层,中间层是儿子和女儿,最下层 是孙子、孙女和外孙女。不能把这种关系倒过来,因为绝对不会先有儿子或女儿 再有爷爷,也不会先有孙子或孙女再有儿子、先有外孙女再有女儿。 外孙女 爷爷 儿子 儿子 女儿 孙子 孙子 孙子 孙女 外孙女 外孙女 图 1.2 家族关系图 【例1-3】 图1.3是四个城市的公路交通图,这是一个典型的图状结构。在 图中,每个城市是一个顶点(在图状结构中,数据元素称为顶点),它们之间是 多对多的关系。成都与都江堰、雅安直接通公路,都江堰与成都、青城山直接通 公路,青城山与都江堰、成都及雅安直接通公路,雅安与成都、青城山直接通公 路。这些公路构成了一个公路交通网,所以,又把图状结构称为网状结构(Network Structure) 数据结构(C#语言版) 1.2 算法4 成都 都江堰 青城山 雅安 图 1.3 四城市交通图 从数据类型数据结构的概念可知,二者的关系非常密切。数据类型可以看 作是简单的数据结构。数据的取值范围可以看作是数据元素的有限集合,而对数 据进行操作的集合可以看作是数据元素之间关系的集合。 数据结构包括数据的逻辑结构和物理结构。上述数据结构的定义就是数据的 逻辑结构(Logic Structure),数据的逻辑结构是从具体问题抽象出来的数学模型, 是为了讨论问题的方便,与数据计算机中的具体存储没有关系。然而,我们讨 论数据结构的目的是为了在计算机中实现对它的操作,因此还需要研究在计算机 中如何表示和存储数据结构,即数据的物理结构(Physical Structure)。数据的物理 结构又称为存储结构(Storage Structure),是数据计算机中的表示(又叫映像) 和存储,包括数据元素的表示和存储以及数据元素之间关系的表示和存储。 数据的存储结构包括顺序存储结构和链式存储结构两种。顺序存储结构 (Sequence Storage Structure)是通过数据元素在计算机存储器中的相对位置来表 示出数据元素的逻辑关系,一般把逻辑上相邻的数据元素存储在物理位置相邻的 存储单元中。在C#语言中用数组来实现顺序存储结构。因为数组所分配的存储 空间是连续的,所以数组天生就具有实现数据顺序存储结构的能力。链式存储结 构(Linked Storage Structure)对逻辑上相邻的数据元素不要求其存储位置必须相 邻。链式存储结构中的数据元素称为结点(Node),在结点中附设地址域(Address Domain)来存储与该结点相邻的结点的地址来实现结点间的逻辑关系。这个地址 称为引用(Reference),这个地址域称为引用域(Reference Domain)。 从20世纪60年代末到70年代初,出现了大型程序,软件也相对独立,人 们越来越重视数据结构,认为程序设计的实质是确定数据结构,加上设计一个好 的算法,这就是人们常说的“程序=数据结构+算法”。下一节谈谈算法的问题。 1.2 算法 从上节我们知道,算法与数据结构和程序的关系非常密切。进行程序设计时, 先确定相应的数据结构,然后再根据数据结构和问题的需要设计相应的算法。由 于篇幅所限,下面只从算法的特性、算法的评价标准和算法的时间复杂度等三个 方面进行介绍。 1.2.1 算法的特性 算法(Algorithm)是对某一特定类型的问题的求解步骤的一种描述,是指令的 有限序列。其中的每条指令表示一个或多个操作。一个算法应该具备以下5个特 性: 1、有穷性(Finity):一个算法总是在执行有穷步之后结束,即算法的执行时间是 有限的。 2、确定性(Unambiguousness):算法的每一个步骤都必须有确切的含义,即无二 义,并且对于相同的输入只能有相同的输出。 3、输入(Input):一个算法具有零个或多个输入。它即是在算法开始之前给出的 数据结构(C#语言版) 1.2 算法5 量。这些输入是某数据结构中的数据对象。 4、 输出(Output):一个算法具有一个或多个输出,并且这些输出与输入之间存 在着某种特定的关系。 5、 能行性(realizability):算法中的每一步都可以通过已经实现的基本运算的有 限次运行来实现。 算法的含义与程序非常相似,但二者有区别。一个程序不一定满足有穷性。 例如操作系统,只要整个系统不遭破坏,它将永远不会停止。还有,一个程序只 能用计算语言来描述,也就是说,程序中的指令必须是机器可执行的,而算法 不一定用计算语言来描述,自然语言、框图、伪代码都可以描述算法。 在本书中我们尽可能采用C#语言来描述和实现算法,使读者能够阅读或上 机执行,以便更好地理解算法。 1.2.2 算法的评价标准 对于一个特定的问题,采用的数据结构不同,其设计的算法一般也不同,即 使在同一种数据结构下,也可以采用不同的算法。那么,对于解决同一问题的不 同算法,选择哪一种算法比较合适,以及如何对现有的算法进行改进,从而设计 出更适合于数据结构的算法,这就是算法评价的问题。评价一个算法优劣的主要 标准如下: 1、正确性(Correctness)。算法的执行结果应当满足预先规定的功能和性能的要求, 这是评价一个算法的最重要也是最基本的标准。算法的正确性还包括对于输入、 输出处理的明确而无歧义的描述。 2、可读性(Readability)。算法主要是为了人阅读和交流,其次才是机器的执行。 所以,一个算法应当思路清晰、层次分明、简单明了、易读易懂。即使算法已转 变成机器可执行的程序,也需要考虑人能较好地阅读理解。同时,一个可读性强 的算法也有助于对算法中隐藏错误的排除和算法的移植。 3、健壮性(Robustness)。一个算法应该具有很强的容错能力,当输入不合法的数 据时,算法应当能做适当的处理,使得不至于引起严重的后果。健壮性要求表明 算法要全面细致地考虑所有可能出现的边界情况和异常情况,并对这些边界情况 和异常情况做出妥善的处理,尽可能使算法没有意外的情况发生。 4、运行时间(Running Time)。运行时间是指算法在计算机上运行所花费的时间, 它等于算法中每条语句执行时间的总和。对于同一个问题如果有多个算法可供选 择,应尽可能选择执行时间短的算法。一般来说,执行时间越短,性能越好。 5、占用空间(Storage Space)。占用空间是指算法在计算机上存储所占用的存储空 间,包括存储算法本身所占用的存储空间、算法的输入及输出数据所占用的存储 空间和算法在运行过程中临时占用的存储空间。算法占用的存储空间是指算法执 行过程中所需要的最大存储空间,对于一个问题如果有多个算法可供选择,应尽 可能选择存储量需求低的算法。实际上,算法的时间效率和空间效率经常是一对 矛盾,相互抵触。我们要根据问题的实际需要进行灵活的处理,有时需要牺牲空 间来换取时间,有时需要牺牲时间来换取空间。 通常把算法在运行过程中临时占用的存储空间的大小叫算法的空间复杂度 (Space Complexity)。算法的空间复杂度比较容易计算,它主要包括局部变量所占 用的存储空间和系统为实现递归所使用的堆栈占用的存储空间。 如果算法是用计算语言来描述的,还要看程序代码量的大小。对于同一个 问题,在用上面5条标准评价的结果相同的情况下,代码量越少越好。实际上, 代码量越大,占用的存储空间会越多,程序的运行时间也可能越长,出错的可能 数据结构(C#语言版) 1.2 算法6 性也越大,阅读起来也越麻烦。 在以上标准中,本书主要考虑程序的运行时间,也考虑执行程序所占用的空 间。影响程序运行时间的因素很多,包括算法本身、输入的数据以及运行程序的 计算机系统等。计算机的性能由以下因素决定: 1、硬件条件。包括所使用的处理器的类型和速度(比如,使用双核处理器还是 单核处理器)、可使用的内存(缓存和RAM)以及可使用的外存等。 2、实现算法所使用的计算语言。实现算法的语言级别越高,其执行效率相对 越低。 3、所使用的语言的编译器/解释器。一般而言,编译的执行效率高于解释,但解 释具有更大的灵活性。 4、所使用的操作系统软件。操作系统的功能主要是管理计算机系统的软件和硬 件资源,为计算机用户方便使用计算机提供一个接口。各种语言处理程序如编译 程序、解释程序等和应用程序都在操作系统的控制下运行。 1.2.3 算法的时间复杂度 一个算法的时间复杂度(Time Complexity)是指该算法的运行时间与问题规 模的对应关系。一个算法是由控制结构和原操作构成的,其执行的时间取决于二 者的综合效果。为了便于比较同一问题的不同算法,通常把算法中基本操作重复 执行的次数(频度)作为算法的时间复杂度。算法中的基本操作一般是指算法中 最深层循环内的语句,因此,算法中基本操作语句的频度是问题规模n的某个函 数f(n),记作:T(n)=O(f(n))。其中“O”表示随问题规模n的增大,算法执行时 间的增长率和f(n)的增长率相同,或者说,用“O”符号表示数量级的概念。例 如,如 )1n(n 2 1 )n(T −= ,则 )1n(n 2 1 −的数量级与n2 相同,所以T(n)=O(n2 )。
内容简介编辑 本书采用通俗的语言和形象化的方法来表达概念和定理,逻辑严谨、思维缜密,可作为高等院校计算机及相关专业“形式语言与自动机”课程的教材。 [1] 作者简介编辑 陈有祺,南开大学信息技术科学学院教授,多年来一直从事计算机软件方面的教学和研究工作,从1993年起享受国务院政府特殊津贴。讲授的课程主要有程序设计语言.编译原理,数据结构、形式语言与自动机等,研究领域包括编译理论、人工智能、自然语言理解,形式语言等。1980年至1982年在美国西密歇根大学作访问学者,研修人工智能和形式语言,回国后一直为研究生讲授“形式语言与自动机”课程。相关著作包括:《BCLR(k)文法及其分析算法》、《广义上下文无关文法和它的语法分析》、《从输入输出序列确定自动机的结构》,《形式语言与自动机》等。 编辑推荐编辑 本书以四类形式语言(短语结构语言,上下文有关语言。上下文无关语言。正则语言)和四种自动机(有穷自动机、下推自动机.图灵机,线性有界自动机)为主线,讨论了形式语言与自动机方面的主要理论成果和应用实例。 本书的主要特色: 取材丰富。涵盖了该领域国内外现有教材的主要内容。 在写作方法上,循序渐进,深入浅出。在概念的引入和定理的证明上,尽量采用通俗的语言和形象化的方法来表达。 理论与实际相结合。除具有配合定理和定义的大量例题外,许多章节还有现代计算机技术中应用的实例。 适应面广。既适合作为本科生的教材,也适合作为研究生的教材。 图书目录编辑 出版者的话 序言 前言 教学建议 第1章 预备知识 1.1 定理及其证明方法 1.1.1 演绎法 1.1.2 反证法 1.1.3 归纳法 1.2 集合及其基本运算 1.2.1 集合基础知识 1.2.2 集合的基本运算 1.2.3 关系与映射 1.3 图和树简介 1.3.1图的基本概念 1.3.2图的矩阵表示 1.3.3 树的基本知识 1.4 字母表、字符串和语言 习题 第2章 文法的一般理论 2.1 问题的提出 2.2 形式文法与形式语言 2.3 文法的乔姆斯基分类 习题 第3章 有穷自动机 3.1 非形式化描述 3.2 有穷自动机的基本定义 3.3 非确定的有穷自动机 3.4 具有£转移的有穷自动机 3.5 有穷自动机的应用 3.5.1 在文本中查找字符串 3.5.2 用于文本搜索的非确定的有穷自动机 3.5.3 识别关键字集合的DFA 3.6 具有输出的有穷自动机 习题 第4章 正则表达式 4.1 正则表达式的定义 4.2 正则表达式和有穷自动机的关系 4.3则表达式的等价变换 4.3.1 交换律与结合律 4.3.2 单位元与零元 4.3.3 分配律 4.3.4 与“*”构造有关的定律 4.3.5 发现正则表达式定律的一般方法 4.4 正则表达式的应用 4.4.1UNIX中的正则表达式 4.4.2 词法分析 4.4.3 查找文本中的模式 习题 第5章正则语言的性质 5.1 正则文法和有穷自动机的关系 5.2 正则语言的泵引理 5.3 正则语言的封闭性 5.4 正则语言的判定算法 5.5 有穷自动机的最小化 习题 第6章 上下文无关文法 6.1上下文无关文法的语法分析 6.2 上下文无关文法的化简 6.3 上下文无关文法的范式 6.4 上下文无关文法的应用 6.4.1 用上下文无关文法描述语言 6.4.2 语法分析器生成工具YACC …… 第7章 下推自动机 第8章 上下文无关语言的性质 第9章 图灵机导引 第10章 不可判定性 第11章 线性有界自动机和上下文有关文法 第12章 确定的上下文无关语言和LR(k)文法 参考文献 …… 参考资料

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

正在輸入......

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值