内容简介:用递归的方式实现了一颗树状的结构,该模型可以处理上亿qq数据。内存中查询10次既可以找到结果,速度非常快。虽然将数据全部放置在了内存中,但是内存的消耗应该是降低到了最低的。相较于C语言,这段代码明显就要难看了很多。因为Go语言是类型安全的语言,安全的的背后就是效率的损失。
递归树
用递归的方式实现了一颗树状的结构,该模型可以处理上亿qq数据。
内存中查询10次既可以找到结果,速度非常快。虽然将数据全部放置在了内存中,但是内存的消耗应该是降低到了最低的。
相较于C语言,这段代码明显就要难看了很多。因为 Go 语言是类型安全的语言,安全的的背后就是效率的损失。
/*
Copyright © 2018 jonson
功能:在上亿乱序的qq账号密码数据文件中构建递归树,能够在不到1秒的时间内查询出指定账号的密码。
代码基于泄漏的qq老密,加群获取文件
*/
package main
import (
"bufio"
"fmt"
"log"
"os"
"strings"
"unsafe"
)
var g_pp = make([]*[]*byte,10)
func main() {
search()
}
//初始化构建内存模型
func init(){
fmt.Println("初始化开始")
file, err := os.Open("1E~001.txt")
if err != nil {
log.Fatal(err)
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
str:= scanner.Text()
if len(str) <50{//数据已经整理过,最多50位。
qq:= getQQ(str)
//fmt.Println(qq)
if len(qq)==10 && isAllNum(qq){
//递归树,将模型构建完毕。
assign(&g_pp,11,qq,str)
}
}
}
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
fmt.Println("初始化结束")
}
/*
最重要的递归函数,pp指针。deep为深度,str为字符串,password为密码
*/
func assign(pp *[]*[]*byte, deep int, str string,password string) {
//最后一级指针时,开辟内存,存储密码。
if deep == 1 {
buf:= make([]*byte,10)
(*pp)[getnum(str[10-deep])] = &buf
p:= (*string)(unsafe.Pointer((*pp)[getnum(str[10-deep])]))
*p = password
return
}
//刚开始传递11级指针的地址,deep=11递归下去,可以省略,改为传递11级指针,deep=10。
if deep == 11 {
assign((*[]*[]*byte)(unsafe.Pointer(pp)), deep - 1, str,password);
return
}
//判断该指针是否为空。如1131052403,当deep=10时,取出第一个数字1.判断pp[1]是否为Nil,为Nil就说明从来没有出现过第10位为1的qq号。
//这时就会为pp[1]开辟10个指针大小的内存,初始化为空。
//如果已经存在就继续递归。
if (*pp)[getnum(str[10-deep])]!=nil{
assign((*[]*[]*byte)(unsafe.Pointer((*pp)[getnum(str[10-deep])])), deep - 1, str,password);
}else {
buf:= make([]*byte,10)
(*pp)[getnum(str[10-deep])] = &buf
assign((*[]*[]*byte)(unsafe.Pointer((*pp)[getnum(str[10-deep])])), deep - 1, str,password);
}
}
//字符转换为数字
func getnum(u uint8) uint8{
return u - '0'
}
//qq补齐位数,判断是否为数字,字符转换为数字,数字不足补充0的算法
//获取QQ号 1131052403----qwerty
//截取数字10位,不足的补0,
//对于这个函数的改进,让我可以在查找qq函数时也可以用
func getQQ(s string) string{
raw:= strings.Split(s,"----")[0]
length := len(raw)
if length < 10 {
raw = strings.Repeat("0",10-length) + raw
}
return raw
}
//判断qq全部为数字
func isAllNum(qq string ) bool{
for _,ch := range qq{
if ch < '0' || ch > '9'{
return false
}
}
return true
}
/*
根据初始化递归树的原理,我们可以明白判断是否存在的意义。
如果在某一位出现了一个数字,其所在的指针为NULL,就说明在该位从来没有出现过这个数字。
相反,如果存在该数字,就首先说明其每一位的指针都不为空。
*/
var flag = true
var findresult string = ""
func isExit(pp *[]*[]*byte, deep int, str string) {
if deep == 1 {
if (*pp)[getnum(str[10-deep])]!=nil{
findresult = *(*string)(unsafe.Pointer((*pp)[getnum(str[10-deep])]))
}
return
}
if deep == 11 {
isExit((*[]*[]*byte)(unsafe.Pointer(pp)), deep - 1, str);
return
}
if flag && (*pp)[getnum(str[10-deep])]!=nil{
isExit((*[]*[]*byte)(unsafe.Pointer((*pp)[getnum(str[10-deep])])), deep - 1, str);
}else {
flag = false
return
}
}
//查找qq号
func search(){
input := bufio.NewScanner(os.Stdin)
for input.Scan(){
flag = true
findresult=""
qq:= input.Text()
qq= getQQ(qq)
fmt.Println("搜索qq号:",qq)
isExit(&g_pp,11,qq)
if isAllNum(qq) && findresult!=""{
fmt.Printf("结果为:%s\n",findresult)
}
}
}
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Learning Vue.js 2
Olga Filipova / Packt Publishing / 2017-1-5 / USD 41.99
About This Book Learn how to propagate DOM changes across the website without writing extensive jQuery callbacks code.Learn how to achieve reactivity and easily compose views with Vue.js and unders......一起来看看 《Learning Vue.js 2》 这本书的介绍吧!