diff options
| author | Jérémy Zurcher <jeremy@asynk.ch> | 2016-11-13 22:29:59 +0100 | 
|---|---|---|
| committer | Jérémy Zurcher <jeremy@asynk.ch> | 2016-11-13 22:29:59 +0100 | 
| commit | c64d8fdb9016263b82207d265def04589fb6f22b (patch) | |
| tree | 41dcd3449cd574637d527aedd04b975dc406bc6c /02-data_structures/04-binary_search_trees/03-rope | |
| parent | f14c9988786b578c115ba1f8a93d61f51d013e2f (diff) | |
| download | coursera-c64d8fdb9016263b82207d265def04589fb6f22b.zip coursera-c64d8fdb9016263b82207d265def04589fb6f22b.tar.gz  | |
Algorithms : complete 02-data_structures 04-binary_search_trees
Diffstat (limited to '02-data_structures/04-binary_search_trees/03-rope')
| -rw-r--r-- | 02-data_structures/04-binary_search_trees/03-rope/rope.cpp | 168 | 
1 files changed, 159 insertions, 9 deletions
diff --git a/02-data_structures/04-binary_search_trees/03-rope/rope.cpp b/02-data_structures/04-binary_search_trees/03-rope/rope.cpp index d5f5f35..2f2bb75 100644 --- a/02-data_structures/04-binary_search_trees/03-rope/rope.cpp +++ b/02-data_structures/04-binary_search_trees/03-rope/rope.cpp @@ -2,22 +2,170 @@  #include <string>  #include <iostream> +/* static bool debug = false; */ + +struct Vertex { +  const char *s; +  size_t weight; +  Vertex* left; +  Vertex* right; + +  Vertex(const char *s, size_t weight) +  : s(s), weight(weight), left(NULL), right(NULL) {} + +  Vertex(Vertex* left, Vertex* right, size_t weight) +  : s(NULL), weight(weight), left(left), right(right) {} +};  class Rope {  	std::string s; +    Vertex *root;  public: -	Rope(const std::string &s) : s(s) {  +	Rope(const std::string &s) : s(s) { +        root = new Vertex(&s[0], s.size());  	} -	void process( int i, int j, int k ) { -                // Replace this code with a faster implementation -                std::string t = s.substr(0, i) + s.substr(j + 1); -                s = t.substr(0, k) + s.substr(i, j - i + 1) + t.substr(k); +	void process( int i, int j, int k ) +    { +        Vertex* left = NULL; +        Vertex* right = NULL; +        Vertex* out = NULL; +        int len = weight(root); + +        /* if (debug) std::cout << std::endl << "PROCESS : " << i << " " << j << " " << k << std::endl; */ + +        if (i > 0) { +            split(root, i, out); +            left = root; +            /* if (debug) { */ +            /*     std::cout << "   left : " << print(left) << std::endl; */ +            /*     std::cout << "    out : " << print(out) << std::endl; */ +            /* } */ +        } else { +            left = NULL; +            out = root; +        } + +        if (len > (j + 1)) { +            split(out, (j - i + 1), right); +            /* if (debug) { */ +            /*     std::cout << "   out  : " << print(out) << std::endl; */ +            /*     std::cout << "  right : " << print(right) << std::endl; */ +            /* } */ +        } else { +            right = NULL; +        } + +        /* if (debug) std::cout << "  concat left || right : "; */ +        root = concat(left, right); +        /* if (debug) std::cout << print(root) << std::endl; */ + +        left = NULL; +        right = NULL; +        if (k > 0) { +            split(root, k, right); +            left = root; +            /* if (debug) { */ +            /*     std::cout << "   left : " << print(left) << std::endl; */ +            /*     std::cout << "  right : " << print(right) << std::endl; */ +            /* } */ +            root = concat(left, concat(out, right)); +            /* if (debug) std::cout << "   root : " << print(root) << std::endl; */ +        } else { +            root = concat(out, root); +            /* if (debug) std::cout << "   root : " << print(root) << std::endl; */ +        }  	}  	std::string result() { -		return s; +        return print(root);  	} + +private: +    std::string print(Vertex *v) +    { +        /* std::cout << weight(v) << std::endl; */ +        if (v == NULL) return "NULL"; +        std::string res; +        in_order(v, res); +		return res; +    } + +    void in_order(Vertex *v, std::string &r) { +        if (v == NULL) return; +        /* if (debug) { */ +        /*     std::cout << v << "  " << v->weight << " "; */ +        /*     if (v->s != NULL) { */ +        /*         for (int i = 0; i < v->weight; i++) */ +        /*             std::cout << v->s[i]; */ +        /*     } */ +        /*     std::cout << std::endl << "   " << v->left<< std::endl; */ +        /*     std::cout << "   " << v->right << std::endl; */ +        /* } */ + +        in_order(v->left, r); +        if (v->s != NULL) { +            for (int i = 0; i < v->weight; i++) +                r.push_back(v->s[i]); +        } +        in_order(v->right, r); +    } + +    size_t weight(Vertex *v) { +        size_t w = 0; +        while (v != NULL) { +            w += v->weight; +            v = v->right; +        } +        return w; +    } + +    Vertex* concat(Vertex *left, Vertex *right) { +        if (right == NULL) +            return left; +        if (left == NULL) +            return right; +        return new Vertex(left, right, weight(left)); +    } + +    // split into : [0 ; (key-1)] [key; ...] +    void split(Vertex* v, int key, Vertex*& outer) { +        /* if (debug) std::cout << " split  " << key  << " " << print(v) << std::endl; */ +        _split(v, key, outer); +    } + +    int _split(Vertex* v, int key, Vertex*& outer) { +        if (v == NULL) return 0; +        if (key < v->weight) { +            if (v->left == NULL) { +                /* if (debug) std::cout << "      found : " << v->s[key] << std::endl; */ +                Vertex *tmp = new Vertex(&v->s[key], v->weight - key); +                v->weight = key; +                outer = concat(tmp, outer); +                return v->weight; +            } else { +                outer = concat(v->right, outer); +                v->right = NULL; +                v->weight = _split(v->left, key, outer); +                // compress +                if (v->left != NULL && v->left->left != NULL && v->left->right == NULL) { +                    Vertex *tmp = v->left; +                    v->left = v->left->left; +                    delete(tmp); +                } +                return v->weight; +            } +        } else { +            key -= v->weight; +            if (key == 0) { +                outer = concat(v->right, outer); +                v->right = NULL; +                return v->weight; +            } else { +                return v->weight + _split(v->right, key, outer); +            } +        } +    }  };  int main() { @@ -26,11 +174,13 @@ int main() {  	std::cin >> s;  	Rope rope(s);  	int actions; +    /* if (debug) std::cout << rope.result() << std::endl; */  	std::cin >> actions; -        for (int action_index = 0; action_index < actions; ++action_index) { -                int i, j, k; +    for (int action_index = 0; action_index < actions; ++action_index) { +        int i, j, k;  		std::cin >> i >> j >> k;  		rope.process(i, j, k); +        /* if (debug) std::cout << rope.result() << std::endl; */  	} -	std::cout << rope.result() << std::endl; +    std::cout << rope.result() << std::endl;  }  | 
