专利名称:一种顺序压缩/解压缩数据的方法及装置的制作方法
技术领域:
本发明涉及一种压缩/解压缩数据的方法和装置,尤其涉及一种顺序压缩/解压缩数据的方法及装置。
目前,顺序压缩/解压缩数据是一种常用的对数据进行压缩/解压缩的方法。该方法是用在压缩过程中已经处理过的数据作为参考来压缩/解压缩后面的数据从而减少冗余,典型的顺序压缩方案有LZ77和Zlib。Zlib是基于Huffman编码和LZ77的一种顺序压缩方案。
图1是一种现有的顺序压缩/解压缩数据的装置的结构示意框图。如图1所示,该装置包括顺序编码器120,用于将输入的N个数据段作为一个整体一起进行顺序编码压缩;存储器130,用于保存压缩好的数据;顺序解码器140,用于对压缩后的数据进行顺序解码,并利用数据性质或者一个索引表来将N个数据段分离出来。这样的压缩方法能获得最大的压缩效率,数据段之间的冗余度可以被节约。特别是如果该N个数据段具有相同或相似的数据结构,则压缩后的数据的冗余会大大减少。
然而,在图1所示的装置中,想要对压缩后的每个数据段进行随机存取是不可能的。由于在图1所示的压缩过程中,后一个数据段的压缩,如数据段K(K为1-N中的任一个数),要依赖于前面所有已压缩的数据段,即数据段1-K。因此,在进行解压缩时,必须首先对该数据段(数据段K)前的所有被压缩的数据段(数据段1-K)进行解压缩,然后,该压缩后的数据段(数据段K)才能被解压缩出来。一个极端的例子是,为了从压缩后的数据中获得最后的一个数据段(数据段N),在数据段N之前所有被压缩的数据段都必须被依次解压缩并被一一抛弃,一直解压缩到最后才能获得数据段N。
图2是另一种现有的顺序压缩/解压缩数据的装置的结构示意框图。与上述压缩方法不同的是,数据段彼此之间独立地被压缩/解压缩。如图2所示,该装置包括顺序编码器120,用于对数据段K独立地进行顺序压缩,该数据段K为1-N个数据段中的任意一个;存储器130,用于保存压缩好的数据段K;顺序解码器140,用于对压缩后的数据段K进行解压缩还原出数据段K。在上述压缩过程中,该N个数据段被分别压缩/解压缩,每一个数据段的压缩/解压缩过程是相互独立的,后一数据段的顺序压缩/解压缩并不依赖于前面已压缩的数据段。如要通过解压缩来获得数据段K,则只要直接从存储器130中找到压缩后的数据段K即可进行顺序解压缩,而不需要对其前面压缩的数据段进行解压缩。由于本装置是独立地压缩数据段,因此也就获得了对这些数据段进行随机存取的途径。然而,也正因为各个数据段是被独立压缩的,因而它们之间的冗余不能被利用,从而导致整个数据的压缩率很低。
因此,需要一种新的顺序压缩/解压缩数据的方法及装置,它既能有效对数据进行压缩也能够随机存取数据。
发明内容
本发明的目的之一是解决现有的顺序压缩/解压缩方案(scheme)的缺陷,提供一种新的顺序压缩/解压缩数据的方法及装置,从而能有效对数据进行顺序压缩也能够随机存取数据。
本发明提供一种顺序压缩一个数据段的方法,该数据段具有一种数据结构。首先,获取多个压缩参数;然后,根据所获得的压缩参数对该数据段进行顺序压缩,从而得到一个压缩后的数据段。其中该数据段可以是通过对数据进行预处理来获得。该压缩参数是来自于一个存储装置,当然,该压缩参数还可通过对具有该数据结构的一个模板进行压缩后得到。对具有该数据结构的一个模板进行压缩后除了得到所述的压缩参数外,还得到一个压缩后的模板。该压缩后的模板与压缩后的数据段被分别存储,或者该压缩后的模板被丢弃。
与之相对应地,本发明还提供一种顺序解压缩一个压缩后的数据段的方法,该数据段具有一种数据结构。首先,获取多个解压缩参数;然后,根据所获得的解压缩参数对该压缩后的数据段进行顺序解压缩,从而得到一个解压缩后的数据段。该解压缩参数是来自于一个存储装置,当然,该解压缩参数还可通过对一个压缩后的模板进行顺序解压缩后得到,该模板具有所述的数据结构。对该压缩后的模板进行顺序解压缩后除了得到所述的解压缩参数外,还得到一个解压缩后的模板。该解压缩后的模板被丢弃。
本发明还提供一种顺序压缩一个数据段的装置,该装置包括一个获取装置和一个压缩装置,该数据段具有一种数据结构。该顺序压缩一个数据段的装置还可有选择地包括一个预处理装置、一个存储装置和一个丢弃装置。该获取装置,用于获取多个压缩参数;该压缩装置,用于根据所获得的压缩参数,对所述的数据段进行顺序压缩,从而得到一个压缩后的数据段。该压缩装置,还用于对具有该数据结构的一个模板进行顺序压缩,从而得到所述的压缩参数和一个压缩后的模板;该预处理装置,用于对数据进行预处理从而获得所述的数据段;该存储装置,用于存储所述的压缩参数;该丢弃装置,用于丢弃所述压缩后的模板。
与之相对应的,本发明提供一种顺序解压缩一个压缩后的数据段的装置,该装置包括一个获取装置和一个解压缩装置。该顺序解压缩一个压缩后的数据段的装置还可有选择地包括一个存储装置和一个丢弃装置。该获取装置,用于获取多个解压缩参数;该解压缩装置,用于根据所获得的解压缩参数,对压缩后的数据段进行顺序解压缩,从而得到一个解压缩后的数据段,该数据段具有一种特定的数据结构。该解压缩装置还用于对一个压缩后的模板进行顺序解压缩,从而得到所述的解压缩参数和一个解压缩后的模板,该模板具有所述的数据结构;该存储装置,用于存储所述的解压缩参数;该丢弃装置,用于丢弃该解压缩后的模板。
本发明提供的上述顺序压缩/解压缩数据的方法及其装置,在对于一个具有特定数据结构的数据段进行压缩后,其数据结构部分(模板)可被滤出,故可提高数据的压缩比;在对多个具有特定数据结构的数据段进行分别压缩后,每一个数据段的数据结构部分均可被滤出,但可仅保留一个压缩后的模板,或丢弃所有的压缩后的模板,故可大大提高数据的压缩比,又能够对各个数据段进行随机处理。
通过参照结合附图所进行的如下描述和权利要求,本发明的其它目的和成就将是显而易见的,并对本发明也会有更为全面的理解。
本发明通过实例的方式,参照附图进行详尽的解释,其中图1是一种现有的顺序压缩/解压缩数据的装置的结构示意框图;
图2是另一种现有的顺序压缩/解压缩数据的装置的结构示意框图;图3是根据本发明的一个实施例的一个顺序压缩一个数据段的装置的结构示意框图;图4是根据本发明的一个实施例的一个顺序压缩一个数据段的流程图;图5是根据本发明的一个实施例的一个顺序解压缩一个压缩后的数据段的装置的结构示意框图;和图6是根据本发明的一个实施例的一个顺序解压缩一个压缩后的数据段的流程示意图。
在所有的附图中,相同的参照数字表示相似或相同的特征和功能。下面参照附图结合实施例对本发明进一步说明。
具体实施例方式
图3是根据本发明的一个实施例的一个顺序压缩一个数据段的装置的结构示意框图,该数据段具有一种数据结构。装置300包括一个获取装置310和一个压缩装置320。装置300还可包括一个预处理装置330、一个存储装置340和一个丢弃装置350。
获取装置310用于获取多个压缩参数,这些压缩参数指明了具有该数据结构的模板的编码压缩信息,包括这个模板的压缩方式、存储位置、数据结构等信息。该压缩参数可从存储装置340中获得。该压缩参数对应于压缩装置320在压缩完一个具有该数据结构的模板时的内部状态。
压缩装置320用于根据所获得的压缩参数,对待压缩的数据段进行顺序压缩,从而得到一个压缩后的数据段。该压缩装置320还用于对具有该数据结构的一个模板进行顺序压缩,从而得到所述的压缩参数。待压缩的数据来自于预处理装置330,当然,亦可来自于其它数据源(图中未显示)。
预处理装置330用于对输入的数据进行预处理,从而产生一个符合所述的数据结构的数据段。该数据段是一个动态数据,根据输入数据的不同而变化。例如,XML(eXtensible Markup Language)格式中数据库记录的排版处理单元(publishing process)就是预处理装置的一个适合的实例。如果输入的数据是没有任何内容的空白数据(blank data),则预处理装置330会产生一个具有所述数据结构的一个模板。该模板描述了数据段的数据结构,但不包含任何动态的内容数据。
该预处理装置330可以根据不同的情况输出各种不同类别的数据段。举例来说,可以根据数据库输入的不同类型数据产生不同的数据段,在这种情况下,针对每一种数据段,可以相应地产生一个对应的数据结构的模板以用于压缩相应的数据段。当然,也可以设计一个通用的模板来供所有类型的数据段进行压缩时使用,但该方案只能提供给一个次最佳性能的压缩比。
存储装置340用于存储压缩后的数据段和压缩参数,还可以用于存储压缩后的数据结构的模板。这个存储装置340是一个硬盘,还可以是一个USB(Universal Serial Bus)盘,也可以是缓存等。但是需要指出的是压缩后的数据段和压缩后的模板需要分别被存储,比如,可以以不同的文件名存储。存储在存储装置340的压缩后的模板是为了在解压缩该数据段时使用。
丢弃装置350用于将压缩后的模板丢弃。该压缩后的模板来自于压缩装置320。为了不占据存储装置的太多空间,也可以将压缩后的模板丢弃。
装置300的运行过程详见下面图4所述。
图4是根据本发明的一个实施例的一个顺序压缩一个数据段的流程图。该数据段具有一种数据结构。首先,获取具有该数据结构的一个模板(步骤S410)。该模板可通过对不包含任何有效内容的数据进行预处理后得到。在该预处理过程中,可在该模板的结尾处加上一个标志,如文件结束标志,该标志用于表明该模板文件的结束位置。
如下所述是一个电视节目数据的数据结构<radioshow radioshowID=″″>
<description></description>
<start_time></start_time>
<end_time></end_time>
<party><host></host><participant></participant></party>
</radioshow>
所述的模板的内容为上述数据结构。
接着,对该模板进行顺序压缩(步骤S420)。具体来说,先初始化编码状态,然后对该模板进行顺序压缩,例如利用Zlib顺序压缩运算法则,从而得到一个压缩后的模板和多个压缩参数。该压缩参数可用于压缩待压缩的数据段。该压缩参数指明了该模板的编码压缩信息及其在压缩装置中的存储位置,包括该模板的压缩方式、数据结构、Huffman列表等信息。需要说明的是Zlib顺序压缩运算法并不是唯一的压缩法则,实施者可以根据自己的需要选择不同的压缩算法。
然后,丢弃该压缩后的模板(步骤S430)。为了不影响整个数据的压缩率和节约存储空间,系统可将压缩后的模板丢弃。由于模板的结尾处具有一个标志,如文件结束标志,当系统读到该标志后,会自动丢弃这个压缩的模板。当然,也可以将压缩后的模板存储在一个本地存储装置的一个特定存储区中,以供将来用于解压缩。特别是在多个具有该数据结构的数据段分别依次按本发明的压缩方式进行压缩时,可以只保留其中一个压缩后的模板,丢弃其余的压缩后的模板。
上述步骤S410-S430是通过对具有该数据结构的一个模板进行顺序压缩从而获取压缩参数的过程。该压缩参数可被存储下来,如存储到一个本地存储装置中,以供在对具有同样/类似数据结构的另一个数据段进行压缩时使用。在这种情况下,如果在一个本地存储装置中已经保存了该压缩参数,则在对另一个具有同样数据结构的数据段进行压缩时,则可以不进行上述步骤S410-S430,即不需要对一个具有该数据结构的模板进行压缩,而可以直接从该存储装置中获得该压缩参数。值得注意的是,在直接从该存储装置中获得该压缩参数前,应先初始化编码状态,以确保前一个流程结束时的压缩参数不会影响本流程。
接下来,获取一个数据段,该数据段具有所述的数据结构(步骤S440)。该数据段是对数据进行预处理来获得,如通过XML(eXtensibleMarkup Language)格式中数据库记录的排版处理单元(publishingprocess)来获得一个符合XML格式的数据段。当然,该数据段亦可来自于其它数据源。
下面的例子可以更具体地说明模板和数据段之间的关系,例如,经过格式预处理后,获得二个电视节目数据的数据段,数据段1是
<radioshow radioshowID=″new talk show″>
<description>a new TV talk show every Friday</description>
<start_time>7pm</start_time>
<end_time>8pm</end_time>
<party><host>Mr.XYZ</host><participant>Mr.ABC</participant></party>
</radioshow>
数据段2是<radioshow radioshowID=″News report″>
<description>news report every evening</description>
<start_time>6pm</start_time>
<end_time>7pm</end_time>
<party><host>Mr.ABC</host><participant></participant></party>
</radioshow>
上述两个数据段的相同之处是具有与上述模板一样的数据结构,不同之处在于每一个数据段包含有不同的有效内容,如在数据段1中的″new talk show″,a new TV talk show every Friday等,在数据段2中的″News report″,news report every evening等。
再接下来,根据已经获取的压缩参数对数据段进行顺序编码压缩(步骤S450),由于该压缩参数包含了具有相同数据结构的模板的压缩信息和存储的地址以及长度等信息,因此,根据该压缩参数在对该数据段进行顺序压缩时,顺序压缩所具有的特性会自动搜寻已经出现过的字符串,当搜寻到曾经在模板中出现过的编码字符串时,就会自动输出该字符串在模板中的出现位置及长度。所以,顺序编码法则会自动将该数据段中与已压缩过的的模板相同的部分以存储地址和长度替代,这个存储地址指向该压缩后的模板,替换后的数据段的大小远远小于原先的数据段。由于借助于压缩该模板过程中产生的压缩参数来对该数据段进行顺序压缩,同时压缩后的模板可被丢弃,因而能够大大提高数据段的压缩率。
最后,存储该压缩后的数据段(步骤S460)。为了不影响压缩率,该压缩后的数据段的存储区域与压缩后的模板的存储区域是不同的,例如,可以以不同的文件名进行存储。
上述实施例完成了对一个数据段的压缩,在很多情况下,需要依次对多个具有相同模板的数据段进行顺序压缩。例如,可以依次对20个电视节目数据(也就是20个数据段)进行压缩,这些电视节目数据经过预处理后具有相同或者相似的数据结构。在根据上述流程S460压缩完一个数据段后,可以继续按上述流程压缩下一个数据段,值得注意的是,在每一个流程的开始,需要初始化编码状态,比如,清空压缩装置中的所有压缩参数,以确保本流程结束时的压缩参数不会影响下一个流程,因为本流程结束时的参数已包括一些对应于该数据段中的有效内容的压缩参数。
图5是根据本发明的一个实施例的一个顺序解压缩一个压缩后的数据段的装置的结构示意框图。该压缩后的数据段是由装置300获得,该数据段具有所述的数据结构。装置500包括一个获取装置510和一个解压缩装置520。装置500还可包括一个存储装置540和一个丢弃装置550。
获取装置510,用于获取多个解压缩参数,这些解压缩参数指明了该压缩后的模板的解压缩信息,包括这个模板的解压缩方式、存储位置、数据结构等信息。该压缩参数可以来自于存储装置540。该解压缩参数对应于解压缩装置520在解压缩完该压缩后的模板时的内部状态。
解压缩装置520,用于根据所获得的解压缩参数,对该压缩后的数据段进行顺序解压缩,从而得到一个解压缩后的数据段。如果无法直接从获取装置510中获得该解压缩参数,则该解压缩装置520还用于对一个该压缩后的模板进行顺序解压缩,从而得到一个解压缩后的模板和所述的解压缩参数,该模板具有所述的数据结构。
存储装置540,用于存储解压缩后的数据段,还可用于存储所述的解压缩参数。
丢弃装置550,用于丢弃解压缩后的模板。
装置500的运行过程详见下面图6所述。
图6是根据本发明的一个实施例的一个顺序解压缩一个的流程图。该压缩后的数据段是由图4流程产生的,该数据段具有所述的数据结构。
首先,获取一个压缩后的模板(步骤S610),该模板具有所述的数据结构。该压缩后的模板是从一个存储装置中获取,也可以由网络或者其他装置传送来。该压缩后的模板还可以通过对一个具有所述数据结构的模板进行顺序压缩来获得。
然后,对该压缩后的模板进行顺序解压缩(步骤S620)。具体来说,在解码状态初始化后,对压缩后的模板进行顺序解压缩,得到一个解压缩后的模板和多个解压缩参数。该解压缩参数可用于解压缩后面的待解压缩的数据段,该解压缩参数包括该压缩后的模板的解压缩信息,包括解压缩方式、地址和数据结构等信息。该顺序解压缩可以利用Zlib顺序解压缩运算法则。为了节约存储空间,可丢弃该解压缩后的模板(步骤S630),该丢弃可通过该模板的文件结束标志来实现。
上述步骤S610-S630是通过对压缩后的模板进行顺序解压缩从而获取解压缩参数的过程。该解压缩参数可被存储下来,如存储到一个本地存储装置中,以供在对的另一个压缩后的数据段进行解压缩时使用,该数据段具有同样/类似数据结构。在这种情况下,如果在一个本地存储装置中已经保存了该解压缩参数,则在对所述的另一个压缩后的数据段进行解压缩时,则可以不进行上述步骤S410-S430,即不需要对一个压缩后的模板进行解压缩,而可以直接从该存储装置中获得该解压缩参数。值得注意的是,在直接从该存储装置中获得该解压缩参数前,应先初始化编码状态,以确保前一个流程结束时的解压缩参数不会影响本流程。
接着,获取一个压缩后的数据段(步骤S640)。该压缩后的数据段可以从一个存储装置中获取,也可以由网络或者其他装置传送而来。
随后,对该压缩后的数据段进行顺序解压缩(步骤S650),该顺序解压缩可以利用Zlib顺序解压缩运算法则。根据已经获得的解压缩参数和压缩的数据段中的存储地址找到相应的替换信息,并把该替换信息替换到解压缩后的数据段,最终得到一个完整的解压缩后的数据段。该解压缩后的数据段具有所述的数据结构,包含特定的有效内容。
最后,存储该解压缩后的数据段(步骤S660)。
上述解压缩过程完成了对一个压缩后的数据段的解压缩,在很多情况下,需要依次对很多个压缩后的数据段进行顺序解压缩,这些数据段具有相同/类似的数据结构。在根据上述流程S660解压缩完一个压缩后的数据段后,可以继续按上述流程解压缩下一个压缩后的数据段,值得注意的是,在每一个流程的开始,需要初始化编码状态,比如,清空压缩装置中的所有解压缩参数,以确保本流程结束时的解压缩参数不会影响下一个流程,因为本流程结束时的参数已包括一些对应于该数据段中的有效内容的解压缩参数。
上述实施例的顺序压缩/解压缩数据的方法,主要是通过预处理过程从而将数据转换为具有相同数据结构的数据段,并且同时得到一个构造该数据段的模板用于压缩/解压缩数据。该方法通过对一个具有一种数据结构的模板的压缩,得到具有同样数据结构的数据段压缩所需要的压缩参数,并根据此参数对数据段进行压缩,并丢弃压缩后的模板,从而得到高压缩率的数据段。同时,由于每个数据段是单独进行顺序压缩的,因此也就能够随机存取每一个数据段。相应地,该方法通过对一个压缩后的模板的解压缩,得到压缩后的数据段解压缩所需要的压缩参数,该数据段与该模版具有同样的数据结构,并根据此参数对压缩后的数据段进行解压缩,从而一个解压缩后的数据段。同时,由于每个数据段是单独进行顺序压缩的,因此也就能够单独地对每一个压缩后的数据段进行解压缩。
下面的实验结果可进一步说明本发明的压缩率相比与现有技术的压缩率的优势。该实验包括以图2所述的技术进行数据段压缩的压缩率为基准,对同样的数据段进行顺序压缩,本发明例的压缩率提高了38.4%,。所有的方法均利用Zlib作为顺序压缩/解压缩的运算法则。以下的表格1对两种结果进行了描述。
表格1实验结果
虽然经过对本发明结合具体实施例进行描述,对于在本技术领域熟练的人士,根据上文的叙述做出的替代、修改与变化将是显而易见的。因此,在这样的替代、修改和变化落入附后的权利要求的精神和范围内时,应该被包括在本发明中。
权利要求
1.一种顺序压缩一个数据段的方法,该数据段具有一种数据结构,包括步骤a.获取多个压缩参数;b.根据所获得的压缩参数,对所述的数据段进行顺序压缩,从而得到一个压缩后的数据段。
2.如权利要求1所述的方法,其中步骤a为对具有所述数据结构的一个模板进行顺序压缩,从而得到所述的压缩参数。
3.如权利要求2所述的方法,其中步骤a还得到一个压缩后的模板。
4.如权利要求3所述的方法,还包括步骤丢弃所述压缩后的模板。
5.如权利要求3所述的方法,还包括步骤分别存储所述压缩后的模板与压缩后的数据段。
6.如权利要求1所述的方法,其中步骤a中所述的压缩参数来自一个存储装置。
7.如权利要求1所述的方法,还包括步骤对数据进行预处理,从而得到所述的数据段。
8.如权利要求1所述的方法,还包括步骤存储所述的压缩后的数据段。
9.一种顺序解压缩一个压缩后的数据段的方法,该数据段具有一种数据结构,包括步骤a.获取多个解压缩参数;b.根据所获得的解压缩参数,对所述压缩后的数据段进行顺序解压缩,从而得到一个解压缩后的数据段。
10.如权利要求9所述的方法,其中步骤a为对一个压缩后的模板进行顺序解压缩,从而得到所述的解压缩参数,该模板具有所述的数据结构。
11.如权利要求10所述的方法,还包括步骤对具有所述数据结构的一个模板进行顺序压缩,从而得到所述的压缩后的模板。
12.如权利要求11所述的方法,所述压缩后的模板来自于一个存储装置。
13.如权利要求10所述的方法,其中步骤a还得到一个解压缩后的模板。
14.如权利要求13所述的方法,还包括步骤丢弃所述的解压缩后的模板。
15.如权利要求10所述的方法,还包括步骤存储所述的解压缩后的数据段。
16.如权利要求9所述的方法,所述的解压缩参数来自于一个存储装置。
17.一种顺序压缩一个数据段的装置,该数据段具有一种数据结构,包括一个获取装置,用于获取多个压缩参数;一个压缩装置,用于根据所获得的压缩参数,对所述的数据段进行顺序压缩,从而得到一个压缩后的数据段。
18.如权利要求17所述的装置,还包括一个预处理装置,用于对数据进行预处理,从而得到所述的数据段。
19.如权利要求17所述的装置,还包括一个存储装置,用于存储所述的压缩参数。
20.如权利要求17所述的装置,其中所述的压缩装置还用于对具有所述数据结构的一个模板进行顺序压缩,从而得到所述的压缩参数和一个压缩后的模板。
21.如权利要求20所述的装置,还包括一个丢弃装置,用于丢弃所述压缩后的模板。
22.一种顺序解压缩一个压缩后的数据段的装置,该数据段具有一种数据结构,包括一个获取装置,用于获取多个解压缩参数;一个解压缩装置,用于根据所获得的解压缩参数,对所述压缩后的数据段进行顺序解压缩,从而得到一个解压缩后的数据段。
23.如权利要求22所述的装置,还包括一个存储装置,用于存储所述的解压缩参数。
24.如权利要求22所述的装置,其中所述的解压缩装置还用于对一个压缩后的模板进行顺序解压缩,从而得到所述的解压缩参数和一个解压缩后的模板,该模板具有所述的数据结构。
25.如权利要求24所述的装置,还包括一个丢弃装置,用于丢弃所述解压缩后的模板。
全文摘要
本发明提供一种顺序压缩/解压缩一个数据段的方法及其装置。本发明首先获取多个压缩/解压缩参数,然后通过这些获得的压缩/解压缩参数对该数据段进行顺序压缩/解压缩,从而得到一个压缩/解压缩后的数据段。该压缩参数者是来自于一个存储装置,当然,该压缩参数还可通过对具有该数据结构的一个模板进行压缩后得到。对具有该数据结构的一个模板进行压缩后除了得到所述的压缩参数外,还得到一个压缩后的模板,该压缩后的模板被丢弃。本发明利用压缩参数对一个具有特定数据结构的数据段进行压缩后,其数据结构部分可被滤出,故可提高数据的压缩比。
文档编号H03M7/30GK1951017SQ200580014935
公开日2007年4月18日 申请日期2005年4月1日 优先权日2004年5月13日
发明者A·莫雷尔 申请人:皇家飞利浦电子股份有限公司