javascript数据结构系列(五)-串(2)

前言

昨天写了简单的块存储结构,很多方法没有实现,今天补上。

串的块存储结构

相比较余线性表、栈等数据结构,串的块存储结构比较复杂。今天实现的方法有substring(),toString()等,操作比较复杂有点不易理解。
//串的块存储
function Chunk(chunkSize){
    this.chunkSize = chunkSize || 4;
    this.chunk = [];
    for(var i = 0; i<this.chunkSize;i++){
        this.chunk[i] = '#'
    }
    //type:chunk
    this.next = null;
};
exports.LString = LString;
function LString(chunkSize){
    this.head = null;
    this.tail = null;
    this.length = 0;
    this.chunkSize = chunkSize || 4;
};
LString.prototype = {
    //生成一个串
    strAssign:function(chars){
        //建立区块
        this.head = this.tail = new Chunk(this.chunkSize);
        this.length = chars.length;
        var current = this.head;
        //在i<chars.length之前,不断地用chars的数据元素来替换'#',每当填充完4个空间之后,进入if(进入if的条件中(i+1) % 4 === 0可以判断),让next指针指向下一个存储区块
        for(var i = 0,len = chars.length;i<len;i++){
            current.chunk[i % this.chunkSize] = chars[i];
            if((i+1 < len) && ((i+1) % this.chunkSize) === 0){
                current.next = new Chunk();
                current = current.next;
            }
        }
        //循环完成之后,让尾指针指向最后的一个区块
        this.tail = current;
    },
    //复制一个串

    //判断是否为空
    strEmpty:function(){
        if(this.length === 0){
            if(this.head === this.tail){
                if(this.head === null){
                    return true;
                }
            }
        }
        return false;
    },
    //若S>T则返回值大于0
    strCompare:function(){
        var current = this.head;
        var curT = tLString.head;
        if(this.lenth !== tLString.length){
            return false;
        }
        while(current){
            for(var i = 0;i < this.chunkSize;i++){
                if(current.chunk[i] !== curT.chunk[i]){
                    return false;
                }
            }
            current = current.next ;
            curT = curT.next;
        }
        return true;
    },
    //求串的长度
    totring:function(){
        var current = this.head;
        if(current === null){
            return '';
        };
        var str = '';
        while(current){
            for(var i = 0;i<this.chunkSize;i++){  
                var ch = current.chunk[i];
                if(ch === "#"){
                    console.log(str);
                    return str;
                }else{
                    str = str + current.chunk[i];
                }
            }
            current = current.next;
        }
        console.log(str);
        return str;
    },
    //返回pos开始长度为len的子串
    subString:function(pos,len){
        //~~按位取反再取反......
        pos = ~~pos || 0;
        len = ~~len || this.length;
        if (pos < 0 || pos > this.length - 1 || len < 0 || len > this.length - pos)
            throw new Error('unexpected parameter');
        var sub = new LString(this.chunkSize);
        var current = findPosChunk(this,pos);
        var cur = sub.head = new Chunk(this.chunkSize);
        var i = 0;
        sub.length = len;
        outerloop:while(current){
            for(var j = 0,size = this.chunkSize;j<size;j++){
                if(i === len){
                    break outerloop;
                }else{
                    cur.chunk[j] = current.chunk[(i + pos) % this.chunkSize];
                    i++;
                    if((i + pos) % this.chunkSize === 0){
                        current = current.next;
                    }
                    if( i % this.chunkSize === 0 && (current.chunk[i] || current.next)){
                        cur.next = new Chunk(this.chunkSize);
                        cur = cur.next;
                    }
                }
            }
        }
        console.log(sub);
        return sub;
    },
    //链接两个字符串
    contact:function(tLString){
        if(!tLString.length){
            return ;
        }
        var ret = new LString(this.chunkSize);
        if(this.head === null){
            strCopy(ret,tLString);
        }else{
            ret.head = ret.tail = new Chunk(this.chunkSize);
            strCopy(ret,this);
            var index = ret.tail.chunk.indexOf("#");
            if(index === -1){
                strCopy(ret,tLString);
            }else{
                strCopy(ret,tLString,ret.tail, tLSting.head, index);
            }
        }
    },
};
//查找低pos个元素所在的区块
function findPosChunk(LS,pos){
    var current = LS.head;
    while(current){
        for(var i = 0,len = LS.chunkSize;i<len;i++){
            if(pos-- === 0){
                console.log(current);
                return current;
            }
        }
        current = current.next;
    }
};
function strCopy(destination,target,curD,currT,offset){   
    offset = offset || 0;
    //定义currT是被复制的串的头指针所指向的区块
    currT = currT || target.head;
    //定义curD是新(空串)的串的头指针所指向的区块
    curD = curD || destination.head;
    var k = 0;
    //当currT为真,表明taget串的字符还没有复制完成
    while (currT){
        for (var i = 0, len = target.chunkSize; i < len; i++, k++) {
            //j的计数是curD的区块的计数
            var j = k % curD.chunkSize + offset ;
            //同Assign方法一样,j % chunksize 的意思是对chunksize取余,这样的话可以保证按照chunksize的大小划分区块
            curD.chunk[j % curD.chunkSize] = currT.chunk[i]; 
            if ((j + 1) % curD.chunkSize === 0 && (currT.chunk[i + 1] || currT.next)) {
                //当curD成功复制一次chunk之后且currT不为空,那么对destination串进行新建区块操作,用来存放下一轮复制
                curD.next = new Chunk(destination.chunkSize);
                //新建之后要把指针向后移动一位
                curD = curD.next;
            }
        }
        currT = currT.next;
    }
    //设立新串的尾指针
    destination.tail = curD;
    //设立新串的长度
    destination.length += target.length;
};

后记

以上。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值