数据结构与STL 8.5分
读书笔记 6.2.1 Editor类的设计
revivedsun

学完该章节 list 的几种实现方式(,双向链表,主表加编表,边表通过游标维护元素之间的先后顺序),并实现了一个简化版Editor。 特别注意erase时迭代器失效的处理方式。

#include <iostream>
#include <list>
#include <string>
using namespace std;

#define MISSING_NUMBER_ERROR	  "MISSING NUMBER ERROR"
#define TWO_NUMBER_ERROR		  "TWO NUMBER ERROR"
#define ILLEGAL_COMMAND_ERROR	  "ILLEGAL COMMAND ERROR"
#define MISSING_COMMAND_ERROR	  "Missing command error"
#define LINE_TOO_LONG_ERROR		  "line's length is too long"
#define LINE_NUMBER_OUT_OF_RANGE  "line number of out range"

const string COMMAND_START  = "$";
const string BLANK = " ";

const string INSERT_COMMAND = "Insert";
const string DELETE_COMMAND = "Delete";
const string LINE_COMMAND	= "Line";
const string DONE_COMMAND   = "Done";


class Editor
{
	public:
		Editor();
		string parse(const string& line);
		string command_check(const string& line);
		string insert_command();
		string delete_command(int k,int m);
		string line_command(int m);
		string done_command();    
	protected:
		list<string> text;
		list<string>::iterator current;
		int currentLineNumber;
		size_t MAX_LINE_LENGTH;
};


Editor::Editor()
{
	current = text.begin();
	currentLineNumber = -1;
	inserting = false;
	MAX_LINE_LENGTH = 75;
}

string Editor::parse(const string& line)    
{
	string test = "cmd";
	string ret;
	string cmd;
	if (line.substr(0,1) == COMMAND_START)  // 是命令
	{
		if (line.find(INSERT_COMMAND) != string::npos)
		{
			return insert_command();            
		}
		else if(line.find(DELETE_COMMAND) != string::npos)
		{
			string para1,para2;
			size_t pos1,pos2;
			pos1 = line.find(BLANK);
			pos2 = line.find(BLANK,pos1+1);
			para1 = line.substr(pos1+1,pos2-pos1);
			para2 = line.substr(pos2+1);
			return delete_command(atoi(para1.c_str()),atoi(para2.c_str()));
		}
		else if(line.find(LINE_COMMAND) != string::npos)
		{
			string para,ret;
			size_t pos = line.find(BLANK);
			para = line.substr(pos+1);
			return line_command(atoi(para.c_str()));
		}
	}
	return ILLEGAL_COMMAND_ERROR;
}

string Editor::done_command()
{
	const string FINAL_MESSAGE = "Here is the final text:\n";
	string text_string = FINAL_MESSAGE;
	if (currentLineNumber == -1)
	{
		text_string += ">\n";
	}
	for (list<string>::iterator itr = text.begin(); itr != text.end(); itr++)
	{
		if (itr != current)
		{
			text_string += (*itr)+"\n";
		}
		else
		{
			text_string += ">"+(*itr)+"\n";
		}
	}
	return text_string;  // 返回空白
}

string Editor::delete_command(int k,int m)
{
	string OUT_OF_RANGE = "parameters out of range";
	if (k<0 || m > (int)text.size() || k>m)
	{
		return OUT_OF_RANGE;
	}
	list<string>::iterator iter = text.begin();
	for(int i = 0; i < k; i++)
	{
		iter++;
	}
	for(int i = k;i<=m;i++)
	{
		text.erase(iter++);
	}
	current = text.begin();
	return BLANK;
}

string Editor::line_command(int m)
{
	int lineLength = text.size();
	if (m<0 || m>= lineLength)
	{
		return LINE_NUMBER_OUT_OF_RANGE;
	}
	while ((currentLineNumber) < m)
	{
		current++;
		currentLineNumber++;
	}
	while((currentLineNumber) > m)
	{
		current--;
		currentLineNumber--;
	}
	return BLANK;
}

string Editor::insert_command()
{
	string msg;
	cout<<"Input Message>";
	getline(cin,msg);
	if (msg.length() > MAX_LINE_LENGTH)  // 超过单行最大长度,出错
	{
		return LINE_TOO_LONG_ERROR;
	}
	text.insert(current,msg);  // 在当前位置下一行
	current++;
	currentLineNumber++;
	return BLANK;
}

int main(int argc, char *argv[])
{
	const string PROMPT = "Please enter a line:";
	Editor editor;
	string result;
	string line;
	do 
	{
		cout<<PROMPT<<endl;
		getline(cin,line);
		if (line.find(DONE_COMMAND) != string::npos)
		{
			result = editor.done_command();
			cout<<result<<endl;
			break;
		}
		result = editor.parse(line);  // 解析命令
		cout<<result<<endl;
	} while (true);
	return 0;
}

0
《数据结构与STL》的全部笔记 4篇
豆瓣
免费下载 iOS / Android 版客户端