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

来源:互联网 发布:剑三丐姐官方捏脸数据 编辑:程序博客网 时间:2024/05/16 12:06

前言

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

串的块存储结构

相比较余线性表、栈等数据结构,串的块存储结构比较复杂。今天实现的方法有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;};

后记

以上。

原创粉丝点击