精华内容
下载资源
问答
  • 信息分类编码

    千次阅读 2013-03-05 09:16:28
    信息分类编码(Information Classifying and Coding)是标准化的一个领域,已发展成了一门学科,自身的研究对象、研究内容和研究方法。在现代社会中,信息分类和编码是提高劳动生产率和科学管理水平的重要方法...

    信息分类编码   

    信息分类编码(Information Classifying and Coding)是标准化的一个领域,已发展成了一门学科,有自身的研究对象、研究内容和研究方法。在现代社会中,信息分类和编码是提高劳动生产率和科学管理水平的重要方法。美国新兴管理学的开创者莫里斯L· 库克(Morris L· Cooker)说:"只有当我们学会了分类和编码,做好简化和标准化工作,才会出现任何真正的科学的管理"。在信息化时代,信息的标准化工作越来越重要,没有标准化就没有信息化,信息分类编码标准是信息标准中的最基础的标准。

    信息分类就是根据信息内容的属性或特征,将信息按一定的原则和方法进行区分和归类,并建立起一定的分类系统和排列顺序,以便管理和使用信息。信息编码就是在信息分类的基础上,将信息对象(编码对象)赋于有一定规律性的、易于计算机和人识别与处理的符号。具有分类编码意义的数据元素是最重要的一类数据元素。应遵照《国家经济信息系统设计与应用标准化规范》和《标准化工作导则:信息分类编码编制的基本原理和方法》(国家标准GB7026-86)关于信息分类编码的规定,按照"国际/国家标准—行业标准—企业标准"的顺序原则,引用或建立企业的信息分类编码标准。

    在信息比较单纯、分类很少的情况下,没有编码也许无关紧要,但在基础数据量日益增大、分类烦多时,信息编码工作就显得格外重要了。此时,基础数据的业务处理流程极为频紧,而凭借对信息的编码,能使各部门提高效率,各种资料传递迅速、意见沟通更加容易。

    中国石油近年将信息化工作作为重点建设的领域,根据业务需要陆续为各个单位上马了财务系统、零售管理系统、购销存系统,正在考虑的还有成品油物流配送系统、调运管理系统、营销系统、客户关系管理系统等,如果没有规定统一的基础信息编码,在以后的系统整合时将面临巨大的困难,使用统一的基础编码能够达到:

    Ø          增强资料的正确性

    在中国石油的成品油运销过程中油品的申请、调运、入库、化验、结帐、盘点、出库、移库、批发等一切活动均可以有编码可以查核,因此数据更加正确。至于一物多名,一名多物或物名错乱之现象不致于发生。

    Ø          提高管理工作效率

    以信息编码代替文字的记述,业务管理更加简便省事,效率因此提高。

    Ø          利于计算机的管理

    物料管理在信息编码推行彻底之后,方能进一步利用电脑作更有效的处理,以达到物料管理之效果。

    Ø          降低库存、降低成本

    编码有利于库存量的控制,同时利于呆帐的防止,并提高各级业务管理部门的工作效率,因此可减轻资金的积压,降低成本。

    Ø          防止舞弊事件之发生

    油品一经编码,进出帐记录正确而迅速,储存井然有序,可以减少舞弊事件之发生。

    Ø          便于设备领用

    库存物料均有正确的统一的名称及规格予以编码。对用料部门的领用以及物料仓库的发料都十分方便。

    Ø          便于压缩物料的品种、规格

    对物料进行编码时,可以对某些性能相近或者相同的物料进行统一、合并和简化,压缩物料的品种、规格。

    第1节                        信息编码的原则

    信息编码必须合乎编码的原则,合理的基础信息编码,必须具备下列基本原则:

    ²       简单性

    ²       分类展开性

    ²       完整性

    ²       单一性

    ²       一贯性

    ²       可伸缩性

    ²       组织性

    ²       适应电脑管理

    ²       充足性

    ²       易记性

    一、       简单性

    编码的目的在于化繁为简,便于管理,如果编码过于繁杂,则违反了编码之目的。因此信息编码在应用文字元号或数字上应力求简单明了,这样可节省阅读、填写、抄录的时间与手续,并可减少其中的错误机会。

    物料相当单纯时,只要将物料简单分类为几项即可,物料分类项目多了,就显得很不方便。若物料相当复杂时,就要将大分类再加以细分,这种分类展开也称为多级分类。

    二、      分类展开性

    物料复杂,信息编码大分类后还要加以细分,如果采用阿拉伯数字十进制,则每段最多只能由十个细分的项目,如果采用英文字母,则每段有26个细分项目,然而细分项目太多,就难于查找,而细分项目太少,则分类展开太慢,分类细分项目通常以五至九个较佳。例如采用阿拉伯数字十进制,有十八个项目时,其分类展开可以利用下列方法。

    需要分类的

    项目

    第一种分类方法

    第二类分类方法

    第三类分类方法

    1

    1

    11

    0

    01

    01

    2

    12

    02

    02

    3

    13

    03

    03

    4

    14

    1

    1

    04

    5

    15

    2

    21

    05

    6

    16

    22

    06

    7

    2

    21

    23

    07

    8

    22

    3

    3

    08

    9

    23

    4

    41

    09

    10

    24

    42

    10

    11

    25

    43

    11

    12

    26

    5

    5

    12

    13

    3

    31

    6

    61

    13

    14

    32

    62

    14

    15

    33

    63

    15

    16

    34

    7

    7

    16

    17

    35

    8

    8

    17

    18

    36

    9

    9

    18

    (表一)

    三、      完整性

    在信息编码时,所有的物料都应有信息编码可归,这样信息编码才能完整。若有些物料找不到赋予之信息编码,则很显然信息编码缺乏完整性。

    新产品新物料的产生容易破坏信息编码的完整性。因此每当有新物料产生,即应赋予新的信息编码,并规定新的物料没有编码,采购部门不得从事采购,即使没信息编码的新物料采购进来了,仓库部门或会计部门发现物料订购单缺少信息编码,即应请采购部门补填信息编码,否则不予入库、不予付款。这样才能确保信息编码的完整性。

    四、      单一性

    信息编码的单一性是指一个信息编码只能代表一种物料,同一种物料只能找到一个信息编码,而绝无一个物料有数个信息编码,或一个信息编码有数项物料,一般地,只要物料的物理或化学性质有变化、只要物料要在仓库中存储、就必须为其指定一个编码,举例,如某零件要经过冲压成型、钻孔、喷漆三道工序才能完成。如果该物料的三道工序都在同一车间完成,不更换加工单位,即冲压成型后立即进行钻孔,紧接着进行喷漆,中间没有入库、出库处理,则该物料可取一个代码。如果该物料的三道工序不在同一个车间完成,其顺序是冲压、入库、领料、钻孔、入库、领料、喷漆、入库,则在库存管理中为了区分该物料的三种状态,必须取不同的信息编码。例:3000A,3000B,3000C三个编码分别表示三种不同加工状态的物料。

    五、      一贯性

    信息编码要统一而有一贯性,如以年限分类为标准时,就应一直沿用下去,在中途不能改变用籍贯或姓氏别来分类,若要这么做必须要分段或分级进行。

    六、      伸缩性

    物料编编码要考虑到未来新产品发展以及产品规格的变更而发生物料扩展或变动的情形。预留物料的伸缩余地,并不能仅就目前物料的现状加以信息编码的安排,否则他日新物料产生时,就有新物料无号可编的情况。

    七、      组织性

    信息编码依其编码的系统,作井然有序的组织与排列,以便随时可从信息编码查知某项物料帐卡或数据。信息编码的组织性,对物料管理可以省掉不必要的麻烦。

    八、      适应电脑管理

    电脑的应用已经比较普及,因此在编码时一定要考虑录入的方便性,如编码尽可能短、少使用其它符号,如‘#'、‘-'、‘*'等。

    九、      充足性

    信息编码所采用的文字、记号或数字,必须有足够的数量,以便所组成的个别信息编码,足以代表所有个别物料,以及应付将来物料扩展时的实际需要,以免遇有特殊物料时无号可编。否则物料系统被破坏,费时误事。

    十、      易记性

    在不影响上述九项原则之下,信息编码应选择易于记忆的文字、符号或数字,或赋予暗示及联想性。但这原则是属于次要原则,若上述九项原则俱全而独缺乏此项原则的信息编码,仍不失为优秀的信息编码。

    第2节                        信息编码的方法

    目前工商企业所采用的物科编码方法,主要有下列几种:

    1)      阿拉伯数字法

    2)      英文字母法

    3)      暗示法

    4)      混合法

    一、      阿拉伯数字法

    阿拉伯数字法,是以阿拉伯数字作为信息编码的工具,采用以一个或数个阿拉伯数字代表一项物料。这种方法容易了解,只是需另外准备物料项目与数字的对照表,又要记忆对照项目,因此有关人员必须经过一段时间的训练与适应才能运用自如。以阿拉伯数字做信息编码的,较常见的有下列几种:

    ²       连续数字编码法

    ²       分级式数字编码法

    ²       区段数字编码法

    ²       国际十进制分类法

    1)      连续数字编码法

    连续数字编码法是先将所有物料依某种方式大致排列,然后自1号起依顺序编排流水号。这种信息编码方法可做到一料一号,只是顺序编码除显示编码时间的先后,往往与所代表项目的属性并无关联。因为新购物料无法插入原有排列顺序的料号内,例如: 1078为3/8"×3/4"之六角铁制带帽螺栓,而新购的六角铁制带帽螺栓为3/8" ×1",其信息编码无法插入(因过去没有库存或采用这种物料,故无编码),故只好编以最后一个号码8974。两种物料本应排在一起,现在信息编码相距如此遥远,在物料管理、仓储管理上很不方便。

    2)      分级式数字编码法

    分级式数字编码法是先将物料主要属性分为大类并编定其号码。其次再将各大类根据次要属性细分为较次级的类别并编定其号码,如此已继续进行下去。在分级式数字编码法中,任一物料项目只有一个信息编码。

    表二为三种属性的阶级式数字编码法,共可组成36个(3×4×3)编码,这种方法的优点一方面显示编码的规律性,一方面达到一物料项目仅有一编码的目标,其缺点是无用空号太多,一方面显得浪费累赘,另一方面常导致信息编码位数不够用。

    来    源

    (大类)

    材     料

    (中类)

    用     途

    (小类)

    1 = 自制

    1 = 非铁金属

    1 = 零部件

    2 = 外购

    2 = 钢铁

    2 = 包装用料

    3 = 委外加工

    3 = 木材

    3 = 办公用品

     

    4 = 化学品

     

    (表二)

    3)      区段数字编码法

    区段数字编码法介于连续数字编码法与分级式数字编码法之间。使用位数较级次式数字编码法更少,而仍能达到信息编码的目的。例如有64项,分为5大类,其情形如下:

    A类

    12项

    B类

    10项

    C类

    17项

    D类

    15项

    E类

    10项

    合计

    64项

    (表三)

    上述情形,如用阶级式数字编码法必须3位数,但如改为区段数字编码则仅需二位数即可,其情形如下:

    类别

    分配编码

    剩余备用编码

    A类

    12项(01-20)

    8项

    B类

    10项(21-37)

    7项

    C类

    17项(38-61)

    7项

    D类

    15项(62-83)

    7项

    E类

    10项(84-99)

    6项

    (表四)

    4)      国际十进分类(U. D. C. )

     这种方法于1876年美国杜威M.DeWey首创,其方法新颖而独到,可以无限制展开,颇受欧洲大陆各国的重视。1895年的国际图书馆学会决定杜威的十进法为基础,作更进一步发展,其后经众多数学专家的确究与发展,最后完成所谓国际十进制分类法(Universal Decimal Classification),目前已有许多国家采用为国家规格。

    所谓国际十进制分类法是将所有物料分类为十大类,分别以0至9之数字代表之,然后每大类物料再划分为十个中类,再以0至9之数字为代表,如此进行下去按金字塔Pyramid形态展开。其情形如下:

    6                    应用科学

    62.                     工业技术

    621.                机械的工业技术

    621.8               动力传动

    621.88                  挟具

    621.882.           螺丝、螺帽

    621.882.2              各种小螺丝

    621.882.21             金属用小螺丝

    621.882.215            丸螺丝

    621.682.215.3          平螺丝

    采用国际十进分类的信息编码,如编码编至三位数字之后仍须继续延长时时,即应加以"."符号以表示划分,国际十进分类法可无限展开,任何新物料之产生均可插入原有信息编码之系统而不混淆原有之信息编码系统,国际十进分类法所能运用之符号只有十个(0-9),故使编码趋长而又无暗示作用,实在美中不足。

    二、      英文字母法

    是以英文字母作为信息编码工具的信息编码法。英文字母中I、O、Q、Z 等字与阿拉伯数字1、0、9、2等容易混淆,故多废弃不用,除此之外,尚有23个字母可利用。如以A代表金属材料,B代表非木材,C代表玻璃。以AA代表铁金属,以AB代表铜金属......,英文字母在我国已经相当普遍,是可用的信息编码方法。

    三、      暗示法

    暗示编码法是指信息编码代表物料的意义,可自编码本身联想出来。暗示编码法又可分为:

    ²       字母暗示法

    ²       数字暗示法

    1)      英文字母暗示法:

    从物料的英文字母当中,择取重要且有代表性的一个或数个英文字母(通常取主要文字的第一个字母)做为编码的号码,使阅读信息编码者可以从中想象到英文字文字,进而从暗示中得知该物料为何物。

    2)      数字暗示法:

      直接以物料的数字为信息编码的号码,或将物料的数字依一固定规则而转换成信息编码的号码,信息编码的阅读者可从信息编码数字的暗示中得悉该物料为何物。

    四、      混合法

    混合法信息编码系联合使用英文字母与阿拉伯数字来作信息编码,而多以英文字母代表物料之类别或名称,其后再用十进制元或其它方式编阿拉伯数字号码。这种信息编码方法较十进制元采用符号较多,故有不少企业乐于采用此种方法。

    第3节  系统信息编码的处理特点

    一、      灵活地解决信息编码的修改问题

    信息编码原则上不允许修改,但由于各种原因,如:制定信息编码原则时预留范围不够,需要扩充;新信息编码时物料的类别分配错误;随着企业的发展,使用信息类型的变化,原来的编码原则需要更改或细分等。当这些事情发生时都需要对现有的信息编码进行修改,否则物料的编码原则将失效。

    综上所述,信息编码的修改在很多情况下是因为信息类别变化引起的,信息编码中所携带的物料类别信息越多,则信息编码越需要频繁地修改。

    二、      物料分类更加灵活、细致

    信息类别管理采用分级管理,用户可根据需要设置物料类别及细分类别,原则上对级次不限制。用户可以根据需要随时调整物料的类别,达到统计、分析的目的。

    三、      使用技巧

    如果完全按照顺序号进行信息编码,虽然编码简短,但不容易记忆,如果编码中携带了物料的类别信息,则不易修改。一般地,根据企业的具体情况,采用二者结合的方法。有以下原则可参考:

    当物料种类比较少时,如1000种以下,可较多地携带类别信息

    如:   600型扫描仪,编码为SCAN600

           1200型扫描仪,编码为SCAN1200

           PⅡ300Mhz处理器,编码为P2CPU300

           PHILIPS显示器,编码为CP001(CP表示电脑部件)

           IBM显示器,编码为CP002(CP表示电脑部件)

    当物料的种类较多时,如5000种以上,可不携带或少携带类别信息

    如:   3/8" x 3/4"六角铁制螺栓带帽,编码为:5872

    3/8" x 1"六角铁制螺栓带帽,编码为:5873

    1/2" x 1"六角铁制螺栓带帽,编码为:5874

    毛衣(红色):3002R (用R表示红色)

    毛衣(黄色):3002Y (用Y表示红色)

    记住毛衣为3002,可联想出红色3002R,绿色3002G......

    将来可能会变动的物料类别信息或物料属性最好不要将其作为信息编码的一部分,而将其放在物料的类别信息中。

    如果用户目前已经存在旧的信息编码,而且所有人员已经熟悉,不到万不得已,最好不要修改,继续沿用以前的代码,可减少许多工作量。

    展开全文
  • 信息论实验-信源编码2(Lz编码和算数编码的C++实现)

    万次阅读 多人点赞 2017-08-13 17:21:36
    上一篇文章给出了Huffman编码和Shannon Fano编码编码原理以及C++的程序,程序可以用来实现给任意类型的文件进行无损压缩,缺点是比较耗时,不能作为正常的通用压缩软件来使用,但是作为算法理解,算法思路是没有...

    上一篇文章给出了Huffman编码和Shannon Fano编码的编码原理以及C++的程序,程序可以用来实现给任意类型的文件进行无损压缩,缺点是比较耗时,不能作为正常的通用压缩软件来使用,但是作为算法理解,算法思路是没有问题的,后续可能需要进行优化,下面的LZ编码和算数编码和Huffman、Fano编码是走的截然不同的道路,他们的思想差别很大,但却殊途同归,在算法理解上我借助了一些网友前辈的博客中的例子,文章最后我也会指出引用了那些文章,谢谢前辈们给出的经典的例子能让晚辈站在巨人的肩膀上,所以在此声明,希望我的引用不会侵犯到前辈们的权益
    * 先上源代码*
    信源编码源代码

    第三章:算数编码的实现

    一. 算数编码的原理

    算数编码不同于Huffman编码,它是非分组(非块)码。它从全序列出发,考虑符号之间的依赖关系来进行编码的。
    算数编码主要的编码方法正是计算输入信源符号序列所对应的区间。术编码的基本原理是将编码的消息表示成实数0和1之间的一个间隔(Interval),消息越长,编码表示它的间隔就越小,表示这一间隔所需的二进制位就越多。
    算术编码用到两个基本的参数:符号的概率和它的编码间隔。信源符号的概率决定压缩编码的效率,也决定编码过程中信源符号的间隔,而这些间隔包含在0到1之间。编码过程中的间隔决定了符号压缩后的输出。
    给定事件序列的算术编码步骤如下:
    (1)编码器在开始时将“当前间隔” [ L, H) 设置为[0,1)。
    (2)对每一事件,编码器按步骤(a)和(b)进行处理
    (a)编码器将“当前间隔”分为子间隔,每一个事件一个。
    (b)一个子间隔的大小与下一个将出现的事件的概率成比例,编码器选择子间隔对应于下一个确切发生的事件相对应,并使它成为新的“当前间隔”。
    (3)最后输出的“当前间隔”的下边界就是该给定事件序列的算术编码。
    设Low和High分别表示“当前间隔”的下边界和上边界,CodeRange为编码间隔的长度,LowRange(symbol)和HighRange(symbol)分别代表为了事件symbol分配的初始间隔下边界和上边界。算术编码也是一种对错误很敏感的编码方法,如果有一位发生错误就会导致整个消息译错。
    算术编码可以是静态的或者自适应的。在静态算术编码中,信源符号的概率是固定的。在自适应算术编码中,信源符号的概率根据编码时符号出现的频繁程度动态地 进行修改,在编码期间估算信源符号概率的过程叫做建模。需要开发动态算术编码的原因是因为事先知道精确的信源概率是很难的,而且是不切实际的。当压缩消息 时,我们不能期待一个算术编码器获得最大的效率,所能做的最有效的方法是在编码过程中估算概率。因此动态建模就成为确定编码器压缩效率的关键。

    二. 算数编码过程

    假设有信源符号{A, B. C, D}, 对应的概率和初始编码间隔如下表所示

    符号 A B C D
    概率 01. 0.4 0.2 0.3
    初始编码间隔 [0, 0.1) [0.1, 0.5) [0.5, 0.7) [0.7, 1)

    如果二进制消息序列的输入为:CADACDB。编码时首先输入的符号是C, 找到他的编码范围是[0.5, 0.7)。由于消息由于消息中第二个符号A的编码范围是[0, 0.1),因此它的间隔就取[0.5, 0.7)的第一个十分之一作为新间隔[0.5, 0.52)。依此类推,编码第3个符号D时取新间隔为[0.514, 0.52),编码第4个符号A时,取新间隔为[0.514, 0.5146),…。消息的编码输出可以是最后一个间隔中的任意数
    编码过程如下表所示
    表3.2 算数编码的编码过程

    步骤 输入符号 编码间隔 编码判决
    1 C [0.5, 0.7] 符号的间隔范围[0.5, 0.7]
    2 A [0.5, 0.52] [0.5, 0.7]间隔的第一个1/10
    3 D [0.514, 0.52] [0.5, 0.52]间隔的最后一个1/10
    4 A [0.514, 0.5146] [0.514, 0.52]间隔的第一个1/10
    5 C [0.5143, 0.51442] [0.514, 0.5146]间隔的第五个1/10开始,二个1/10
    6 D [0.514384, 0.51442] [0.5143, 0.51442]间隔的最后3个1/10
    7 B [0.5143836,0.514402] [0.514384,0.51442]间隔的4个1/10,从第1个1/10开始
    8 从[0.5143876, 0.514402]中选择一个数作为输出:0.5143876

    译码过程如下表
    表3.3 算数编码的译码过程

    步骤 间隔 译码符号 译码判决
    1 [0.5, 0.7] C 0.51439在间隔 [0.5, 0.7)
    2 [0.5, 0.52] A 0.51439在间隔 [0.5, 0.7)的第1个1/10
    3 [0.514, 0.52] D 0.51439在间隔[0.5, 0.52)的第7个1/10
    4 [0.514, 0.5146] A 0.51439在间隔[0.514, 0.52]的第1个1/10
    5 [0.5143, 0.51442] C 0.51439在间隔[0.514, 0.5146]的第5个1/10
    6 [0.514384, 0.51442] D 0.51439在间隔[0.5143, 0.51442]的第7个1/10
    7 [0.51439,0.5143948] B 0.51439在间隔[0.51439, 0.5143948]的第1个1/10
    8 译码的消息:C A D A C D B

    三. 算数编码的实现

    这几种算法唯独算数编码我没有用C++实现,当时记得为了应付课堂作业,借用了网上一位博友的代码,大家如果想借鉴这个算法实现的代码,我这里可以给出我更改后的版本,但并不是我原创的,但是很抱歉具体是在哪里借鉴的我忘记了,当时比较草率,没有想太多,这里我还是把过程及测试结果给大家介绍清楚,代码的话如果能找到原主人最好不过了,这里我给出我改过的版本。
    算数编码我只是使用字符串进行了测试,不能做到像Huffman编码一样对任何类型的文件都进行编码和译码。
    主函数

    int main()
    {
        string str; //输入要编码的String类型字符串
        int number = 0, size = 0; //number--字符串中不重复的字符个数;size--字符串长度 
        char c[N]; //用于存储不重复的字符
        long double p[N], output; //p[N]--不重复字符的概率,output--编码结果 
        disp();
        cout << "输入要编码的字符串:";
        getline(cin, str); //输入要编码的字符串
        size = str.length(); //字符串长度
        number = proba(str, c, p, size);//调用求概率函数,返回不重复字符的个数
        cout.setf(ios::fixed); //“魔法配方”规定了小数部分的个数
        cout.setf(ios::showpoint); //在此规定编码结果的小数部分有十个
        cout.precision(10);//调用编码函数,返回编码结果
        output = bma(c, p, str, number, size);//调用译码函数,输出要编码的字符串,
        yma(str, c, p, number, size, output); //以验证编码是否正确   
        getchar();
        return 0;
    }

    特殊结构和功能函数的定义

    #define N 100 //输入的字符应该不超过50个
    struct L //结构用于求各字符及其概率
    {
        char ch; //存储出现的字符(不重复)
        int num; //存储字符出现的次数
        double f;//存储字符的概率
    };
    //显示信息
    void disp();
    //求概率函数,输入:字符串;输出:字符数组、字符的概率数组;返回:数组长度; int proba(string str,char c[],long double p[],int count);
    //求概率的辅助函数
    int search(vector<L> arch, char, int n);
    long double bma(char c[], long double p[], string str, int number, int size);
    int proba(string str, char c[], long double p[], int count);
    //编码函数,输入:字符串,字符数组,概率数组,以及数组长度;输出:编码结果 long double bma(char c[],long double p[],string str,int number,int size);
    //译码函数,输入:编码结果,字符串,字符数组,概率数组,以及它们的长度;输出:字符串
    //该函数可以用于检测编码是否正确
    void yma(string str, char c[], long double p[], int number, int size, long double input);
    
    void disp()
    
    {
    
        cout << endl;
        cout << "此程序只需要输入要编码的字符串,不需要输入字符概率\n";
        cout << endl;
    
    }
    
    //求概率函数
    
    int proba(string str, char c[], long double p[], int count)
    
    {
    
        cout.setf(ios::fixed); //“魔法配方”规定了小数部分位数为三位
        cout.setf(ios::showpoint);
        cout.precision(3);
        vector<L>pt; //定义了结构类型的向量,用于同时存储不重复的字符和其概率
        L temp; //结构类型的变量
        temp.ch = str[0]; //暂存字符串的第一个字符,它的个数暂设为1
        temp.num = 1;
        temp.f = 0.0;
        pt.push_back(temp); //将该字符及其个数压入向量
        for (int i = 1; i<count; i++)//对整个字符串进行扫描
    
        {
            temp.ch = str[i]; //暂存第二个字符
            temp.num = 1;
            temp.f = 0.0;
            for (int j = 0; j<pt.size(); j++) //在结构向量中寻找是否有重复字符出现
            { //若重复,该字符个数加1,并跳出循环 
                int k; //若不重复,则压入该字符,并跳出循环 
                k = search(pt, str[i], pt.size());
                if (k >= 0)
    
                {
                    pt[k].num++;
                    break;
                }
                else
                {
                    pt.push_back(temp);
                    break;
                }
    
            }
    
        }
        for (int i = 0; i<pt.size(); i++) //计算不重复字符出现的概率
        {
            pt[i].f = double(pt[i].num) / count;
        }
        int number = pt.size(); //计算不重复字符出现的次数
        cout << "各字符概率如下:\n";
        for (int i = 0; i<number; i++) //显示所得的概率,验证是否正确
        {
            if (count == 0)
            {
                cout << "NO sample!\n";
            }
            else
            {
                c[i] = pt[i].ch;
                p[i] = pt[i].f;
                cout << c[i] << "的概率为:" << p[i] << endl;
            }
        }
        return number; //返回不重复字符的个数
    }
    //求概率的辅助函数
    //若搜索发现有重复字符返回正数
    //否则,返回-1
    int search(vector<L> arch, char ch1, int n)
    {
        for (int i = 0; i<n; i++)
        {
            if (ch1 == arch[i].ch) return i;
        }
    return -1;
    }
    //编码函数
    long double bma(char c[], long double p[], string str, int number, int size)
    {
        long double High = 0.0, Low = 0.0, high, low, range;
        //High--下一个编码区间的上限,Low--下一个编码区间的下限;
        //high--中间变量,用来计算下一个编码区间的上限;
        //low--中间变量,用来计算下一个编码区间的下限;
        //range--上一个被编码区间长度
        int i, j = 0;
        for (i = 0; i<number; i++)
        {
            if (str[0] == c[i]) break; //编码第一个字符
        }
        while (j<i)
        {
            Low += p[j++]; //寻找该字符的概率区间下限
        }
        range = p[j]; //得到该字符的概率长度
        High = Low + range; //得到该字符概率区间上限
        for (i = 1; i<size; i++) //开始编码第二个字符
        {
            for (j = 0; j<number; j++) //寻找该字符在c数组中的位置
            {
                if (str[i] == c[j])
                {
                    if (j == 0) //若该字符在c数组中的第一个字符
                    {
                        low = Low; //此时该字符的概率区间下限刚好为零 
                        high = Low + p[j] * range;
                        High = high;
                        range *= p[j]; //求出该字符的编码区间长度
                    }
                    else //若该编码字符不是c数组中的第一个 
                    {
                        float proba_next = 0.0;
                        for (int k = 0; k <= j - 1; k++)
                            proba_next += p[k]; //再次寻找字符的概率区间下限
                        low = Low + range*proba_next; //编码区间下限 
                        high = Low + range*(proba_next + p[j]);//编码区间上限
                        Low = low; //编码区间下限 
                        High = high; //编码区间上限 
                        range *= p[j]; //编码区间长度
                    }
                }
                else continue; //i++,编码下一个字符 
            }
        }
        cout << endl;
        cout << "输入字符串的编码为:" << Low << endl;
        return Low;
    }
    //译码函数
    void yma(string str, char c[], long double p[], int number, int size, long double input)
    {
        vector<char> v; //定义char类型向量v
        long double temp; //中间变量
        long double sum[N]; //存储不重复字符概率区间的下限
        sum[0] = 0.0; //数组第一个元素为0
        for (int i = 1; i<number + 1; i++) //计算数组各元素的值
        {
            sum[i] = sum[i - 1] + p[i - 1];
        }
        for (int j = 0; j<size; j++)
        {
            for (int k = 0; k<number; k++)
            {
                //确定被编码字符的下限属于【0,1】之间的哪一段 
                if ((input>sum[k]) && (input<sum[k + 1])) //发现在哪就将属于该段的字符压入向量v
                {
                    v.push_back(str[j]);
                    temp = (input - sum[k]) / (sum[k + 1] - sum[k]);//计算下一个被编码字符的下限 
                    input = temp;
                    break;
                }
                else
                    continue;
            }
        }
        cout << endl;
        cout << "译码输出为:"; //将译码结果输出
        for (int m = 0; m<v.size(); m++)
        {
            cout << v[m];
        }
        cout << endl;
    }

    第四章:LZ编码的实现之LZ-78编码

    一. LZ-78编码原理

    经过查找资料,LZ编码并不是一种编码,而是一组编码,由LZ-77和LZ-78演变而来有很多种变形。所以这里我只选取了一种比较简单的算法LZ-78算法。
    LZ-78编码算法是一种分段编码算法。算法的压缩过程非常简单。在压缩时维护一个动态词典Dictionary,其包括了历史字符串的index与内容。设信源符号集 A=a0,a1,a2...aq1共q个字符,设输入信源序列为

    S1S2...Sn

    编码就是将此序列分成不同的X段。分段的原则是:
    1. 先取第一个符号作为第一段,然后再继续分段
    2. 若出现有与前面相同符号时,就在添加进跟随后面的一个符号一起组成一个段,以使与前面的段不同。
    3. 尽可能取最少个连通着的信源符号,并保证隔断都不相同。直至信源符号徐立结束。
    这样,不同的段内的信源符号可看成一短语,可得不同段所对应的短语字典表。若编成二元码,段号用二进制表示,段号所需码长为l=logX(n) ,X(n)是段号数。

    二. LZ-78编码过程

    LZ-78编码在压缩时维护一个动态词典Dictionary,其包括了历史字符串的index与内容;压缩情况分为三种:
    1. 若当前字符c未出现在词典中,则编码为(0, c);
    2. 若当前字符c出现在词典中,则与词典做最长匹配,然后编码为(prefixIndex,lastChar),其中,prefixIndex为最长匹配的前缀字符串,lastChar为最长匹配后的第一个字符;
    3. 为对最后一个字符的特殊处理,编码为(prefixIndex,)
    举例
    以字符串“ABBCBCABABCAABCAAB”压缩编码构造字典的过程如下
    LZ-78编码
    1. A 不在字典中; 插入A
    2. B不在字典中; 插入B
    3. B 在字典中.
    BC 不在字典中; 插入BC
    4. B在字典中.
    BC在字典中.
    BCA不在字典中.;插入BCA
    5. B在字典中.
    BA不在字典中; 插入BA.
    6. B在字典中.
    BC在字典中.
    BCA在字典中.
    BCAA不在字典中;插入BCAA
    7. B在字典中.
    BC在字典中.
    BCA在字典中.
    BCAA在字典中.
    BCAAB 不在字典中; 插入BCAAB.

    三. LZ-78编码编程实现和性能分析

    LZ-78算法我构建了一个LZ78类。类的定义如下

    class LZ78
    {
    public:
        struct Dictionary
        {
            unsigned int Index;
            int preIndex;
            unsigned char lastChar;
            vector<unsigned char> stringInDic;
        };
    public:
        struct OutData
        {
            unsigned int preIndex;
            unsigned char lastChar;
        };
    public:
        string fileAddress;
        LZ78();   //构造函数
        void open(string);
        void Press();
        void Decode(string sourcefile, string dstfile);
    private:
        bool IfStringInDic(vector<Dictionary> CurrentString, vector<unsigned char> DataDic, unsigned int &Index);
    private:
        vector<unsigned char> FindPreString(vector<Dictionary> DataDic, unsigned int);
    };

    核心属性
    1. struct Dictionary: 存储字典信息
    2. struct OutData: 存储输出信息即上面所提到的二元组(preIndex, lastChar);
    3. string fileAddress: 需要压缩的文件的路径名称
    核心函数:
    1. void open(string address) : 打开待压缩文件
    2. void Press(): 压缩文件操作
    3. void Decode(string sourcefile, string dstfile): 解码操作
    正式操作见下面主函数:
    主函数:

    int main()
    {
        LZ78 haha;
        clock_t start, end;
        start = clock();
        haha.open("./KongFu.jpg");  //打开文件
        haha.Press();   //压缩文件
        end = clock();
        cout << "压缩文件用时:" << endl << endl;
        cout << double((end - start) / CLOCKS_PER_SEC) << "/s" << endl << endl;
        start = clock();
        LZ78 nothaha;
        nothaha.Decode("./KongFu.jpg.lz", "KongFuout.jpg");
        cout << "解压用时:" << endl << endl;
        cout << double((start - end) / CLOCKS_PER_SEC) << "/s" << endl << endl;
        getchar();
    }

    文件压缩步骤
    第一步:建立haha对象为LZ78类型
    第二步:打开待压缩的文件
    第三步:压缩文件
    第四部:压缩结束
    文件解压步骤
    第一步:建立nothaha对象为LZ78类型
    第二步:解压文件
    第三步:解压结束
    LZ-78编码的性能测试见下表
    表4.1 LZ-78编码性能测试

    原始文件 890Bytes(文本) 46.7kb(图像) 7.82M(视频)
    压缩文件 3133Bytes 47.9kb 7.81M
    压缩率 1.29 1.025 99.8%
    压缩用时 6/s 20/s /
    解码用时 0/s 0/s /

    看到自己程序跑的结果自己都想笑,这也太慢了点了,有时候想安慰一下自己,可能是C++读取文件的API很耗时,要想速度快,有朝一日自己写读取文件的API,励志。
    最后附上LZ-78程序的C++源代码

    LZ78.h

    #include <iostream>
    #include <fstream>
    #include <vector>
    using namespace std;
    class LZ78
    {
    public:
        struct Dictionary
        {
            unsigned int Index;
            int preIndex;
            unsigned char lastChar;
            vector<unsigned char> stringInDic;
        };
    public:
        struct OutData
        {
            unsigned int preIndex;
            unsigned char lastChar;
        };
    public:
        string fileAddress;
        LZ78();   //构造函数
        void open(string);
        void Press();
        void Decode(string sourcefile, string dstfile);
    private:
        bool IfStringInDic(vector<Dictionary> CurrentString, vector<unsigned char> DataDic, unsigned int &Index);
    private:
        vector<unsigned char> FindPreString(vector<Dictionary> DataDic, unsigned int);
    };
    
    LZ78::LZ78()
    {
    
    }
    void LZ78::open(string input)
    {
        fileAddress = input;
    }
    
    void LZ78::Press()
    {
        ifstream read;
        read.open(fileAddress, ios::in|ios::binary);
        if (!read )
        {
            cout << "文件读取错误" << endl << endl;
            return;
        }
        ofstream write;
        write.open(fileAddress + ".lz", ios::out|ios::binary);
        if (!write)
        {
            cout << "输出文件不能建立(*.lz)" << endl << endl;
        }
    
        unsigned char *firstchar = new unsigned char;
        read.read((char*)firstchar, sizeof(unsigned char));
        vector<Dictionary> DataDic;    //建立字典
        while (!read.eof())
        {
    
            if (DataDic.size() == 0)
            {
                Dictionary firstDic;
                OutData *firstout = new OutData;
                firstDic.Index = 1;
                firstDic.preIndex = 0;
                firstDic.lastChar = *firstchar;
                firstDic.stringInDic.push_back(*firstchar);
                DataDic.push_back(firstDic);
                firstout->lastChar = *firstchar;
                firstout->preIndex = 0;
                write.write((char*)firstout, sizeof(OutData));
            }
            else
            {
                unsigned char *now = new unsigned char; //用于读取的字符
                unsigned char *reallast = new unsigned char;
                vector<unsigned char> CurrentString;
                unsigned int index = 0;  //字符串存在在字典中的位置, 初始设为0
                Dictionary currentInfo;   //存储当前的单词到字典中
                OutData *currentOutdata = new OutData;  //存储当前编码信息,一会压缩进如压缩文件。
    
                int EOFflag = 0;
                do
                {
                    read.read((char*)now, sizeof(unsigned char));
                    if (read.eof())
                    {
                        EOFflag = 1;  //标记是否到文件的结尾
                        break;
                    }
                    else
                    {
                        CurrentString.push_back(*now);
                    }
                } 
                while (IfStringInDic(DataDic, CurrentString, index));
    
    
                if (EOFflag == 1)
                {
                    if (CurrentString.size() == 0)
                    {
                        break;  //如果当前字符串中没有字符,直接跳出循环
                    }
                    else
                    {     //如果当前字符串中有字符,对这段字符进行压缩。
                        *reallast = CurrentString[CurrentString.size() - 1];
                        CurrentString.erase(CurrentString.end() - 1);
                        IfStringInDic(DataDic, CurrentString, index);
    
                    }
    
                }
                else
                {
                    *reallast = *now;
                }
                currentInfo.Index = DataDic.size() + 1;
                currentInfo.lastChar = *reallast;
                currentInfo.preIndex = index;
                currentInfo.stringInDic = CurrentString;
                DataDic.push_back(currentInfo);
    
                currentOutdata->lastChar = *reallast;
                currentOutdata->preIndex = index;
                write.write((char*)currentOutdata, sizeof(OutData));
    
            }
    
        }
    
        read.close();
        write.close();
    }
    
    bool LZ78::IfStringInDic(vector<Dictionary> DataDic, vector<unsigned char> CurrentString, unsigned int &Index)
    {
        int flag = 0;
        for (int i = 0; i < DataDic.size(); i++)
        {
            if (CurrentString == DataDic[i].stringInDic)
            {
                Index = DataDic[i].Index;
                flag = 1;
                return true;
            }
    
        }
        if (flag == 0)
        {
            return false;
        }
    }
    
    
    void LZ78::Decode(string sourcefile, string dstfile)
    {
        ifstream readfile;
        ofstream putfile;
        readfile.open(sourcefile, ios::in | ios::binary);
        putfile.open(dstfile, ios::out | ios::binary);
        OutData *getdata = new OutData;
        readfile.read((char*)getdata, sizeof(OutData));
        vector<Dictionary> DataDic;    //建立字典
        Dictionary *spacefirst = new Dictionary;
        spacefirst->Index = 0;
        spacefirst->lastChar = '0';
        spacefirst->preIndex = 0;
        //spacefirst->stringInDic
        DataDic.push_back(*spacefirst);
        while (!readfile.eof())
        {
            Dictionary *now = new Dictionary;
            now->lastChar = getdata->lastChar;
            now->Index = DataDic.size();
            now->preIndex = getdata->preIndex;
            vector<unsigned char> preString;  //存储前一个的字符串
            if (now->preIndex != 0)
            { //如果preIndex等于0那么此字符是新出现的字符,否则在前面字典中找
                preString = FindPreString(DataDic, now->preIndex);
            }
            preString.push_back(now->lastChar);  
            now->stringInDic = preString;  //获取此单词的字符串。
            DataDic.push_back(*now);
            for (int i = 0; i < preString.size(); i++)
            {
                putfile.write((char*)&preString[i], sizeof(unsigned char));
            }
            readfile.read((char*)getdata, sizeof(OutData));
    
        }
        readfile.close();
        putfile.close();
    }
    
    vector<unsigned char>  LZ78::FindPreString(vector<Dictionary> DataDic, unsigned int preindex)
    {
        if (DataDic.size() < 1)
        {
            cout << "不能找到前一个字符串" << endl;
        }
        else
        {
            for (int i = 0; i < DataDic.size(); i++)
            {
                if (preindex == DataDic[i].Index)
                {
                    return DataDic[i].stringInDic;
                }
            }
        }
    }

    LZ-78Main.cpp

    #include "LZ78.h"
    #include <string>
    #include <time.h>
    int main()
    {
        LZ78 haha;
        clock_t start, end;
        start = clock();
        haha.open("./KongFu.jpg");  //打开文件
        haha.Press();   //压缩文件
        end = clock();
        cout << "压缩文件用时:" << endl << endl;
        cout << double((end - start) / CLOCKS_PER_SEC) << "/s" << endl << endl;
        start = clock();
        LZ78 nothaha;
        nothaha.Decode("./KongFu.jpg.lz", "KongFuout.jpg");
        cout << "解压用时:" << endl << endl;
        cout << double((start - end) / CLOCKS_PER_SEC) << "/s" << endl << endl;
        getchar();
    }

    总结

    经过此次试验真的是收获了很多,首先是对各种编码的熟悉,从Huffman编码、Shannon Fano码、算数编码到LZ编码家族,了解了Zip,winrar等压缩软件的压缩原理,以及压缩算法从兴起到应用,里面还有一些版权纠纷的故事(LZW版权问题)。到现在的操作系统使用的压缩软件的情况,Windows主要的软件是winrar和zip, linux系统下主要是.gz和gzip软件。其原理都是基于DELLATE算法的。DELLATE算法是以Huffman编码和LZW编码为核心的。另一方面,从信息论角度细致的学习了各种编码的编码原理和译码方式,这些收获相信在今后的学习中都会有用的。这次实验不仅锻炼了编程能力,而且学习到很多编码领域的新知识。

    参考文献
    《信息论与编码》傅祖芸、赵建中 电子工业出版社
    C++实现Huffman文件编码和解码:http://www.cnblogs.com/matrix-r/p/3354887.html
    zip压缩原理 http://blog.jobbole.com/76676/
    Huffman对文件编码和解码http://blog.csdn.net/computer_liuyun/article/details/41446773
    huffman编码原理与实现:http://blog.csdn.net/abcjennifer/article/details/8020695
    二进制和ASCII编码: http://blog.csdn.net/sxhelijian/article/details/29594687
    压缩编码的历史:http://blog.csdn.net/kimylrong/article/details/39405981
    Lz78算法:http://www.cnblogs.com/aeexiaoqiang/p/6529375.html
    算数编码: http://blog.csdn.net/adam_tu/article/details/7696455

    展开全文
  • 信息论与编码之课设-哈夫曼编码

    千次阅读 2016-11-26 19:45:41
    哈夫曼编码(Huffman Coding),又称霍夫曼编码,是一种编码方式,  夫曼编码是可变字长编码(VLC)的一种。Huffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长度最短的码字,有时称之...

     哈夫曼编码(Huffman Coding),又称霍夫曼编码,是一种编码方式, 

    夫曼编码是可变字长编码(VLC)的一种。Huffman1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长度最短的码字,有时称之为最佳编码,一般就叫做Huffman编码(有时也称为霍夫曼编码)

       首先,将符号按照概率由大到小排队编码时,从最小概率的两个符号开始,可选其中一个支 路为0,另一支路为1。这里,我们选上支路为0,下支路为1。再将已编码的两支路的概率合并,并重新排队。多次重复使用上述方法直至合并概率归一时为止   

     从文件中或者输入 读入一个字符串,统计字符串中的字符种类(不包括大小写),以及每个字符出现的概率,并按照霍夫曼编程思想,构造哈夫曼树结构,将其转化成01”的二进制字符串,并且可以读入一串01字符串,将其译为对应的哈夫曼字符。并计算其编码效率。

    基本算法:

    ①  输入字符串 (不包含大小写),回车结束

         ②  根据循环遍历统计字符串中每个不同字符的概率以及总个数

         ③  根据哈夫曼编码构造哈夫曼树

             先将数组排序,采用优先队列求出最小的两个概率,求和得到父节点 ,加入哈夫曼树数组中,依次循环直到只剩下一个概率且为1的根节点

          ④  编码,从每个叶子节点向根遍历,如果是左子树编码就为0,右子树为1.直到所有的叶子节点都编码完毕。

          ⑤   根据公式求编码效率n == H(s)/l

         ⑥  译码 ,根据输入的字符串,从根节点开始想下边遍历,如果是1就向右子树,0就是左子树,直到找到一个叶子节点就退出。继续从根节点开始。

    代码如下:

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<queue>
    #include<stack>
    #include<cmath>
    #include<algorithm>
    #include<functional>
    #define max 200
    using namespace std;
    struct jcode//求得概率之后的结构体
    {
        char c;
        int x;//概率
        int b;//下标
        friend bool operator<(jcode a, jcode b ){//优先队列排序
            return b.x<a.x;
        }
    };
    typedef jcode jjnum[max];
    typedef struct bnode{//存储哈夫曼树的结构体数组
        char data;
        int  x;
        int  lchild,rchild,parent;
        char code[max];//每个字符编码
        int len;//编码长度
    }bnode;
    typedef bnode huffman[max];
    //统计输入的字符及各自概率
    int  getnum(string ss,jjnum str)
    {
        int i,j;
        int temp[max];
        for(i = 0;i< max;i++)
        {
            temp[i]=0;
        }
        for(i = 0;i<ss.length();i++)//求概率
             temp[ss[i]-'!']++;
        j=0;
        for(i = 0;i<max;i++)//存到结构体1
        {
            if(temp[i]!=0)
            {
                str[j].x= temp[i];
                str[j].c = i+'!';
                str[j].b = j;
                j++;
            }
        }
        return j;
    }
    void create(priority_queue<jcode>q,huffman &t,int cnum,jjnum str)//构造哈夫曼树
    {
        int i,a1,a2;
        for(i=0;i<2*cnum-1;i++)//初始化结点
        {
           t[i].lchild = t[i].parent = t[i].rchild = t[i].x  = 0;
           t[i].data= '1';
    
        }
        for(i=0;i<cnum;i++)//叶子节点
        {
            t[i].x = str[i].x;
            t[i].data = str[i].c;
        }
    
        for(i=cnum;i<2*cnum-1;i++)//根据哈夫曼编码构造哈夫曼树
        {
            a1 = q.top().b;
            t[a1].parent = i;q.pop();
            a2 = q.top().b;
            t[a2].parent = i;q.pop();
            t[i].lchild = a1;//指向孩子
            t[i].rchild = a2;
            t[i].x = t[a1].x+t[a2].x;//概率小的两个相加
            jcode e;
            e.c = '1';e.x = t[i].x;e.b = i;
            q.push(e);//和存到队列中
        }
        for(i=0;i<cnum;i++)//由0.1进行二元编码,1右0左
        {
            int x;
            x=i;
            t[i].len = 0;
            while(t[x].parent!=0)//从叶子节点向根
            {
                if(t[t[x].parent].lchild == x)
                {
                    t[i].code[t[i].len]='0';//存下来编码
                    t[i].len++;
                }
                else
                {
                    t[i].code[t[i].len]='1';
                    t[i].len++;
                }
                x = t[x].parent;
    
            }
        }
    
        for(i=0;i<cnum;i++)//输出每个字符编码
        {
            if(t[i].data!='1')
            {
              cout<<t[i].data<<"  ===  ";
              for(int j=t[i].len-1;j>=0;j--)
                cout<<t[i].code[j];
              cout<<endl;
            }
        }
    }
    //编码f
    void strhttree(jjnum str,int num,huffman &t)
    {
        int i;
        priority_queue<jcode>q2;
        for(i = 0; i < num; i++)//加入优先队列
            q2.push(str[i]);
        create(q2,t,num,str);
    }
    void yima(string ss,int i,huffman &t,int num,int cnum)//译码
    {
        while(num>=cnum)//从根节点开始
        {
          if(ss[i]=='1')
          {
              num = t[num].rchild;
              i++;
          }
          else
         {
              num = t[num].lchild;
              i++;
          }
        }
        if(i<=ss.length())//得到一个叶子节点,即译出一个字符
        {
          cout<<t[num].data;
          yima(ss,i,t,2*cnum-2,cnum);//继续译码
        }
    }
    int main()
    {
        string s;//输入字符串
        huffman t;//哈夫曼树
        getline(cin,s);
        jcode str[max];
        int cnum = getnum(s,str);//字符的种类个数
        strhttree(str,cnum,t);//构造哈夫曼树
        for(int k = 0;k<s.length();k++)//输出编码
            for(int i=0;i<cnum;i++)
           {
               if(s[k]==t[i].data){
                 for(int j=t[i].len-1;j>=0;j--)
                   cout<<t[i].code[j];
               }
           }
        cout<<endl;
        double sum1 =0.0,sum2 = 0.0;
        for(int i = 0;i<cnum;i++)//求编码效率
        {
           sum1+=((t[i].x*1.0/s.size())*(-log2(t[i].x*1.0/s.size())));
            sum2+=(t[i].x*1.0/s.size())*t[i].len;
    
        }
        cout<<"n=="<<(sum1/sum2)<<endl;
        string l;
        getline(cin,l);//输入码
        int x= 2*cnum -2;//根节点、
        yima(l,0,t,x,cnum);//译码
        return 0;
    }
    
    


    展开全文
  • 全国省份信息编码 //省份数组 $all_region = [ '110000' => '北京市', '120000' => '天津市', '130000' => '河北省', '140000' => '山西省', '

    全国省份信息与编码

        //省份数组
            $all_region = [
                    '110000' => '北京市',
                    '120000' => '天津市',
                    '130000' => '河北省',
                    '140000' => '山西省',
                    '150000' => '内蒙古自治区',
                    '210000' => '辽宁省',
                    '220000' => '吉林省',
                    '230000' => '黑龙江省',
                    '310000' => '上海市',
                    '320000' => '江苏省',
                    '330000' => '浙江省',
                    '340000' => '安徽省',
                    '350000' => '福建省',
                    '360000' => '江西省',
                    '370000' => '山东省',
                    '410000' => '河南省',
                    '420000' => '湖北省',
                    '430000' => '湖南省',
                    '440000' => '广东省',
                    '450000' => '广西壮族自治区',
                    '460000' => '海南省',
                    '500000' => '重庆市',
                    '510000' => '四川省',
                    '520000' => '贵州省',
                    '530000' => '云南省',
                    '540000' => '西藏自治区',
                    '610000' => '陕西省',
                    '620000' => '甘肃省',
                    '630000' => '青海省',
                    '640000' => '宁夏回族自治区',
                    '650000' => '新疆维吾尔自治区',
                    '710000' => '台湾省',
                    '810000' => '香港特别行政区',
                    '820000' => '澳门特别行政区'
            ];

    全世界国家代码查询

        //国家数组。由GB/T 2659-2000国家标准得到,核对多次,确认正确。使用时请将:'TW'=>'台湾',改为,'TW'=>'中国台湾'。
            $all_country = [
                    'AD'=>'安道尔',
                    'AE'=>'阿联酋',
                    'AF'=>'阿富汗',
                    'AG'=>'安提瓜和巴布达',
                    'AI'=>'安圭拉',
                    'AL'=>'阿尔巴尼亚',
                    'AM'=>'亚美尼亚',
                    'AN'=>'荷属安的列斯',
                    'AO'=>'安哥拉',
                    'AQ'=>'南极洲',
                    'AR'=>'阿根廷',
                    'AS'=>'美属萨摩亚',
                    'AT'=>'奥地利',
                    'AU'=>'澳大利亚',
                    'AW'=>'阿鲁巴',
                    'AZ'=>'阿塞拜疆',
                    'BA'=>'波黑',
                    'BB'=>'巴巴多斯',
                    'BD'=>'孟加拉国',
                    'BE'=>'比利时',
                    'BF'=>'布基纳法索',
                    'BG'=>'保加利亚',
                    'BH'=>'巴林',
                    'BI'=>'布隆迪',
                    'BJ'=>'贝宁',
                    'BM'=>'百慕大',
                    'BN'=>'文莱',
                    'BO'=>'玻利维亚',
                    'BR'=>'巴西',
                    'BS'=>'巴哈马',
                    'BT'=>'不丹',
                    'BV'=>'布维岛',
                    'BW'=>'博茨瓦纳',
                    'BY'=>'白俄罗斯',
                    'BZ'=>'伯利兹',
                    'CA'=>'加拿大',
                    'CC'=>'科科斯(基林)群岛',
                    'CD'=>'刚果(金)',
                    'CF'=>'中非',
                    'CG'=>'刚果(布)',
                    'CH'=>'瑞士',
                    'CI'=>'科特迪瓦',
                    'CK'=>'库克群岛',
                    'CL'=>'智利',
                    'CM'=>'喀麦隆',
                    'CN'=>'中国',
                    'CO'=>'哥伦比亚',
                    'CR'=>'哥斯达黎加',
                    'CU'=>'古巴',
                    'CV'=>'佛得角',
                    'CX'=>'圣诞岛',
                    'CY'=>'塞浦路斯',
                    'CZ'=>'捷克',
                    'DE'=>'德国',
                    'DJ'=>'吉布提',
                    'DK'=>'丹麦',
                    'DM'=>'多米尼克',
                    'DO'=>'多米尼加',
                    'DZ'=>'阿尔及利亚',
                    'EC'=>'厄瓜多尔',
                    'EE'=>'爱沙尼亚',
                    'EG'=>'埃及',
                    'EH'=>'西撒哈拉',
                    'ER'=>'厄立特里亚',
                    'ES'=>'西班牙',
                    'ET'=>'埃塞俄比亚',
                    'FI'=>'芬兰',
                    'FJ'=>'斐济',
                    'FK'=>'福兰克群岛(马尔维纳斯)',
                    'FM'=>'密克罗尼西亚联邦',
                    'FO'=>'法罗群岛',
                    'FR'=>'法国',
                    'GA'=>'加蓬',
                    'GB'=>'英国',
                    'GD'=>'格林纳达',
                    'GE'=>'格鲁吉亚',
                    'GF'=>'法属圭亚那',
                    'GH'=>'加纳',
                    'GI'=>'直布罗陀',
                    'GL'=>'格陵兰',
                    'GM'=>'冈比亚',
                    'GN'=>'几内亚',
                    'GP'=>'瓜德罗普',
                    'GQ'=>'赤道几内亚',
                    'GR'=>'希腊',
                    'GS'=>'南乔治亚岛和南桑德韦奇岛',
                    'GT'=>'危地马拉',
                    'GU'=>'关岛',
                    'GW'=>'几内亚比绍',
                    'GY'=>'圭亚那',
                    'HK'=>'香港',
                    'HM'=>'赫德岛和麦克唐纳岛',
                    'HN'=>'洪都拉斯',
                    'HR'=>'克罗地亚',
                    'HT'=>'海地',
                    'HU'=>'匈牙利',
                    'ID'=>'印度尼西亚',
                    'IE'=>'爱尔兰',
                    'IL'=>'以色列',
                    'IN'=>'印度',
                    'IO'=>'英属印度洋领地',
                    'IQ'=>'伊拉克',
                    'IR'=>'伊朗',
                    'IS'=>'冰岛',
                    'IT'=>'意大利',
                    'JM'=>'牙买加',
                    'JO'=>'约旦',
                    'JP'=>'日本',
                    'KE'=>'肯尼亚',
                    'KG'=>'吉尔吉斯斯坦',
                    'KH'=>'柬埔寨',
                    'KI'=>'基里巴斯',
                    'KM'=>'科摩罗',
                    'KN'=>'圣基茨和尼维斯',
                    'KP'=>'朝鲜',
                    'KR'=>'韩国',
                    'KW'=>'科威特',
                    'KY'=>'开曼群岛',
                    'KZ'=>'哈萨克斯坦',
                    'LA'=>'老挝',
                    'LB'=>'黎巴嫩',
                    'LC'=>'圣卢西亚',
                    'LI'=>'列支敦士登',
                    'LK'=>'斯里兰卡',
                    'LR'=>'利比里亚',
                    'LS'=>'莱索托',
                    'LT'=>'立陶宛',
                    'LU'=>'卢森堡',
                    'LV'=>'拉脱维亚',
                    'LY'=>'利比亚',
                    'MA'=>'摩洛哥',
                    'MC'=>'摩纳哥',
                    'MD'=>'摩尔多瓦',
                    'MG'=>'马达加斯加',
                    'MH'=>'马绍尔群岛',
                    'MK'=>'前南马其顿',
                    'ML'=>'马里',
                    'MM'=>'缅甸',
                    'MN'=>'蒙古',
                    'MO'=>'澳门',
                    'MP'=>'北马里亚纳',
                    'MQ'=>'马提尼克',
                    'MR'=>'毛里塔尼亚',
                    'MS'=>'蒙特塞拉特',
                    'MT'=>'马耳他',
                    'MU'=>'毛里求斯',
                    'MV'=>'马尔代夫',
                    'MW'=>'马拉维',
                    'MX'=>'墨西哥',
                    'MY'=>'马来西亚',
                    'MZ'=>'莫桑比克',
                    'NA'=>'纳米比亚',
                    'NC'=>'新咯里多尼亚',
                    'NE'=>'尼日尔',
                    'NF'=>'诺福克岛',
                    'NG'=>'尼日利亚',
                    'NI'=>'尼加拉瓜',
                    'NL'=>'荷兰',
                    'NO'=>'挪威',
                    'NP'=>'尼泊尔',
                    'NR'=>'瑙鲁',
                    'NU'=>'纽埃',
                    'NZ'=>'新西兰',
                    'OM'=>'阿曼',
                    'PA'=>'巴拿马',
                    'PE'=>'秘鲁',
                    'PF'=>'法属波利尼西亚',
                    'PG'=>'巴布亚新几内亚',
                    'PH'=>'菲律宾',
                    'PK'=>'巴基斯坦',
                    'PL'=>'波兰',
                    'PM'=>'圣皮埃尔和密克隆',
                    'PN'=>'皮特凯恩',
                    'PR'=>'波多黎各',
                    'PS'=>'巴勒斯坦',
                    'PT'=>'葡萄牙',
                    'PW'=>'帕劳',
                    'PY'=>'巴拉圭',
                    'QA'=>'卡塔尔',
                    'RE'=>'留尼汪',
                    'RO'=>'罗马尼亚',
                    'RU'=>'俄罗斯联邦',
                    'RW'=>'卢旺达',
                    'SA'=>'沙特阿拉伯',
                    'SB'=>'所罗门群岛',
                    'SC'=>'塞舌尔',
                    'SD'=>'苏丹',
                    'SE'=>'瑞典',
                    'SG'=>'新加坡',
                    'SH'=>'圣赫勒拿',
                    'SI'=>'斯洛文尼亚',
                    'SJ'=>'斯瓦尔巴岛和扬马延岛',
                    'SK'=>'斯洛伐克',
                    'SL'=>'塞拉利昂',
                    'SM'=>'圣马力诺',
                    'SN'=>'塞内加尔',
                    'SO'=>'索马里',
                    'SR'=>'苏里南',
                    'ST'=>'圣多美和普林西比',
                    'SV'=>'萨尔瓦多',
                    'SY'=>'叙利亚',
                    'SZ'=>'斯威士兰',
                    'TC'=>'特克斯和凯科斯群岛',
                    'TD'=>'乍得',
                    'TF'=>'法国南部领地',
                    'TG'=>'多哥',
                    'TH'=>'泰国',
                    'TJ'=>'塔吉克斯坦',
                    'TK'=>'托克劳',
                    'TM'=>'土库曼斯坦',
                    'TN'=>'突尼斯',
                    'TO'=>'汤加',
                    'TP'=>'东帝汶',
                    'TR'=>'土尔其',
                    'TT'=>'特立尼达和多巴哥',
                    'TV'=>'图瓦卢',
                    'TW'=>'台湾',
                    'TZ'=>'坦桑尼亚',
                    'UA'=>'乌克兰',
                    'UG'=>'乌干达',
                    'UM'=>'美国本土外小岛屿',
                    'US'=>'美国',
                    'UY'=>'乌拉圭',
                    'UZ'=>'乌兹别克斯坦',
                    'VA'=>'梵蒂岗',
                    'VC'=>'圣文森特和格林纳丁斯',
                    'VE'=>'委内瑞拉',
                    'VG'=>'英属维尔京群岛',
                    'VI'=>'美属维尔京群岛',
                    'VN'=>'越南',
                    'VU'=>'瓦努阿鲁',
                    'WF'=>'瓦里斯和富图纳',
                    'WS'=>'西萨摩亚',
                    'YE'=>'也门',
                    'YT'=>'马约特',
                    'YU'=>'南斯拉夫',
                    'ZA'=>'南非',
                    'ZM'=>'赞比亚',
                    'ZW'=>'津巴布韦'
            ];

    淘宝ip地址库采集: 详见 http://ip.taobao.com/instructions.php
    返回的数据为json类型:

        {
            "code" : 0, // 0:请求成功;1:请求失败
            "data" : {
                "country" : "\u4e2d\u56fd", // 国家
                "country_id" : "CN", // 国家代码
                "area" : "\u534e\u5317", // 地区
                "area_id" : "100000", // 地区代码
                "region" : "\u5317\u4eac\u5e02", // 省(自治区、直辖市、特别行政区)
                "region_id" : "110000", // 省代码
                "city" : "\u5317\u4eac\u5e02", // 市(地区、自治州、盟及国家直辖市所属市辖区和县)
                "city_id" : "110000", // 市代码
                "county" : "", // 县(市辖区、县级市、旗)
                "county_id" : "-1", // 县代码
                "isp" : "\u4e2d\u56fd\u79d1\u6280\u7f51", // 运营商
                "isp_id" : "1000114", // 运营商代码
                "ip" : "210.75.225.254" // ipv4/ipv6
            }
        }

    淘宝ip地址库相关:http://blog.csdn.net/shishuo365/article/details/38361471

    世界所有国家信息与编码:由联合国统计局统一制定。详见:http://zh.wikipedia.org/wiki/ISO_3166-1
    中国标准网:http://cx.spsp.gov.cn/index.aspx?Token=Token&First=First
    原文件链接:http://vdisk.weibo.com/s/AWGPjgZkFus8?from=page_100505_profile&wvr=6

    中国省份信息与编码:地区、省、市、县以及相应的代码,由中华人民共和国国家统计局统一制定,详见:http://www.stats.gov.cn/tjsj/tjbz/xzqhdm/201401/t20140116_501070.html
    链接:http://wenku.baidu.com/link?url=Uyp0Z-DMdc58SB9ko3mR8TNVz_-DJgRog0ucQEuJQWiV0cjajR5GdyMw7xkEuCu2cA3dfW7j3xLRrK5WWxw1JNh15EXQ1kHW-M63ikNzvvi

    中国有多少个省?

    23个省、4个直辖市、2个特别行政区、5个自治区。
    23个省:河北省(冀)、山东省(齐)、辽宁省(辽)、黑龙江省(黑)、吉林省(吉)、甘肃省(陇)、青海省(青)、河南省(豫)、江苏省(苏)、湖北省(鄂)、湖南省(湘)、江西省(赣)、浙江省(浙)、广东省(粤)、云南省(滇)、福建省(福)、台湾省(台)、海南省(琼)、山西省(晋)、四川省(川)、陕西省(陕)、贵州省(黔)、安徽省(皖)。
    4个直辖市:重庆市、北京市、上海市、天津市。
    5个自治区:广西壮族自治区、内蒙古自治区、西藏自治区、新疆维吾尔自治区、宁夏回族自治区。
    2个特别行政区:澳门特别行政区、香港特别行政区。

    截至2004年12月31日,全国县级以上行政区划共有:23个省,5个自治区,4个直辖市,2个特别行政区;50个地区(州、盟);661个市,其中:直辖市4个;地级市283个;县级市374个;1636个县(自治县、旗、自治旗、特区和林区);852个市辖区。总计:省级34个,地级333个,县级2862个。
    
    展开全文
  • 字符编码的常用种类介绍

    万次阅读 2018-11-06 14:31:10
    字符编码的常用种类介绍 第一种:ASCII码 ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言。它是现今...
  • 实现压缩编码算法——Huffman编码 2. 实现压缩编码算法——Shannon Fano编码 3. 实现压缩编码算法——LZ编码 4. 实现压缩编码算法——算数编码 5. 利用上述压缩算法压缩图像、音频、视频文件,分析压缩算法的性能。...
  • 信源编码与信道编码

    千次阅读 2018-04-20 19:14:18
    信源编码:对输入信息进行编码,优化信息和压缩信息,并打包成符合标准的数据包。信源编码的主要作用是:1....信源编码种类主要包括:Huffman编码、算术编码、L-Z编码,这三种均为无损编码,另外还有一些...
  • 接上一篇博客:课设复习之信息论固定算术编码与译码...自适应编码适合在信源各符号概率未知的情况下进行编码,此时可以将所有种类的符号概率设为相同,之后编码时将传来的符号在该种类下加1,然后在该种类初始符...
  • 字符字节与编码 字符是人们常用的一些记号,比如”1”, “汉”, ...编码是大家对计算机如何使用字节来表示一个字符的约定,可分为ASCII编码,ANSI编码(本地化编码),UNICODE编码(国际化编码)三种。 1.ASCI...
  • 编码

    千次阅读 多人点赞 2019-07-04 16:49:57
    大多数编码器都使用光学传感器来提供脉冲序列形式的电信号, 这些信号可以依次转换成运动、方向或位置信息编码器依运动方式可分为旋转编码器或是线性编码器;按照读出方式编码器可以分为接触式和非接触式两种;...
  • char类型与字符编码

    千次阅读 2014-05-10 20:43:23
    char是字符类型,Java语言对字符采用Unicode字符编码
  • 前言:什么是地理信息编码? 地理信息编码:就是通过联系经度纬度的一种对照表。我们可以通过经度纬度信息查找到相应的地址,也可以把相关的地址转换成相应的经度纬度。 下面是我理解的地理信息模型:(余则成-密码...
  • 材料编码是基础中的基础
  • 那么能否用视频的压缩方式压缩图片,达到上千倍压缩的效果?简单的答案是不能,因为视频压缩时,利用了信息的相关性,能够采用所谓的增量编码,而单一一张图片中,不具有太多的相关性可以利用。
  • MP3中ID3信息编码格式

    千次阅读 2017-07-13 16:54:08
    标签帧组成 4 个字节的帧标识 + 4个字节的内容大小 + 2个标志 + 内容 内容的第1个字节代表了编码格式(00) 0:ASCII (ISO-8859-1) 1:Unicode16 3:UTF-8
  • 视频压缩编码和音频压缩编码的基本原理

    万次阅读 多人点赞 2014-06-03 00:01:20
    本文介绍一下视频压缩编码和音频压缩编码的基本原理。其实有关视频和音频编码的原理的资料非常的多,但是自己一直也没有去归纳和总结一下,在这里简单总结一下,以作备忘。
  • 信息分类编码技术研究及应用

    千次阅读 2008-01-07 10:27:00
    本文从烟草机械制造企业信息化过程入手,介绍信息分类编码在企业信息化中的重要性, 对信息分类编码技术进行了较为详细的阐述,重点介绍烟草机械制造企业信息分类编码的方法、信息分类编码的原理与编码的内容。...
  • 文本编码

    万次阅读 2016-03-01 00:05:49
    文本编码 文本编码这个问题自三年前就困扰着我,当时是用Python处理多国语言时出现的bug,最后问题解决了,但其中具体逻辑并不懂。后来零零散散接触了不少资料,算是大致弄明白,记录如下。 unicode与ascii等编码...
  • 文本文件的编码方式及内容类型是应用层测试中文本测试关注的重点,常见的文本编码方式为UTF -8、GBK2312、GBK、BIG5、GB18030等等,常见的文本内容类型为TXT、HTML、XML、Torrent、WML、XHTML等。 下面详细介绍下...
  • 赫夫曼编码Huffman的matlab编码实现

    千次阅读 2019-10-29 20:38:34
    赫夫曼编码是我们经常使用的一种类型编码,它是一种即时码,很多优点,下面我们使用matlab语言来实现huffman编码的过程。 首先,我们输入一组概率,这里以[0.512 0.128 0.128 0.032 0.128 0.032 0.032 0.008]为例...
  • 基础数据类型转换-编码

    千次阅读 2020-03-15 17:42:04
    数据类型间的转换,编码知识
  • ASCII编码

    千次阅读 2020-01-11 12:29:50
    ASCII ((American Standard Code for Information Interchange): 美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言。它是最通用的信息交换标准,并等同于国际标准...
  • 前言材料编码还有几种方案,这里给大家简单介绍一下电力系统的KKS编码和中石化的物资分类码。
  • 硬盘录像机的10个编码参数是哪些

    千次阅读 2019-01-23 16:19:43
    是否常常会被指导修改录像机的编码参数? 是否常常对于需要更改的参数存在疑惑,这个参数是什么?为什么需要更改?怎么更改比较合适? 且听贵阳监控今日为你一一解释 码流类型 码流类型分复合流和视频流两种。 复合...
  • 字符编码

    千次阅读 2015-12-25 19:25:59
     在编码表中,每个字符都对应的编码编码是整数,最终在计算机中存储的是字符的编码,而不是字符本身(因为计算机数据都是二进制数值,所以字符本身是无法存储的)。  当我们存储字符’A’时,其实是通过编码表...
  • 关于runtime的文章中多次提到了类型编码,下边说说类型编码到底是什么鬼。 相关链接: 官方文档一 官方文档二 YYModel 源码历险记<二> 关于变量类型编码 类型编码(Type Encodings) 类型编码(Type ...
  • Redis数据类型编码

    万次阅读 2020-04-28 18:12:48
    Redis五大数据类型 (一)String 字符串 string是redis最基本的类型,一个key对应一个value。string类型是二进制安全的,意思是redis的string可以包含任何数据,比如图片或者序列化的对象 。string类型是redis最基本...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 710,267
精华内容 284,106
关键字:

信息编码有哪些类型