如何判断一个元素在亿级数据中是否存在? 很难吗...

这两天看博客园首页一篇文章,https://www.cnblogs.com/crossoverJie/p/10018231.html

主要是分析一个面试题:

现在有一个非常庞大的数据,假设全是 int 类型。现在我给你一个数,你需要告诉我它是否存在其中(尽量高效)。

虽然文章给的布隆过滤器不能解决面试的这个题的问题,判断不存在和判断存在是两码事。

 

下面给出我的思路,欢迎大家讨论分析。

先假定有1亿个正整数,如何处理。如何初始化这1亿个数,使得来一个数就能快速分析出结果呢?

很直观的一种方法就是某个数存在就给它标记为1,否则标记为0,先假定有一个int.Max长的数组,每个数的值放到它的序号上,比如第一个数是5,那么就在第5位置1,其余类似。

如果用int数组,这样的话,这个数组就很长了,内存可能吃不消。

其实0、1这样的用比特存储就刚刚好,那么每8位的比特合在一起,就是一个byte,每一个byte加一个序号(表示是第几个8位)就能表示8个数是否存在了。那么如果用byte数组长度就是:1亿/ 8 = 12500000长的byte数组即可,这个数组的序号就是第N*8-N*8+8个数的分布情况。比如要查100是否存在这1亿数据中,对100除8取结果和余数,结果确定序号,判断序号对应的数的二进制在余数位是否为1即可。

同理,用int可以存32个数,就是1亿/32长的int数组;用long可以存64个数,就是1亿/64长的long数组即可。

无论是用byte、int还是long数组,大小都查不到,约: 1亿/ 32 * 4 / 1024 / 1024 ≈ 12(MB),也就是说用这么一点内存即可解决问题。

对于负数的处理,无非再用一个数组来存下即可。

那么如果数据多于1亿,比如10亿,百亿甚至更多怎么办呢?

很简单,存在数据库里面嘛,一个表俩字段(序号+值)即可,建个索引,很容易就能支持海量数据的处理了,这样扩展性的问题也就解决了。

 

一时兴起写的,排版请见谅。欢迎大家讨论。

转载于:https://www.cnblogs.com/wilsonLee/p/10038152.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用Matlab下载googlefinance上面的option数据版本2012a-getoption.m 本帖最后由 1989111 于 2014-3-31 12:00 编辑 之前一直潜水,但是后来写了点程序回馈大家,献丑了!大家都知道下载yahoo 或者google的的股票数据API,但是option他们没有提供API。 所以,一般的entry level的数据拿daily的就好了. 所以今天鄙人讲讲怎么在google finance 拿option的数据. 一下方法,也是鄙人自创的,用的是matlab,code也很原始,但是用来抛砖引玉,也是极好的. 大家在matlab里面自创一个function,复制粘贴一下就好了,用法很简单, ticker用string的名字输入就好,例如[call,put]=getoption;,就可以得到当天option,call 和put的数据了. 下面是程序源代码: function [calls,puts]=getoption QQ截图20140330224814.png 请注意源代码里面没有这一句。因为我木有权限发url! sourcefile=urlread;目的有三:1. 我不读取网页数据,以上的修改过的link是以下下载链接, output是JSON 文件,属于google API的范畴. 显得高端大气上档次一些. 用正则表达式读网页拖慢网络速度,于是改用,这个人家网站自己提供的下载链接,或者用code:  A=urlwrite; B=importdata; 然后对B做后面的正则表达式处理,这样可以减少对网站的资源占用.2. 读取网页不可靠,网页上很多冗余信息,对扒数据没啥用处, JSON由于有API提供的接口,写作方式比较固定,几乎没有冗余信息,读取工作顺利,出错概率小.3. JSON 文件在java里面可以直接读取,如果用matlab在java里面写得话会很方便,但是哥还是坚持用低调而奢华的用正则表达式读取JSON文件, 大家可以用word打开JSON文件,看看里面的格式,写得挺整齐的.                                 下面的code照旧,写得不好不要见怪,多谢各种给我的代码提供意见的热心码农,另外在一位热心网友的留言下我找到了如何下载全部option的办法, 感谢那位网友提供的帮助,他给我的指点实质上告诉了我:其实google整个网页的数据呈现就是以JSON文件的读取做基础的! 这也是我作此修改的最大原因,以期达到更大可靠性.但是人家是做有偿服务的,所以我不能贴出来抢别人生意,请大家见谅 callstart=regexpi; [locations,datefile]= regexp; strike= regexp; bid= regexp; ask= regexp; volume=regexp; price=regexp; OpenInterest=regexp; Expiration=regexp; for i=1:length     strike{i}= regexp;     bid{i}= regexp;     ask{i}= regexp;     volume{i}= regexp;     price{i}= regexp;     OpenInterest{i}= regexp;     Expiration{i}= regexp\w.*', 'match'); end index1=find ; index2=find ; A={price{index1};strike{index1};bid{index1};ask{index1};volume{index1};OpenInterest{index1};Expiration{index1}}; B={price{index2};strike{index2};bid{index2};ask{index2};volume{index2};OpenInterest{index2};Expiration{index2}}; A=A'; B=B'; for i=1:length     calldata.price{i}= str2double;     calldata.strike{i}=str2double;     calldata.bid{i}=str2double;     calldata.ask{i}=str2double;     calldata.Volume{i}=str2double;     calldata.OpenInterest{i}=str2double;     calldata.Expiration{i}= cell2mat; end for i=1:length putdata.price{i}=str2double; putdata.strike{i}=str2double; putdata.bid{i}=str2double; putdata.ask{i}=str2double; putdata.Volume{i}=str2double; putdata.OpenInterest{i}=str2double; putdata.Expiration{i}= cell2mat; end   calls=dataset({calldata.strike','Strike'},{calldata.price','Price'},{calldata.bid','Bid'},{calldata.ask','ask'},...       {calldata.Volume','Volume'},{calldata.OpenInterest','Open Interest'},{calldata.Expiration','Expiration'});   puts=dataset({putdata.strike','Strike'},{putdata.price','Price'},{putdata.bid','Bid'},{putdata.ask','ask'},...       {putdata.Volume','Volume'},{putdata.OpenInterest','Open Interest'},{putdata.Expiration','Expiration'}); end 下面鄙人就来讲解一下里面的代码是干啥的. 第一行当然是输入一个ticker,输入的形式必须是string的,用matlab的话说就是'XXXX', XXXX代表ticker; 第二行,是吧一个网址和ticker串起来,因为google finance上的网址都有规律,所以如果你要搜索google的option今天的报价, 有图为证:                                 所以在执行当,已经有了一个string 变量url,它指向goog finance网址: 然后我们看看是不是:                                 仔细一看,真的是, 然后第二句就是读取这个网页的源文件, 简单说来就是我们打开了这个网页,然后read source file就会出来各种字母的那个页面 然后再看看后面的code callstart=regexpi; [locations,datefile]= regexp; 这个东西是叫做matlab正则表达式的应用,想系统学的同学可以上网搜,比我讲的要好, 我只是要用的时候拿出来看, 上图:                                 大家看到strike的规律没有? 都是strike 后面跟着一个价格, 所以,下面这个code就是讲得是匹配含有{xxx strike.xxx}的最小长度的字符.*? 的意思就是尽可能短的字符 [locations,datefile]= regexp; 然后大家可以打开datefile去看看 找到的匹配字符 大概是这个模样: {cid:"216439834517106",name:"",s:"GOOG130830P00710000",e:"OPRA",p:"-",c:"-",b:"-",a:"0.45",oi:"0",vol:"-",strike:"710.00",expiry:"Aug 30, 2013"} 这个算是一个元素,datefile里面有好多个这样的元素.... 再看下面的语句,明白了上面的,下面的也就不难理解了 strike= regexp; bid= regexp; ask= regexp; volume=regexp; price=regexp; OpenInterest=regexp; Expiration=regexp; 这几个就是在{cid:"216439834517106",name:"",s:"GOOG130830P00710000",e:"OPRA",p:"-",c:"-",b:"-",a:"0.45",oi:"0",vol:"-",strike:"710.00",expiry:"Aug 30, 2013"}里面找含有strike:".*?",b:".*?"等等的字符,于是乎我们又进了一步,把响应的字符都找出来了. 得到了price大概像这个东西 ',p:"-"'        ',p:"-"'        ',p:"-"'        ',p:"-"'        ',p:"-"'        ',p:"-"'        ',p:"-"'        ',p:"0.40"'        ',p:"0.45"'        ',p:"0.10"'        ',p:"0.10"' 其他的例如expiration啥的大概都差不多. 到这里为止,我们要的数据都已经扒下来了,但是这样的数据存在的形式是在让人蛋疼,于是乎我们做一下的工作 for i=1:length     strike{i}= regexp;     bid{i}= regexp;     ask{i}= regexp;     volume{i}= regexp;     price{i}= regexp;     OpenInterest{i}= regexp;     Expiration{i}= regexp\w.*', 'match'); end 这个讲的是既然我们找到了那些数据,数据总是跟着p:"0.10",这样子多难看啊, 拿price的例子来说,price{i}= regexp; 想要做的意思就是,遍历price这个向量里面每一个元素, 只留下xxx.xxx的数据,[0-9]{1,}表示至少出现一次,[0-9]{1,}.[0-9]{1,}则表示把一个含有小字读取出来, 于是p:"0.10"就会变成0.10啦,同理跟其他的也是一样的. 然后就是 index1=find ; index2=find ; A={price{index1};strike{index1};bid{index1};ask{index1};volume{index1};OpenInterest{index1};Expiration{index1}}; B={price{index2};strike{index2};bid{index2};ask{index2};volume{index2};OpenInterest{index2};Expiration{index2}}; 当时我留了call start这个变量没讲,是因为这个相当于一个路标,表示着call 和put的分界线, find这个函只不过是找到大于call start和小于它的相对位置而已. index1 和index2都含有了put 和 call的相对位置. 后面的没啥好说了,就是data转换输出的东西,A是call,B是put的数据 这里没啥好说的,就是为了输出方便,好看, 需要说明的是这里用了matlab的dataset和cell函,因此,获得的数据不能够直接拿来做向量运算,如果要用到,要需要做一下转换,dataset2cell,然后cell2double的转换,这样的话就可以变成一般的double型的变量来运算啦. 有图为证:                                 然后再说一下这个函的缺点,第一,变成dataset和cell要转换,这是一个缺点.第二, 不能拿历史数据,这个我知道啊,option 的历史数据都是要钱的,屌丝只能能够每天跑这个程序一次,自己建立一个自己需要的option pricec的数据库了. 需要指出的是google finance有15min的延迟,因此,intraday的数据只要你跑程序多,是可以拿到的.   这是程序代码[/align][align=left][align=left]function [calls,puts]=getoption[/align] [align=left]sourcefile=urlread;[/align] [align=left]callstart=regexpi;[/align][align=left][locations,datefile]= regexp;[/align][align=left]strike= regexp;[/align][align=left]bid= regexp;[/align][align=left]ask= regexp;[/align][align=left]volume=regexp;[/align] [align=left]price=regexp;[/align][align=left]OpenInterest=regexp;[/align][align=left]Expiration=regexp;[/align][align=left]for i=1:length[/align][align=left]    strike{i}= regexp;[/align][align=left]    bid{i}= regexp;[/align][align=left]    ask{i}= regexp;[/align][align=left]    volume{i}= regexp;[/align][align=left]    price{i}= regexp;[/align][align=left]    OpenInterest{i}= regexp;[/align][align=left]    Expiration{i}= regexp;[/align][align=left]end[/align] [align=left]index1=find ;[/align][align=left]index2=find ;[/align][align=left]A={price{index1};strike{index1};bid{index1};ask{index1};volume{index1};OpenInterest{index1};Expiration{index1}};[/align][align=left]B={price{index2};strike{index2};bid{index2};ask{index2};volume{index2};OpenInterest{index2};Expiration{index2}};[/align][align=left]A=A';[/align][align=left]B=B';[/align] [align=left]for i=1:length[/align] [align=left]    calldata.price{i}= str2double;[/align][align=left]    calldata.strike{i}=str2double;[/align][align=left]    calldata.bid{i}=str2double;[/align][align=left]    calldata.ask{i}=str2double;[/align][align=left]    calldata.Volume{i}=str2double;[/align][align=left]    calldata.OpenInterest{i}=str2double;[/align][align=left]    calldata.Expiration{i}= cell2mat;[/align][align=left]end[/align][align=left]for i=1:length[/align][align=left]putdata.price{i}=str2double;[/align][align=left]putdata.strike{i}=str2double;[/align][align=left]putdata.bid{i}=str2double;[/align][align=left]putdata.ask{i}=str2double;[/align][align=left]putdata.Volume{i}=str2double;[/align][align=left]putdata.OpenInterest{i}=str2double;[/align][align=left]putdata.Expiration{i}= cell2mat;[/align][align=left]end[/align] [align=left]  calls=dataset;[/align][align=left]  puts=dataset;[/align][align=left]end[/align] [/align] [align=left]复制代码 复制代码
数据库范式(范式,数据库设计范式,数据库的设计范式)是符合某一种级别的关系模式 的集合。构造数据库必须遵循一定的规则。在关系数据库,这种规则就是范式。关系 数据库的关系必须满足一定的要求,即满足不同的范式。目前关系数据库有六种范式 :第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、第四范式(4NF)、第五范 式(5NF)和第六范式(6NF)。满足最低要求的范式是第一范式(1NF)。在第一范式的 基础上进一步满足更多要求的称为第二范式(2NF),其余范式以次类推。一般说来, 据库只需满足第三范式(3NF)就行了。下面我们举例介绍第一范式(1NF)、第二范式 (2NF)和第三范式(3NF)。 在创建一个数据库的过程,范化是将其转化为一些表的过程,这种方法可以使从数据 库得到的结果更加明确。这样可能使数据库产生重复数据,从而导致创建多余的表。范 化是在识别数据库数据元素、关系,以及定义所需的表和各表的项目这些初始工 作之后的一个细化的过程。 下面是范化的一个例子 Customer Item purchased Purchase price Thomas Shirt $40 Maria Tennis shoes $35 Evelyn Shirt $40 Pajaro Trousers $25 如果上面这个表用于保存物品的价格,而你想要删除其一个顾客,这时你就必须同 时删除一个价格。范化就是要解决这个问题,你可以将这个表化为两个表,一个用于存 储每个顾客和他所买物品的信息,另一个用于存储每件产品和其价格的信息,这样对其 一个表做添加或删除操作就不会影响另一个表。 关系数据库的几种设计范式介绍 1 第一范式(1NF) 在任何一个关系数据库,第一范式(1NF)是对关系模式的基本要求,不满足第一范式 (1NF)的数据库就不是关系数据库。 所谓第一范式(1NF)是指数据库表的每一列都是不可分割的基本数据项,同一列不能 有多个值,即实体的某个属性不能有多个值或者不能有重复的属性。如果出现重复的 属性,就可能需要定义一个新的实体,新的实体由重复的属性构成,新实体与原实体之 间为一对多关系。在第一范式(1NF)表的每一行只包含一个实例的信息。例如,对于 图3-2 的员工信息表,不能将员工信息都放在一列显示,也不能将其的两列或多列在一 列显示;员工信息表的每一行只表示一个员工的信息,一个员工的信息在表只出现 一次。简而言之,第一范式就是无重复的列。 2 第二范式(2NF) 第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必 须先满足第一范式(1NF)。第二范式(2NF)要求数据库的每个实例或行必须可以 被惟一地区分。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。如 图3-2 员工信息表加上了员工编号(emp_id)列,因为每个员工的员工编号是惟一的,因此 每个员工可以被惟一区分。这个惟一属性列被称为主关键字或主键、主码。 第二范式(2NF)要求实体的属性完全依赖于主关键字。(即主关键字就代表了所有属性 ,决定 了所有属性)所谓完全依赖是指不能存在仅依赖主关键字一部分的属性,如果存在,那 么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之 间是一对多的关系。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识 。简而言之,第二范式就是非主属性非部分依赖于主关键字。 3 第三范式(3NF) 满足第三范式(3NF)必须先满足第二范式(2NF)。简而言之,第三范式(3NF)要求一 个数据库表不包含已在其它表已包含的非主关键字信息。例如,存在一个部门信息 表,其每个部门有部门编号(dept_id)、部门名称、部门简介等信息。那么在图3- 2的员工信息表列出部门编号后就不能再将部门名称、部门简介等与部门有关的信息再 加入员工信息表。如果不存在部门信息表,则根据第三范式(3NF)也应该构建它,否 则就会有大量的数据冗余。简而言之,第三范式就是属性不依赖于其它非主属性。 数据库设计三大范式应用实例剖析 数据库的设计范式是数据库设计所需要满足的规范,满足这些规范的数据库是简洁的、 结构明晰的,同时,不会发生插入(insert)、删除(delete)和更新(update)操作 异常。反之则是乱七八糟,不仅给数据库的编程人员制造麻烦,而且面目可憎,可能存 储了大量不需要的冗余信息。   设计范式是不是很难懂呢?非也,大学教材上给我们一堆学公式我们当然看不懂 ,也记不住。所以我们很多人就根本不按照范式来设计数据库。   实质上,设计范式用很形象、很简洁的话语就能说清楚,道明白。本文将对范式进 行通俗地说明,并以笔者曾经设计的一个
浅谈时尚大数据分析 作者:史英杰 杨 珂 来源:《国市场》 2020年第25期 史英杰 ,杨 珂 (北京服装学院 信息工程学院, 北京 100029) [摘 要]文章分析在数据驱动背景下时尚大数据分析的现状和应用前景,介绍三种典型的时尚大数据分析案例,希望为相关领域的研究人员提供一定参考。 [关键词]时尚大数据数据驱动;数据分析 [DOI]10.13939/j.cnki.zgsc.2020.25.188 1 引言 互联网技术及移动技术的兴起促进了电子商务、社交网络的飞速发展,使得时尚相关数据量达到了前所未有的高度,而服装工业的决策也开始走向数据驱动的模式。采用大数据技术对海量的服装时尚数据进行分析,对科学研究和服装工业的发展都有巨大的价值。大数据分析能够应用于时尚产业领域并不偶然,因为两者有较强的兼容性,主要植根于三个要素:数据海量性、多样性和快速性。此外,时尚数据还具有时间相关性和主观性。时尚本身就是人类社会文化的一部分[1],因此时尚数据除了涵盖服装的廓形、纹理、颜色等物理属性外,还存在一定的主观本质,受到时间、地域等多种因素的综合影响。时尚分析过程应当考虑到多种因素的相关性,减少估计或预测结果的偏差。 2 时尚大数据分析典型案例 2.1 谷歌流行趋势预测 谷歌积累了大量来自全球用户的搜索日志,2016年谷歌公司发布了时尚趋势报告Fashion Trends。基于2014-2016年的时装搜索日志,谷歌分析了2016年的流行趋势,包括当年处于上升、下滑趋势的流行时尚元素等。这些不同的风格元素代表了2016年主流时尚,不仅为用户提供了穿搭参考,还为时尚工业厂商提供了重要的设计及生产链参考。 2.2 Stitch Fix时尚定制 浅谈时尚大数据分析全文共3页,当前为第1页。 浅谈时尚大数据分析全文共3页,当前为第1页。 Stitch Fix通过分析用户的个人穿衣风格、尺寸、偏好等信息,为不同用户定期定制不同风格的服装和服饰。如图2所示,Stitch Fix利用公司积累的用户反馈信息分析时尚趋势和周期性变化[2],将用户对时尚元素的积极或消极反馈转化成伯努利实验。针对某一时尚元素,用户正面选择的概率和它的流行程度有关。选择为1的概率越大,则说明该元素越受欢迎,可以作为是否流行的判断。 2.3 Data Dress App 谷歌和Ivyrevel合作推出了一款个性化推荐App--"Data Dress"。用户安装Data Dress后,该App开始监测用户的日常活动、生活习惯和位置信息等。数据收集后,Data Dress开始分析用户的穿衣喜好,结合谷歌的推荐算法向用户推荐并定制个性化的服饰。Data Dress将用户的生活方式数据带入到推荐和时尚单品设计,提供了一种全新的时尚消费模式。 3 结语 传统的时尚分析使用历史数据和直觉来预测客户需求,然而面临更加快速变化的时尚趋势,仅凭传统的分析方法,很难准确及时地预测出时尚潮流的发展趋势。将大数据技术应用于海量的时尚数据,可分析时尚产业的整体格局以及流行趋势,为制定合适的商业战略提供重要参考。目前时尚大数据分析已经有部分研究工作出现,然而时尚大数据的特点使得其分析面临较大挑战,为国内外研究人员提供了广阔的研究空间。 参考文献: [1] BOLLACKER K, DIAZ R, LI X. Beyond clothing ontologies:modeling fashion with subjective infletworks[C].San Francisco :Proceedings of 2016 KDD workshop on machine learning meets fashion,2016. 浅谈时尚大数据分析全文共3页,当前为第2页。 浅谈时尚大数据分析全文共3页,当前为第2页。 [2] ROBERTO S,DARAGH S,PAOLO. Detection of fashion trends and seasonal cycles through the analysis of implicit and explicit client feedback[C].Proceedings of the KDD2016 Workshop of "Machine learning meets fashion", 2016. [基金项目]北京服装学院高水平教师队伍建设专项资金资助项目(项目编号:BIFTQG201803);北京市服装产业字化工程技术研究心开放课题项目(项目编号:KJCX1902-30299/009);北京市教委科技计划项目(项目编号:SQKM201810012010)。 浅谈时尚大数据分析全文共3页,当前为第3页。 浅谈时尚大数据分析全文共3页,
计算机网络数据库存在的安全威胁全文共7页,当前为第1页。计算机网络数据库存在的安全威胁全文共7页,当前为第1页。计算机网络数据库存在的安全威胁 计算机网络数据库存在的安全威胁全文共7页,当前为第1页。 计算机网络数据库存在的安全威胁全文共7页,当前为第1页。 随着计算机网络技术的不断发展,数据库技术的应用也越来越广泛。但同时也使得数据资源容易因为各种各样的原因而被泄露更改或者是破坏。对整个计算机网络系统的运行构成了极大的威胁。这其既有黑客攻击的威胁,也有数据库本身存在漏洞的因素。故此,对网络数据库技术存在的安全漏洞一定要进行全而的查找分析,有针对性的提出应对的措施。以期可以达到保证网络系统正常运行的目的。 1计算机网络数据库的安全保障工作需重点把关的问题 对计算机网络数据库进行有针对性的安全保护措施是非常有必要的,这样做不但可以有效的避免数据库一些数据资源的丢失或者是被篡改的情况发生,而且也可以在一定程度上阻止一些黑客利用安全漏洞进行非法入侵的现象。 对网络数据库的防护手段主要是侧重于以下几点:第一,逻辑完整性。所谓逻辑完整性就是要对整个数据库的整体结构实施监管保护。比如:如果对某一个字段进行更改的时候,不会造成其他字段的损坏。第二,物理完整性。数据的物理完整性实际上就是指数据不会因为自然或者物理故障遭到破坏,比如说电力或者是计算机故障等等。第三,元素安全性。就是要保证数据库的每一个元素都是正确的。第四,控制用户访问的权限。一定要利用各种程序设置访问的权限,并规定只有通过授权的用户才有资格访问数据库。第五,可审计性。进行必要的保护手段,实现对数据库个元素的追踪存取以及修改。第六,可计算机网络数据库存在的安全威胁全文共7页,当前为第2页。计算机网络数据库存在的安全威胁全文共7页,当前为第2页。用性。通过权限用户充分拥有对数据库进行访问的资格。第一七,身份的验证。对访问数据库的用户进行严密的身份验证以及审计追踪。防止安全隐患乘虚而入。 现如今,网络技术仍然在不断的向前进步发展,网络数据库的安全威胁也在不断的升级。因此,我们对于网络数据库的安全防护也不能仅仅局限于传统的数据库管理层。要把管理的触角伸向保护账号安全以及合理设置访问权限等等方面。 2网络数据库现存的安全漏洞 目前,信息技术以及互联网的不断普及。在这样的环境背景之下,网络数据库的安全会受到以下问题的影响: 2.1在数据库的下载方面 如果通过使用一些相关工具的话(比如说暴库技术),可以很快速的将数据库的各项情况具体定位(一般情况下都是使用%5c命令)。虽然并不能保证每次都可以成功暴库,但是出现暴库的概率是非常高的。在得到了地址之后,再通过IE浏览器输入,之后下载到本地磁盘就可以得到用户名和密码。 2.2注入SQL 在如今的互联网应用,WEB服务器大多都是在设完防火墙之后才布置的,一般来讲只会开放80端口。因为非法入境的黑客朋友无法进入其他的端口。因此,80端口成为了他们的攻克目标。他们所使用的方式一般会以注入SQL为主。有一些程序的编辑人员在编写程序代码的时候会忽略掉对用户输入数据正确性的有效识别。这就为应计算机网络数据库存在的安全威胁全文共7页,当前为第3页。计算机网络数据库存在的安全威胁全文共7页,当前为第3页。用程序埋下了许多的安全隐患。通过客户端进行代码传输,收集服务器与处理程序的数据信息。以这种方式获取所需数据的就被称为注入SQL。注入SQL可以按照常规的方式访问80端口。就跟普通的Web网页浏览访问的效果是一样的。因此,注入SQL对于防火墙来说是易容高超的敌人,防护墙对注入SQL无法获得预警信息。如果管理员再疏于审核检查,那么这种侵入是极难被发现的。 2.3病毒感染 随着全球信息化时代的全而来临,不同系统之间的信息交流也日益频繁。这在为我们的生活带来便捷的同时也增加了计算机病毒交互感染的几率。从目前网络各项数据的使用情况上来看,病毒己经成为了网络数据安全威胁的头号敌人。由于病毒大多都是由编程人员手动植入,而且具有高度的传染性。它通常是利用系统之间信息交互的时候进行入侵。并且因为病毒的寄生性以及破坏性都是极强的,所以,要对系统进行定期的检查,做好对病毒的防范工作以及杀毒的工作。 2.4对账号权限设置的安全保护力度不够 在相对比较成熟安全的系统操作环境之下,使用网络数据库的人员通常会渐渐丧失应有的安全意识。比如说在进行账号以及密码的设置时,大多的用户都是仅仅将其选择禁用状态或者是修改的状态来进行简单的权限设置。在这样的权限设置下,用户的账号和密码实际上对很多用户都是公开的。而且对于账号密码的使用以及监控力度也没有按照数据字典的对应要求来执行。除此之外,与传统的数据库管理相比,网络数据库也缺少专门的安全监管人员(就是以现在的网络计算机网络数据
### 回答1: 题目描述: 本题要求你判断给定的一系列操作是否合法。每个操作将要么将给定的元素插入一个、要么将堆顶元素输出、要么输出堆元素个数。堆是一种经过排序的完全二叉树,堆顶元素是整棵树最小(或最大)的元素。 输入格式: 输入第一行给出一个不超过 1000 的正整数 N,表示操作。随后 N 行,每行按下列格式给出一个操作: I key -- 将 key 插入堆 E -- 取出堆顶元素 C -- 输出当前堆元素个数 输出格式: 对输入每个操作,按下列要求输出: 若该操作非法,则对应输出 Invalid 若该操作合法且堆未满,则无论该操作为何,都不用输出 若该操作合法且堆已满,则对应输出 Full 若该操作合法且堆为空,则对应输出 Empty 若该操作合法且堆非空,则对应输出堆顶元素的值或堆元素个数。 输入样例: 9 I 12 I 3 I 5 I 18 C E C E E 输出样例: 4 12 Invalid Empty 题目解析: 这道题需要实现一个堆,并进行相应的操作。由于堆的基本性质是要满足完全二叉树,所以我们可以采用数组来存储堆。具体来说,对于第 i 个节点,它的左儿子的下标是 2i,右儿子的下标是 2i+1,它的父节点的下标是 i/2。 在进行插入操作时,我们将元素插入到堆的最后一个位置,然后依次与其父节点比较,如果比父节点小(或大,根据具体要求而定),则交换它们的位置,直到找到合适的位置为止。 在进行输出堆顶元素操作时,我们需要将堆顶元素取出来,并将最后一个元素放到堆顶,然后再依次将它与它的儿子比较,如果比儿子大(或小,根据具体要求而定),则交换它们的位置,直到找到合适的位置为止。 在进行输出堆元素个数操作时,我们只需要输出堆的大小即可。 在实现堆的过程,我们需要注意堆的容量问题。当堆已满时,插入操作无效;当堆为空时,输出操作无效;当堆非空时,堆顶元素和输出堆元素个数操作是有效的。 参考代码:由于您没有给出具体的参考代码,我为您提供一个 Python 的参考代码: ```python MAXN = 1005 class MinHeap: def __init__(self, capacity): self.data = [0] * (capacity + 1) self.size = 0 self.capacity = capacity def is_full(self): return self.size == self.capacity def is_empty(self): return self.size == 0 def insert(self, x): if self.is_full(): print("Full") return self.size += 1 i = self.size while i > 1 and x < self.data[i // 2]: self.data[i] = self.data[i // 2] i //= 2 self.data[i] = x def delete_min(self): if self.is_empty(): print("Empty") return x = self.data[1] y = self.data[self.size] self.size -= 1 i = 1 while i * 2 <= self.size: j = i * 2 if j + 1 <= self.size and self.data[j + 1] < self.data[j]: j += 1 if y <= self.data[j]: break self.data[i] = self.data[j] i = j self.data[i] = y return x def get_size(self): return self.size n = int(input()) heap = MinHeap(MAXN) for i in range(n): op = input().split() if op[0] == "I": x = int(op[1]) heap.insert(x) elif op[0] == "E": x = heap.delete_min() if x is not None: print(x) elif op[0] == "C": print(heap.get_size()) else: print("Invalid") ``` 在这个参考代码,我们定义了一个 MinHeap 类来实现最小堆。在类的构造函,我们初始化了一个长度为 capacity+1 的数组来存储堆,并设置初始大小和容量为 0 和 capacity。 在类,我们还定义了 is_full 和 is_empty 方法来判断是否已满和是否为空。在 insert 方法,我们先判断是否已满,如果是,则输出 Full 并返回;否则,将元素插入到堆的最后一个位置,并将它与其父节点比较,直到找到合适的位置为止。 在 delete_min 方法,我们先判断是否为空,如果是,则输出 Empty 并返回;否则,将堆顶元素取出来,并将最后一个元素放到堆顶,然后再依次将它与它的儿子比较,如果比儿子大,则交换它们的位置,直到找到合适的位置为止。 在 get_size 方法,我们只需要返回堆的大小即可。 最后,在主函,我们首先读入操作 n,并定义一个容量为 MAXN 的最小堆 heap。接下来,我们按照题目要求进行操作,并输出相应的结果。如果操作不合法,则输出 Invalid。 这个参考代码的时间复 我们可以通过比较堆顶元素与其子节点的值来判断堆时候满足堆的性质。如果堆顶元素大于等于它的子节点,则堆满足最大堆性质;如果堆顶元素小于等于它的子节点,则堆满足最小堆性质。题目描述 一个堆是一棵完全二叉树,并且满足堆的性质:父节点的键值总是大于或等于(小于或等于)任何一个子节点的键值。 本题定义正难则反,即以最小堆为例。 输入格式: 输入第一行给出一个整数N(N<=1000),是输入的堆的个数。随后N行,每行对应一个堆,给出其先序遍历序列。这里默认所有字均为正整数字间以空格分隔。 输出格式: 对输入的每个堆,判断是否是最小堆。如果是,则输出“Yes”,否则输出“No”。 输入样例: 3 8 18 10 7 9 16 19 13 15 8 10 16 18 19 15 13 7 9 1 2 3 4 5 6 7 输出样例: Yes No Yes 解题思路 本题给出了堆的性质,父节点的键值总是大于或等于(小于或等于)任何一个子节点的键值,那么只需要对于每个堆判断是否满足这个性质即可。 首先将先序遍历序列转化为树的结构,然后对于每个父节点和其子节点进行比较,如果存在父节点比子节点的键值大的情况,则说明不满足最小堆的性质,输出 No,否则输出 Yes。 注意事项 1. 本题定义正难则反,即以最小堆为例。 2. 叶节点也被视为合法的堆。 3. 输入时字间以空格分隔,而不是换行。 参考代码题目描述 堆是一种经典的数据结构。堆的定义如下:给定一个序列 $K = \{ k_1,k_2,⋯,k_N\}$,$K$ 的元素在不改变它们的相对位置的情况下,可以看做是一棵完全二叉树的结点所对应的元素。堆可以分为大根堆和小根堆。大根堆的任意结点的值都不大于其父结点的值;小根堆的任意结点的值都不小于其父结点的值。本题需要判断给定的序列是否是堆。 输入格式 第一行包含两个整数 $M$ 和 $N$,分别表示序列元素的个数以及堆的个数。 第二行包含 $M$ 个整数,为给定的 $M$ 个元素 $(k_1,k_2,⋯,k_M)$。 接下来 $N$ 行,每行给出一个判断是否为堆的序列。每行第一个字 $K$ 为该序列元素的个数,随后 $K$ 个数字为该序列的元素 $(k_{a1},k_{a2},⋯,k_{aK})$。 输出格式 对于每个给定的序列,如果它是堆,则输出 Max Heap,如果是小根堆,则输出 Min Heap,否则输出 Not Heap。 注意,即使是大根堆,如果按照层序遍历得到的结点值序列不是递减的,则仍然被认为不是堆。 数据范围 $M≤1000$,$N≤20$,$K≤1000$,$k_i$ 取值为整数,均在 $[-10^5,10^5]$ 范围内。 输入样例1 5 3 98 72 86 60 65 5 86 60 98 72 65 4 98 72 65 86 7 99 72 90 61 65 61 58 输出样例1 Max Heap Not Heap Not Heap 输入样例2 5 3 2 3 1 5 4 5 3 2 5 4 1 5 3 1 2 4 5 5 4 3 2 1 5 输出样例2 Min Heap Not Heap Not Heap 题目分析 1. 判断是否为大根堆 2. 判断是否为小根堆 3. 判断是否为堆 a. 判断是大根堆还是小根堆 b. 判断是否为递减序列 对于判断是大根堆还是小根堆,可以直接判断一个元素和最后一个元素的大小关系。如果第一个元素大于最后一个元素,则该序列是大根堆;如果第题目描述: 给定一个序列,判断是否一个堆的先序遍历结果。 解题思路: 堆是一种特殊的树形结构,可以分为最大堆和最小堆两种。最大堆的任何一个非叶子节点的值都不小于其左右子节点的值,最小堆则相反。堆的先序遍历结果可以用来构建堆,具体做法是从第一个非叶子节点开始,依次对每个节点进行向下调整,直至整个序列满足堆的性质。 本题要求判断一个序列是否为堆的先序遍历结果。由于堆的性质可以通过向下调整来实现,因此可以依次对每个非叶子节点进行向下调整,最终判断整个序列是否满足堆的性质即可。具体步骤如下: 1. 找到最后一个非叶子节点,其下标为 n/2-1。 2. 从最后一个非叶子节点开始,依次对每个节点进行向下调整,直至整个序列满足堆的性质。 3. 在向下调整的过程,若发现某个节点不满足堆的性质,则该序列不是堆的先序遍历结果。 4. 若所有节点均满足堆的性质,则该序列是堆的先序遍历结果。 时间复杂度为 O(n),其 n 为序列长度。 参考代码:题目描述 堆是一种经典的数据结构,通常包括“插入元素”、“删除最小元素”、“建立堆”等基本操作。现请你判断给定的序列是否是某个序列的后序遍历结果。 输入格式: 输入第一行给出一个整数N(≤30)。随后一行给出长度为N的整数序列,字间以空格分隔。 输出格式: 如果输入序列是某个序列的后序遍历结果,则输出“Yes”,否则输出“No”。 输入样例1: 5 1 3 2 5 4 输出样例1: Yes 输入样例2: 7 2 9 5 16 17 15 19 输出样例2: No 解题思路 此题需要判断一个给定的序列是否一个堆的后序遍历结果。根据堆的性质,可以将堆分为最小堆和最大堆。最小堆的性质是:每个父节点都小于它的左右儿子节点;最大堆的性质是:每个父节点都大于它的左右儿子节点。 我们可以通过后序遍历的方式还原出原序列,然后判断是否符合堆的性质。对于最小堆,每次从序列取出最后一个元素作为根节点,然后将剩余元素分为左右两个子序列,分别递归地构建左子树和右子树。对于最大堆,每次从序列取出最后一个元素作为根节点,然后将剩余元素分为左右两个子序列,分别递归地构建左子树和右子树。在构建的过程,如果发现当前的节点值不符合堆的性质,则说明原序列不是一个堆的后序遍历结果。 代码演示题目描述: 给定一系列操作,包括“Push”、“Pop”、“Top”和“IsEmpty”(判断是否为空)。现在要对栈进行一系列操作,并请你在每次操作后输出栈的情况。 输入格式: 第一行包含一个整数N,表示操作。 接下来N行,每行包含一个操作命令,操作命令为“Push x”、“Pop”、“Top”或“IsEmpty”。 输出格式: 对于每个操作: 若该操作为“Push”,则输出“Push x”后,输出当前栈所有元素; 若该操作为“Pop”,则输出“Pop”后,输出当前栈所有元素(若当前栈无元素,则输出“Empty”); 若该操作为“Top”,则输出“Top”后,输出当前栈顶元素(若当前栈无元素,则输出“Empty”); 若该操作为“IsEmpty”,则输出“Empty”。 数据范围: 1≤N≤100,−10^5≤x≤10^5,保证在执行Pop、Top操作时栈不为空。 样例输入: 10 Push 1 Push 2 Top Pop Top Pop Pop IsEmpty Push 3 IsEmpty 样例输出: Push 1 1 Push 2 1 2 Top 2 Pop 1 Top 1 Pop Empty Pop Empty IsEmpty Empty Push 3 3 IsEmpty 答案:堆是一种特殊的树状结构,其每个节点的值都大于等于其孩子节点的值,或者反之,每个节点的值都小于等于其孩子节点的值。这种特殊的结构使堆具有很多有用的特性,例如可以用于实现优先级队列等。题目描述: 给定一系列操作,包括“Pop”、“Push”、“IsEmpty”。其“Pop”表示弹出堆顶元素,“Push”表示插入一个元素,“IsEmpty”表示判断当前堆是否为空。现在要求你对于给定的一系列操作,判断它们是否合法。若合法,输出“Yes”,否则输出“No”。 输入格式: 输入第一行给出正整数N(≤20),是操作的个数。接下来N行,每行有一个字符串S,表示操作。如果S为“Push”,则后面还有一个整数X表示要压入堆的字。如果S为“Pop”,则后面没有字。 输出格式: 对于每一组测试数据,请在一行输出“YES”或“NO”,以表示这组操作是否合法。 输入样例: 4 Push 5 Push 4 Pop Pop 输出样例: Yes 样例解释: 操作为:Push 5、Push 4、Pop、Pop。对于第1个操作,Push操作是合法的,将5压入堆;对于第2个操作,Push操作是合法的,将4压入堆;对于第3个操作,Pop操作是合法的,弹出堆顶元素4;对于第4个操作,Pop操作是合法的,弹出堆顶元素5。所有操作都是合法的,所以输出“Yes”。题目描述 本题要求你写一个堆的判断程序,判断给定的一组序列是否能构成堆。 输入格式: 输入第一行给出正整数N(1<=N<=1000),是输入序列的个数。随后一行给出N个正整数,其间以空格分隔。 输出格式: 如果输入的序列可以构成堆,输出“YES”,否则输出“NO”。 输入样例: 9 8 7 6 5 4 3 2 1 0 输出样例: NO 思路分析 判断堆的性质需要分为两个步骤,即判断是否为最大堆或最小堆,以及根据完全二叉树的定义判断是否符合堆的定义。 具体步骤如下: - 判断是否为最大堆或最小堆: - 最大堆:如果第 i 个结点的值比它的父结点的值要大,则不符合最大堆的性质; - 最小堆:如果第 i 个结点的值比它的父结点的值要小,则不符合最小堆的性质。 - 判断是否符合堆的定义: - 堆定义:完全二叉树,如果每个结点都不大于(或不小于)它的父结点,则该树被称为堆。 由于本题给出的是序列而不是完全二叉树,需要根据完全二叉树的定义,将序列转换成完全二叉树,然后进行堆的判断。 完全二叉树的定义: - 如果一个二叉树,除了最后一层外,其余各层的结点都达到了最大值,最后一层可以不是满的,但结点都集在左边。 将序列转换为完全二叉树: - 如果将元素从序列的左侧开始,以层序遍历的方式插入到完全二叉树,则可以通过下标计算父子关系。 - 第 i 个结点的左儿子为2i,右儿子为2i+1,父结点为i/2。 根据以上思路,可以进行代码实现。 参考代码题目描述: 给定一个序列,判断是否合法的堆(即满足堆的性质且为完全二叉树)。如果是合法的堆,输出它的类型(最大堆还是最小堆),否则输出它的排序后的结果。 解题思路: 题目要求判断给定序列是否为合法的堆,因此需要先了解堆的性质。堆是一种特殊的树形数据结构,它满足如下性质: 1. 堆是一棵完全二叉树。 2. 最大堆:任意一个非叶子节点的值都不大于它的左右子节点的值。 最小堆:任意一个非叶子节点的值都不小于它的左右子节点的值。 因此,我们可以先判断给定序列是否为完全二叉树,如果不是则输出排序后的结果,如果是则需要再判断它是最大堆还是最小堆。 判断是否为完全二叉树可以使用队列来实现。具体来说,我们将根节点入队,然后对于每个节点,如果它有左子节点或右子节点,就将它们依次入队,直到队列为空。如果在这个过程出现某个节点没有左子节点或右子节点,但后面还有节点,那么说明这个序列不是完全二叉树,可以直接输出排序后的结果。 如果判断为完全二叉树,那么我们需要判断它是最大堆还是最小堆。最大堆和最小堆的区别在于节点的大小关系,因此可以根据根节点和左右子节点的大小关系来判断。具体来说,如果根节点的值小于左右子节点的值,则为最小堆;如果根节点的值大于左右子节点的值,则为最大堆。如果不满足这两个条件,则输出排序后的结果。 参考代码: l2-012 题目要求判断一个序列是否能够通过堆的方式进行排序。堆排序是一种基于堆的排序算法,具体实现过程可以参考相关资料。 判断一个序列是否可以通过堆排序进行排序,需要满足以下两个条件: 1. 该序列可以构成一个完全二叉树,即除了最后一层节点可能不满外,其他层节点都是满的,最后一层的节点都集在左侧。 2. 对于任意一个非叶子节点i,满足i节点的值大于等于其左右孩子节点的值。 如果序列满足以上两个条件,则可以通过堆排序进行排序。否则,不能通过堆排序进行排序。 L2-012 题目要求对于给定的序列,判断是否一个合法的堆。在判断过程需要使用到两个性质: 1. 对于任意一个结点,它的父结点的权值一定大于等于它的权值。 2. 对于任意一个非叶子结点,它的左右儿子结点的权值一定小于等于它的权值。 我们可以用数组来表示堆,然后分别检查上述两个性质是否满足。 具体做法是,先判断一个性质,即对于任意一个结点,它的父结点的权值一定大于等于它的权值。我们可以从第二个结点开始,一直遍历到最后一个结点,对于每个结点,检查它的父结点是否大于等于它的权值即可。 接下来是判断第二个性质,即对于任意一个非叶子结点,它的左右儿子结点的权值一定小于等于它的权值。我们可以从第一个非叶子结点开始,一直遍历到根节点,对于每个非叶子结点,检查它的左右儿子结点是否小于等于它的权值即可。 如果两个性质都满足,则序列是一个合法的堆,否则不是。 ### 回答2: 题目描述 给定一个整数序列,你需要判断是否一个堆。若是堆,则输出大写字母 P;否则输出大写字母 N 。 输入格式 共一行,为一个整数序列,数据保证每个位置上的都是不超过 109 的非负整数。 输出格式 共一行,为 P 或 N 。 题目分析 堆分为大根堆和小根堆。大根堆要求父节点的值大于等于子节点的值,小根堆要求父节点的值小于等于子节点的值。对于此题整数序列,若是大根堆,则对于任意的 i,满足 a[parent(i)] ≥ a[i];小根堆则满足 a[parent(i)] ≤ a[i]。 思路 首先,读入整数序列。判断为大根堆还是小根堆。再通过依次比较子节点和父节点的大小来判断是否为堆。 代码实现 (详细代码请参考京东零售笔试真题) 时间复杂度 时间复杂度为 O(n),可以通过此题。 总结 本题主要考察堆的知识点和与之相关的一些概念。了解了堆的定义与性质之后,结合题目特点,便可判断整数序列是否为堆。 参考资料 堆。https://www.cnblogs.com/xiaoyunfeifei/p/5735807.html ### 回答3: 本题要求我们判断一个序列是否一个合法的堆。首先我们需要了解什么是堆。 堆是一种特殊的树形数据结构,它满足下列性质: 1、堆是一个完全二叉树; 2、堆的每个节点都满足其父节点的值大于等于(大根堆)或小于等于(小根堆)其子节点的值。 已知一个长度为n的序列,要判断是否为堆,我们可以从序列第二个数开始,依次与其父节点比较,若当前比父节点大(大根堆)或小(小根堆),则进行一次交换操作,继续向上比较,直到根节点位置或满足了性质2为止。如果序列的所有节点都满足堆的性质,则判断为合法的堆。 具体的实现可以采用二叉树的形式,即将序列的元素逐个插入到一棵空二叉树,每次插入后进行一次向上的比较和交换操作。如果全部插入完成后,二叉树满足堆的性质,则判断为合法的堆。 另外还需要注意一个问题,就是对于堆下标从1开始计还是从0开始计的问题。需要根据实际题目给出的情况进行判断,以避免出现下标错位的问题。 总的来说,判断一个序列是否为堆的最关键的是要理解堆的性质,并熟练掌握堆的插入和调整操作。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值