js版本单词查找树2.0_undefined

//字母表结构和代码大量耦合,不考虑解耦了。
//用undefined替换null,对象结构精简很多,getMap不再需要;还有很多代码可以简化,为了与1.0——null进行对照就不改了


//在node下获取key对应的val,d是即将比较的字符串的长度,如d=2表示即将用key的第2个字符与树对应的节点进行比较
function get(node,key,d=0){
    if(node==undefined)return undefined
    if(d==key.length)return node
    return get(node.next[key[d]],key,d+1)
}

//在node下设置key对应的值是val,没有创建有就覆盖,d是即将比较的字符串的长度
//JSON.parse(JSON.stringify(getMap()))实现深复制的效果,避免地址引用
function put(node,key,val,d=0){
    if(node==undefined){
        var node={next:{}}
    }
    if(d==key.length){
        node.val=val
    }else{
        let k=key[d]
        node.next[k]=put(node.next[k],key,val,d+1)
    }
    return node
}
//keysWithPrefix:返回node节点下以pre开头的所有key,设置默认值的参数必须放最后,否则报错,d是即将比较的字符串的长度
function keysWithPrefix(node,pre,list=[],d=0){
    if(node==undefined){return list}
    if(node.val!=undefined&&d>=pre.length){list.push(pre)}
    if(d>=pre.length){
        for(let i=0;i<26;i++){                    //代替下面注释的代码,原因是下面的代码遍历顺序随机
            let x=String.fromCharCode(97+i)
            let y=node.next[x]
            if(y!=undefined){
                list=keysWithPrefix(y,pre+x,list,d+1)
            }
        }
       /* for(let x in node.next){
            let y=node.next[x]
            if(y!=undefined){
                list=keysWithPrefix(y,pre+x,list,d+1)
            }
        }*/
    }else{
        list=keysWithPrefix(node.next[pre[d]],pre,list,d+1)
    }
    return list
}
//keysThatMatch:返回匹配的字符串,如果a.b对应a[a-z]b
function keysThatMatch(node,match,list=[],pre=""){
    if(node==undefined||pre.length>match.length){return list}
    if(node.val!=undefined&&pre.length==match.length){list.push(pre)}
    for(let i=0;i<26;i++){                        //代替下面注释的代码,原因是下面的代码遍历顺序随机
        let d=pre.length
        let x=String.fromCharCode(97+i)
        if(match[d]=='.'||match[d]==x){
            let y=node.next[x]
            if(y!=undefined){
                list=keysThatMatch(y,match,list,pre+x)
            }
        }
    }
    /* for(let x in node.next){
        let d=pre.length
        if(match[d]=='.'||match[d]==x){
            let y=node.next[x]
            if(y!=undefined){
                list=keysThatMatch(y,match,list,pre+x)
            }
        }
    }*/
    return list
}

//longestPrefixOf:返回给定字符串最长公共前缀的key,d1是目前此key的长度,d2是即将比较的字符串的长度
//第一次执行时,d2=0表示即将比较根节点和match
function longestPrefixOf(node,match,d1=0,d2=0){
    //console.log(d1,d2)
    if(node==undefined||d2>match.length){return match.substr(0,d1)}
    if(node.val!=undefined){d1=d2}
    return longestPrefixOf(node.next[match[d2]],match,d1,d2+1)
}

//delete:d是即将比较的字符串的长度,删除key对应节点后,需要把无子节点且没有val的节点也删除
function delete_(node,key,d=0){
    if(node==undefined){
        return undefined
    }
    if(d==key.length){
        node.val=undefined
    }else{
        let k=key[d]
        node.next[k]=delete_(node.next[k],key,d+1)
    }
    for(let i in node.next){        //node.val!=undefined的判断最好放循环外面,放里面影响不大
        if(node.val!=undefined||node.next[i]!=undefined){return node}
    }
    //return undefined
}


var root=undefined
let j1=require('./1')
let mylength=10000
randomWords=j1.getWords(mylength,1,11)
randomWords.forEach((x)=>{root=put(root,x,x+'Val')})    //put随机字符串到以root为根节点的树
console.log("\n\n\n\n\nrandomWords=\n",randomWords)
randomWords.forEach((x)=>{                              //测试put是否生效
    if(get(root,x).val!=x+'Val'){
        console.log(x+'---->'+get(root,x).value)
    }
})



console.log('\n\n\n-->test keysWithPrefix')
console.log(keysWithPrefix(root,"a"))          //打印以'a'开头的字符串
console.log(lst=keysWithPrefix(root,""))       //打印以所有字符串,这里lst是全局变量(在function里声明测试过)
console.log(lst.length)                        //长度可能不到mylength,因为有重复的可以key:val

let matchstr="..."
console.log('\n\n\n-->test keysThatMatch '+matchstr)
console.log(keysThatMatch(root,matchstr))


let prefixstr="abcd"
console.log('\n\n\n-->test longestPrefixOf '+prefixstr)
console.log(longestPrefixOf(root,prefixstr))

console.log('\n\n\n-->test delete')
root=put(root,'aaaaaa','a6val')
root=put(root,'aaaaaaaa','a8val')
console.log(keysWithPrefix(root,""))
console.log(get(root,"aaaaaaaa"))
console.log(get(root,"aaaaaaa"))
console.log(get(root,"aaaaaa"))
console.log(get(root,"aaaaa"))
root=delete_(root,'aaaaaaaa')
root=delete_(root,'a')
console.log(keysWithPrefix(root,""))
console.log(get(root,"aaaaaaaa"))
console.log(get(root,"aaaaaaa"))
console.log(get(root,"aaaaaa"))
console.log(get(root,"aaaaa"))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值