Ropes are scalable string implementation. They are designed for efficient operation that involves the string as a whole. Operations such as assignment, concatenation, and sub-string take time that is nearly independent of the length of the string.
A rope is a binary tree where each leaf (end node) holds a string and a length (also known as a “weight”), and each node further up the tree holds the sum of the lengths of all the leaves in its left subtree. A node with two children thus divides the whole string into two parts: the left sub-tree stores the first part of the string, the right subtree stores the second part of the string, and a node’s weight is the length of the first part.
For rope operations, the strings stored in nodes are assumed to be constant immutable objects in the typical non-destructive case, allowing for some copy-on-write behavior. Leaf nodes are usually implemented as basic fixed-length strings with a reference count attached for deallocation when no longer needed, although other garbage collection methods can be used as well.
Note: The rope class and rope header are SGI extensions; they are not part of the C++ standard library.
Declaration:
Ropes are defined in the same way as vectors as “vector<int>”. But for character ropes, we can use crope as “rope<char>”.
Below is the program for the same:
Program 1:
// C++ program to illustrate the use // of ropes using Rope header file #include <ext/rope> #include <iostream> // SGI extension using namespace __gnu_cxx;
using namespace std;
// Driver Code int main()
{ // rope<char> r = "abcdef"
crope r = "abcdef" ;
cout << r << "\n" ;
return 0;
} |
abcdef
Operations allowed on Rope:
- push_back(): This function is used to input a character at the end of the rope. Time Complexity: O(log N).
- pop_back(): Introduced from C++11(for strings), this function is used to delete the last character from the rope. Time Complexity: O(log N).
- insert(int x, crope r1): Inserts the contents of r1 before the xth element. Time Complexity: For Best Case: O(log N) and For Worst Case: O(N).
- erase(int x, int l): Erases l elements, starting with the xth element. Time Complexity: O(log N).
- substr(int x, int l): Returns a new rope whose elements are the l characters starting at the position x. Time Complexity: O(log N).
- replace(int x, int l, crope r1): Replaces the l elements beginning with the xth element with the elements in r1. Time Complexity: O(log N).
- concatenate(+): concatenate two ropes using the ‘+’ symbol. Time Complexity: O(1).
Below is the program for the same:
Program 2:
// C++ program to illustrate the use // of ropes using Rope header file #include <ext/rope> #include <iostream> // SGI extension using namespace __gnu_cxx;
using namespace std;
// Driver Code int main()
{ // rope<char> r = "abcdef"
crope r = "geeksforgeeks" ;
cout << "Initial rope: "
<< r << endl;
// 'g' is added at the
// end of the rope
r.push_back( 'g' );
r.push_back( 'f' );
r.push_back( 'g' );
cout << "Rope after pushing f: "
<< r << endl;
int pos = 2;
// gfg will be inserted
// before position 2
r.insert(pos - 1, "gfg" );
cout << "Rope after inserting "
<< "gfg at position 2: " << r
<< endl;
// gfg will be deleted
r.erase(pos - 1, 3);
cout << "Rope after removing gfg"
<< " inserted just before: "
<< r << endl;
// Replace "ee" with "00"
r.replace(pos - 1, 2, "00" );
cout << "Rope after replacing "
<< "characters: " << r
<< endl;
// Slice the rope
crope r1 = r.substr(pos - 1, 2);
cout << "Subrope at position 2: "
<< r << endl;
// Removes the last element
r.pop_back();
r.pop_back();
r.pop_back();
cout << "Final rope after popping"
<< " out 3 elements: " << r;
return 0;
} |
Initial rope: geeksforgeeks Rope after pushing f: geeksforgeeksgfg Rope after inserting gfg at position 2: ggfgeeksforgeeksgfg Rope after removing gfg inserted just before: geeksforgeeksgfg Rope after replacing characters: g00ksforgeeksgfg Subrope at position 2: g00ksforgeeksgfg Final rope after popping out 3 elements: g00ksforgeeks
Capacity Functions:
- size(): Returns the length of the rope.
- max_size(): Size of longest rope guaranteed to be representable.
Below is the program for the same:
Program 3:
// C++ program to illustrate the use // of ropes using Rope header file #include <ext/rope> #include <iostream> // SGI extension using namespace __gnu_cxx;
using namespace std;
// Driver Code int main()
{ // rope<char> r = "abcdef"
crope r = "abcdef" ;
cout << r.size() << endl;
cout << r.max_size() << endl;
return 0;
} |
6 1836311902
Iterators:
- mutable_begin(): Returns an iterator pointing to the beginning of the rope.
- mutable_end(): Returns an iterator pointing to the end of the rope.
Below is the program for the same:
Program 4:
// C++ program to illustrate the use // of ropes using Rope header file #include <ext/rope> #include <iostream> // SGI extension using namespace __gnu_cxx;
using namespace std;
// Driver Code int main()
{ // rope<char> r = "abcdef"
crope r = "abcdef" ;
rope< char >::iterator it;
for (it = r.mutable_begin();
it != r.mutable_end(); it++) {
// Print the value
cout << char ((*it) + 2)
<< "" ;
}
return 0;
} |
cdefgh