数据检索二分查找法

硬盘快速搜索第一步文件排序

硬盘文件的排序先用readline(),然后利用sort在使用lambda对getuser进行排序,然后挨个写入

import time

def getuser(line): #二进制行,取出user
    line=line.decode("gbk",errors="ignore")
    linelist=line.split(" # ")
    return linelist[0] 

csdnfile=open(r"C:\Users\Tsinghua-yincheng\Desktop\data索引\csdn.txt","rb")
csdnlist=csdnfile.readlines() #抓取全部
csdnfile.close()
print("read over")
csdnlist.sort(key =lambda x:getuser(x)) #根据user排序
print("sort over")
savefile=open(r"C:\Users\Tsinghua-yincheng\Desktop\data索引\csdnsort.txt","wb")
for line in csdnlist:
    savefile.write(line)
savefile.close()

生成索引

文件有自己的长度,比如第一个长度10(位置9)那么下一个长度的位置就是10。然后每个文件指针就能指向一个文件的开头

csdnsortfile=open(r"C:\Users\Tsinghua-yincheng\Desktop\data索引\csdnsort.txt","rb")
csdnlist=csdnsortfile.readlines()#读取全部

print("读取完成")
lengthlist=[0]
for line in csdnlist:
    lengthlist.append(len(line))#加入每一行的长度

del csdnlist  #删除,节约内存
print("抓取长度完成")
i=0
length=len(lengthlist)#列表长度
while i<length -1:#跳过最后一个
    lengthlist[i+1]+=lengthlist[i] #叠加长度算出某一行的位置
    i+=1  #生成索引
print("索引列表完成")
while True:
    linenum=eval(input("输入要查看哪一行"))#eval() 函数用来执行一个字符串表达式,并返回表达式的值。
    csdnsortfile.seek(lengthlist[linenum-1],0)#跳到指定位置
    line=csdnsortfile.readline()
    print(line)

csdnsortfile.close()

根据内存索引二分查找文件

有了索引后就相当于有了low与high的位置,二分查找法就能调用了

csdnsortfile=open(r"C:\Users\Tsinghua-yincheng\Desktop\data索引\csdnsort.txt","rb")
csdnlist=csdnsortfile.readlines()#读取全部

print("读取完成")
lengthlist=[0]
for line in csdnlist:
    lengthlist.append(len(line))#加入每一行的长度

del csdnlist  #删除,节约内存
print("抓取长度完成")
i=0
length=len(lengthlist)#列表长度
while i<length -1:#跳过最后一个
    lengthlist[i+1]+=lengthlist[i] #叠加长度算出某一行的位置
    i+=1  #生成索引
print("索引列表完成")


def memfind2(lengthlist,findstr):
          low=0   #第一个
          high=len(lengthlist)-1  #最后一个
          
          while  low<=high : #没有重合的情况继续
                mid=(low+high)//2  #整除

                midindex=lengthlist[mid]#取出中间的索引
                csdnsortfile.seek(midindex,0)#跳到文件的位置
                line=csdnsortfile.readline()#读取一行

                line=line.decode("gbk",errors="ignore")
                linelist=line.split(" # ")
                middata=linelist[0]#取出中间数据




                if  findstr<middata:
                    high=mid-1  #重复过程
                elif findstr >middata:
                    low=mid+1
                else:
                    print("找到",mid,middata,line)
                    return 


while True:
     inputstr=input("输入要查找的数据")
     memfind2(lengthlist,inputstr)

csdnsortfile.close()

索引到硬盘

最后写入的时候,利用索引写入

csdnsortfile=open(r"C:\Users\Tsinghua-yincheng\Desktop\data索引\csdnsort.txt","rb")
csdnlist=csdnsortfile.readlines()#读取全部

print("读取完成")
lengthlist=[0]
for line in csdnlist:
    lengthlist.append(len(line))#加入每一行的长度

del csdnlist  #删除,节约内存
print("抓取长度完成")
i=0
length=len(lengthlist)#列表长度
while i<length -1:#跳过最后一个
    lengthlist[i+1]+=lengthlist[i] #叠加长度算出某一行的位置
    i+=1  #生成索引
print("索引列表完成")

savefile=open(r"C:\Users\Tsinghua-yincheng\Desktop\data索引\csdnsortindex.txt","wb")
for i in range(len(lengthlist)-1):
    savefile.write(format(lengthlist[i],"10d").encode("utf-8")) #索引保存到硬盘
savefile.close()

随机访问

随机访问的利用seek这个文件指针加上需要输入的行数减一实现。

csdnfile=open(r"C:\Users\Tsinghua-yincheng\Desktop\data索引\csdnsort.txt","rb")
indexfile=open(r"C:\Users\Tsinghua-yincheng\Desktop\data索引\csdnsortindex.txt","rb")

while True:
      linenum=eval(input("输入要查看哪一行"))
      indexfile.seek(10*(linenum-1),0)#调到索引文件读取索引
      midval=indexfile.read(10) #读取10个字节,
      midval=eval(midval)#抓取索引,变成数据

      csdnfile.seek(midval,0)#调到CSDN文件的索引
      line=csdnfile.readline()#读取一行
      line=line.decode("gbk",errors="ignore")
      print(line)




csdnfile.close()
indexfile.close()

文件二分查找

其实跟之前一样,不过是要先找到文件的最后一个位置,此处是6428632,那么最有一个位置就是减少1,再调用二分查找的算法。




csdnfile=open(r"C:\Users\Tsinghua-yincheng\Desktop\data索引\csdnsort.txt","rb")
indexfile=open(r"C:\Users\Tsinghua-yincheng\Desktop\data索引\csdnsortindex.txt","rb")
#6428632


def find2(findstr):
    low=0#开始
    high=6428632-1 #结束=

    while low <=high:
        mid=(low+high)//2

        indexfile.seek(10*mid,0)#调到索引文件读取索引
        midval=indexfile.read(10) #读取10个字节,
        midval=eval(midval)#抓取索引,变成数据

        csdnfile.seek(midval,0)#调到CSDN文件的索引
        line=csdnfile.readline()#读取一行
        line=line.decode("gbk",errors="ignore")
        linelist=line.split(" # ")

        midstr=linelist[0]
        if  findstr >midstr:
            low=mid+1
        elif findstr<midstr:
            high=mid-1
        else:
            print("找到",midstr,line)
            return 




while True:
      findstr=input("要查找的name")
      find2(findstr)#查找





csdnfile.close()
indexfile.close()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

青灯有味是儿时

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

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

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

打赏作者

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

抵扣说明:

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

余额充值