间隙缓冲区是一种数据结构,用于以当前正在编辑的有效方式来编辑和存储文本。它也类似于数组,但是在数组中引入了一个间隙,用于处理游标处的多个更改。让我们假设一个间隙是另一个包含空白空间的数组。
示例:考虑一个示例,该示例的初始间隙大小为10,最初,数组或间隙的大小相同,因为我们将元素插入数组的方式类似,元素将插入间隙缓冲区中,唯一的区别是每次插入时间隙大小都会减小。
这是在前面插入字符的基本情况。现在,只要需要在某个位置插入一个字符,我们就可以使用left()和right()将间隙向上移动到该位置,然后尝试插入该字符。
需要间隙缓冲区
- 数组是一种数据结构,用于将项目存储在连续的内存位置。但是,它需要在数组末尾插入O(1),而在前面则需要O(n)时间,因为数组将向右移动n个位置,n是数组的长度。
- 当涉及到文本编辑器时,我们需要一种更快的数据结构来进行插入和修改,因为光标位置存在多个更改。
- 在最坏的情况下,数组将花费O(n)的时间进行插入或修改,如下例所示。
- 为了在前面插入“ GEEKS”,通过移动数组留出空间来插入每个字符。
Gap Buffer中的基本操作
间隙缓冲vs绳索
现在,尽管它的插入花费O(1)时间,但是还有另一个函数grow()花费大约O(n)时间。因此,可能会认为这可能与绳索数据结构花费相同的时间,但是增长成本被其他更便宜的过程(如left(),right()和insert())的摊销成本所补偿。因此,这种数据结构易于实现,因此在文本编辑器中相对于诸如绳索之类的其他结构而言具有首选项。
实现间隙缓冲区
C++
// C++ program of implementation of gap buffer
#include
using namespace std;
char buffer[50];
int gap_size = 10;
int gap_left = 0;
int gap_right = gap_size - gap_left-1;
int size = 10;
// Function that is used to grow the gap
// at index position and return the array
void grow(int k, int position)
{
char a[size];
// Copy characters of buffer to a[]
// after position
for (int i = position; i < size; i++) {
a[i - position] = buffer[i];
}
// Insert a gap of k from index position
// gap is being represented by '-'
for (int i = 0; i < k; i++) {
buffer[i + position] = '_';
}
// Reinsert the remaining array
for (int i = 0; i < position + k; i++) {
buffer[position + k + i] = a[i];
}
size += k;
gap_right+=k;
}
// Function that is used to move the gap
// left in the array
void left(int position)
{
// Move the gap left character by character
// and the buffers
while (position < gap_left) {
gap_left--;
gap_right--;
buffer[gap_right+1] = buffer[gap_left];
buffer[gap_left]='_';
}
}
// Function that is used to move the gap
// right in the array
void right(int position)
{
// Move the gap right character by character
// and the buffers
while (position > gap_left) {
gap_left++;
gap_right++;
buffer[gap_left-1] = buffer[gap_right];
buffer[gap_right]='_';
}
}
// Function to control the movement of gap
// by checking its position to the point of
// insertion
void move_cursor(int position)
{
if (position < gap_left) {
left(position);
}
else {
right(position);
}
}
// Function to insert the string to the buffer
// at point position
void insert(string input, int position)
{
int len = input.length();
int i = 0;
// If the point is not the gap check
// and move the cursor to that point
if (position != gap_left) {
move_cursor(position);
}
// Insert characters one by one
while (i < len) {
// If the gap is empty grow the size
if (gap_right == gap_left) {
int k = 10;
grow(k, position);
}
// Insert the character in the gap and
// move the gap
buffer[gap_left] = input[i];
gap_left++;
i++;
position++;
}
}
// Driver code
int main()
{
// Initializing the gap buffer with size 10
for (int i = 0; i < 10; i++) {
buffer[i] = '_';
}
cout << "Initializing the gap buffer "
<< "with size 10" << endl;
for (int i = 0; i < size; i++) {
cout << buffer[i]<<" ";
}
cout << endl;
// Inserting a string to buffer
string input = "GEEKSGEEKS";
int position = 0;
insert(input, position);
cout << endl;
cout << "Inserting a string to buffer"
<< ": GEEKSGEEKS" << endl;
cout << "Output: ";
for (int i = 0; i < size; i++) {
cout << buffer[i]<<" ";
}
input = "FOR";
position = 5;
insert(input, position);
cout << endl;
cout << endl;
cout << "Inserting a string to buffer"
<< ": FOR" << endl;
cout << "Output: ";
for (int i = 0; i < size; i++) {
cout << buffer[i]<<" ";
}
return 0;
}
Java
// Java program of implementation of gap buffer
import java.util.*;
class GFG
{
static char []buffer = new char[50];
static int gap_size = 10;
static int gap_left = 0;
static int gap_right = gap_size - gap_left - 1;
static int size = 10;
// Function that is used to grow the gap
// at index position and return the array
static void grow(int k, int position)
{
char []a = new char[size];
// Copy characters of buffer to a[]
// after position
for (int i = position; i < size; i++)
{
a[i - position] = buffer[i];
}
// Insert a gap of k from index position
// gap is being represented by '-'
for (int i = 0; i < k; i++)
{
buffer[i + position] = '_';
}
// Reinsert the remaining array
for (int i = 0; i < k; i++)
{
buffer[position + k + i] = a[i];
}
size += k;
gap_right += k;
}
// Function that is used to move the gap
// left in the array
static void left(int position)
{
// Move the gap left character by character
// and the buffers
while (position < gap_left)
{
gap_left--;
gap_right--;
buffer[gap_right + 1] = buffer[gap_left];
buffer[gap_left]='_';
}
}
// Function that is used to move the gap
// right in the array
static void right(int position)
{
// Move the gap right character by character
// and the buffers
while (position > gap_left)
{
gap_left++;
gap_right++;
buffer[gap_left - 1] = buffer[gap_right];
buffer[gap_right]='_';
}
}
// Function to control the movement of gap
// by checking its position to the point of
// insertion
static void move_cursor(int position)
{
if (position < gap_left)
{
left(position);
}
else
{
right(position);
}
}
// Function to insert the string to the buffer
// at point position
static void insert(String input, int position)
{
int len = input.length();
int i = 0;
// If the point is not the gap check
// and move the cursor to that point
if (position != gap_left)
{
move_cursor(position);
}
// Insert characters one by one
while (i < len)
{
// If the gap is empty grow the size
if (gap_right == gap_left)
{
int k = 10;
grow(k, position);
}
// Insert the character in the gap and
// move the gap
buffer[gap_left] = input.charAt(i);
gap_left++;
i++;
position++;
}
}
// Driver code
public static void main(String[] args)
{
// Initializing the gap buffer with size 10
for (int i = 0; i < 10; i++)
{
buffer[i] = '_';
}
System.out.println("Initializing the gap" +
" buffer with size 10");
for (int i = 0; i < size; i++)
{
System.out.print(buffer[i] + " ");
}
System.out.println();
// Inserting a string to buffer
String input = "GEEKSGEEKS";
int position = 0;
insert(input, position);
System.out.println();
System.out.println("Inserting a string " +
"to buffer: GEEKSGEEKS");
System.out.print("Output: ");
for (int i = 0; i < size; i++)
{
System.out.print(buffer[i] + " ");
}
input = "FOR";
position = 5;
insert(input, position);
System.out.println();
System.out.println();
System.out.println("Inserting a string" +
" to buffer: FOR");
System.out.print("Output: ");
for (int i = 0; i < size; i++)
{
System.out.print(buffer[i] + " ");
}
}
}
// This code is contributed by Princi Singh
C#
// C# program of implementation of gap buffer
using System;
class GFG
{
static char []buffer = new char[50];
static int gap_size = 10;
static int gap_left = 0;
static int gap_right = gap_size - gap_left - 1;
static int size = 10;
// Function that is used to grow the gap
// at index position and return the array
static void grow(int k, int position)
{
char []a = new char[size];
// Copy characters of buffer to a[]
// after position
for (int i = position; i < size; i++)
{
a[i - position] = buffer[i];
}
// Insert a gap of k from index position
// gap is being represented by '-'
for (int i = 0; i < k; i++)
{
buffer[i + position] = '_';
}
// Reinsert the remaining array
for (int i = 0; i < k; i++)
{
buffer[position + k + i] = a[i];
}
size += k;
gap_right += k;
}
// Function that is used to move the gap
// left in the array
static void left(int position)
{
// Move the gap left character by character
// and the buffers
while (position < gap_left)
{
gap_left--;
gap_right--;
buffer[gap_right + 1] = buffer[gap_left];
buffer[gap_left]='_';
}
}
// Function that is used to move the gap
// right in the array
static void right(int position)
{
// Move the gap right character by character
// and the buffers
while (position > gap_left)
{
gap_left++;
gap_right++;
buffer[gap_left - 1] = buffer[gap_right];
buffer[gap_right] = '_';
}
}
// Function to control the movement of gap
// by checking its position to the point of
// insertion
static void move_cursor(int position)
{
if (position < gap_left)
{
left(position);
}
else
{
right(position);
}
}
// Function to insert the string to the buffer
// at point position
static void insert(String input, int position)
{
int len = input.Length;
int i = 0;
// If the point is not the gap check
// and move the cursor to that point
if (position != gap_left)
{
move_cursor(position);
}
// Insert characters one by one
while (i < len)
{
// If the gap is empty grow the size
if (gap_right == gap_left)
{
int k = 10;
grow(k, position);
}
// Insert the character in the gap and
// move the gap
buffer[gap_left] = input[i];
gap_left++;
i++;
position++;
}
}
// Driver code
public static void Main(String[] args)
{
// Initializing the gap buffer with size 10
for (int i = 0; i < 10; i++)
{
buffer[i] = '_';
}
Console.WriteLine("Initializing the gap" +
" buffer with size 10");
for (int i = 0; i < size; i++)
{
Console.Write(buffer[i] + " ");
}
Console.WriteLine();
// Inserting a string to buffer
String input = "GEEKSGEEKS";
int position = 0;
insert(input, position);
Console.WriteLine();
Console.WriteLine("Inserting a string " +
"to buffer: GEEKSGEEKS");
Console.Write("Output: ");
for (int i = 0; i < size; i++)
{
Console.Write(buffer[i] + " ");
}
input = "FOR";
position = 5;
insert(input, position);
Console.WriteLine();
Console.WriteLine();
Console.WriteLine("Inserting a string" +
" to buffer: FOR");
Console.Write("Output: ");
for (int i = 0; i < size; i++)
{
Console.Write(buffer[i] + " ");
}
}
}
// This code is contributed by 29AjayKumar
输出:
Initializing the gap buffer with size 10
_ _ _ _ _ _ _ _ _ _
Inserting a string to buffer: GEEKSGEEKS
Output: G E E K S G E E K S _ _ _ _ _ _ _ _ _ _
Inserting a string to buffer: FOR
Output: G E E K S F O R _ _ _ _ _ _ _ G E E K S
插入的时间复杂度:O(1)
增长的时间复杂度:O(n)