当前位置: 首页 > news >正文

C++--------效率和表示

C++ 效率和表示

  1. 效率
    • 时间效率:在 C++ 中,不同的数据结构和算法有着各异的时间复杂度。例如,访问数组元素的时间复杂度是 O ( 1 ) O(1) O(1),而遍历链表查找元素的时间复杂度最坏情况下是 O ( n ) O(n) O(n)。选择合适的算法与数据结构能极大提升程序运行速度。像排序算法里,快速排序平均时间复杂度为 O ( n l o g n ) O(n log n) O(nlogn),比冒泡排序的 O ( n 2 ) O(n^2) O(n2) 快得多。
    • 空间效率:同样的数据,不同表示占用空间不同。动态数组按需扩容,若扩容策略不佳会浪费空间;链表每个节点有额外指针开销,相比连续内存存储(如数组)会多占内存。尽量紧凑地组织数据,避免不必要的内存冗余,能提升空间利用率。
  2. 表示
    • 数组:是连续内存块,通过索引快速访问元素。适合随机存取场景,像科学计算中频繁读取矩阵元素。int arr[10]; 声明了一个简单的静态整型数组。动态数组可用 new int[n]; 分配,使用完需 delete[] 释放。
    • :遵循后进先出(LIFO)原则,操作集中在栈顶。在表达式求值、函数调用管理场景常用。用 std::stack 类很方便,例如:
    #include <stack>
    std::stack<int> s;
    s.push(1);
    int top = s.top();
    s.pop();
    
    • 链表:由节点串联而成,节点含数据与指针。适合频繁插入删除场景,因为无需移动大量元素。单链表节点结构:struct Node { int data; Node* next; };

编辑文本的软件模式

  1. 命令模式
    • 将操作封装成命令对象,文本编辑器的撤销、重做功能常用此模式。每个命令实现 executeundo 方法,用户操作时,创建对应命令执行,要撤销就反向调用 undo。比如复制文本命令,execute 执行复制,undo 把复制内容清除。
  2. 观察者模式
    • 文本编辑器里,文档内容变化可能关联多个视图更新,如实时预览窗口。文档作为被观察对象,视图是观察者,文档状态变时通知所有关联视图更新,保持一致性。
  3. 单例模式
    • 文本编辑器的配置管理类常是单例,全局仅有一个实例,方便统一管理诸如字体、字号、颜色偏好等设置,避免多处配置冲突。

设计简单的文本编辑器

  1. 基于数组类的实现
    • 数据存储:用动态数组存储文本字符,std::vector<char> 很适用。
    • 插入操作:在指定位置插入字符,需将插入点后的元素依次后移。例如:
    #include <vector>
    #include <iostream>class TextEditorArray {
    private:std::vector<char> text;
    public:void insert(char c, int pos) {if (pos <= text.size()) {text.insert(text.begin() + pos, c);}}void print() {for (char ch : text) {std::cout << ch;}std::cout << std::endl;}
    };
    
  2. 基于栈的类实现
    • 思路:把文本的每一行看作一个栈元素,利用栈的特性来处理文本。插入新行类似入栈,删除行类似出栈。
    • 代码示例
    #include <stack>
    #include <string>
    #include <iostream>class TextEditorStack {
    private:std::stack<std::string> lines;
    public:void insertLine(const std::string& line) {lines.push(line);}void deleteLine() {if (!lines.empty()) {lines.pop();}}void print() {std::stack<std::string> temp = lines;while (!temp.empty()) {std::cout << temp.top() << std::endl;temp.pop();}}
    };
    
  3. 基于列表的实现
    • 数据结构:用链表存储文本行,方便插入、删除操作。单链表节点结构存储一行文本。
    • 代码示例
    #include <iostream>struct LineNode {std::string line;LineNode* next;LineNode(const std::string& l) : line(l), next(nullptr) {}
    };class TextEditorList {
    private:LineNode* head;
    public:TextEditorList() : head(nullptr) {}void insertLine(const std::string& line) {LineNode* newNode = new LineNode(line);newNode->next = head;head = newNode;}void deleteLine() {if (head) {LineNode* temp = head;head = head->next;delete temp;}}void print() {LineNode* current = head;while (current) {std::cout << current->line << std::endl;current = current->next;}}
    };
    

以上这些简单的文本编辑器实现只是基础示例,真实的文本编辑器还需考虑诸如文件读写、光标定位、格式编辑等复杂功能。

简单的文本器设计思路

以下是一个简单文本编辑器的详细设计思路:

一、功能需求分析

  1. 文本输入与显示

    • 用户能够通过键盘输入字符,并实时在屏幕上显示输入的文本内容。
    • 支持换行操作,使文本呈现多行结构。
  2. 基本编辑功能

    • 插入:在光标位置插入新的字符、字符串或段落。光标位置应能通过键盘方向键或鼠标点击灵活控制。
    • 删除:删除光标位置的单个字符,或选中一段文本后批量删除。
    • 替换:将指定的字符或字符串替换为新的内容。
  3. 光标移动

    • 可以通过键盘上的方向键(上、下、左、右)精确控制光标在文本中的位置,实现逐字符或逐行移动。
    • 具备快速移动功能,如 Home 键移到行首、End 键移到行尾、Ctrl + Home 移到文本开头、Ctrl + End 移到文本末尾等。
      在这里插入图片描述
  4. 文本选择

    • 用户能够使用鼠标拖动或键盘组合键(如 Shift + 方向键)选中一段文本,选中后的文本有明显的视觉标识(如反色显示),以便进行后续的复制、剪切、删除等操作。
  5. 复制、剪切与粘贴

    • 复制:将选中的文本复制到剪贴板,供后续粘贴使用。
    • 剪切:把选中的文本移动到剪贴板,同时从原位置删除。
    • 粘贴:将剪贴板中的内容插入到光标所在位置。
  6. 保存与加载

    • 能够将编辑的文本保存到本地文件系统,支持常见的文本文件格式,如.txt。
    • 可以从文件中加载已有的文本,方便用户继续编辑。
  7. 撤销与重做

    • 撤销:取消最近一次的编辑操作,恢复到操作前的文本状态,支持多级撤销,以便用户回溯到之前的多个编辑步骤。
    • 重做:在撤销操作后,如果用户又想恢复被撤销的操作,可使用重做功能,同样支持多级重做。

二、数据结构选择

  1. 基于数组或动态数组(如 std::vector

    • 优点:
      • 随机访问效率高,对于在固定位置插入或读取文本字符较为便捷。例如,当用户通过光标定位到某一具体位置进行插入操作时,利用数组索引能快速定位到插入点。
      • 内存管理相对简单,std::vector 在 C++ 中可以自动扩容,无需开发者过多操心内存分配问题。
    • 缺点:
      • 在文本中间频繁插入或删除元素时,需要移动大量后续元素,操作效率较低。例如,若要在一段较长文本的中间插入一个段落,就需要将插入点之后的所有元素依次向后移动相应的位置,时间复杂度较高。
  2. 基于链表

    • 优点:
      • 对于频繁的插入和删除操作具有优势,只需修改相邻节点间的指针,无需大规模移动元素。比如,在文本编辑过程中经常需要插入新行或删除某些行,链表结构能轻松应对。
      • 可以灵活地动态扩展,适应不同长度的文本需求。
    • 缺点:
      • 随机访问困难,要访问链表中的某个特定节点,需要从表头开始逐个遍历节点,时间复杂度为 O ( n ) O(n) O(n),这在需要快速定位文本中某一具体位置时效率较低。
      • 内存开销相对较大,每个节点除了存储文本数据本身,还需要额外的指针空间来指向下一个节点。
  3. 结合使用数组与链表

    • 思路:可以考虑用数组存储文本的行,而每行内部再用链表来处理字符的插入、删除等操作。这样既能利用数组便于行管理的优势,又能发挥链表在字符层面灵活操作的长处。
    • 例如:创建一个 std::vector,其中每个元素是一个指向链表表头的指针,链表节点存储该行的字符。当需要插入一行新文本时,在 std::vector 中新增一个元素指向新创建的链表;当需要在某行内插入字符时,利用该行对应的链表进行操作。

三、界面设计

  1. 文本显示区域

    • 占据编辑器的主要部分,用于实时展示编辑的文本内容。文本应清晰可读,具备合适的字体、字号和颜色对比度。
    • 可以设置滚动条,方便用户查看较长的文本。滚动条的行为要与光标移动和文本选择等操作相协调,确保用户操作流畅。
  2. 菜单栏

    • 包含常见的文件操作(如保存、打开、新建)、编辑操作(如复制、剪切、粘贴、撤销、重做)以及视图设置(如字体、字号调整)等菜单选项。
    • 每个菜单选项应配有易于理解的图标和快捷键,方便用户快速操作。例如,Ctrl + S 用于保存文件,Ctrl + C 用于复制等。
  3. 工具栏

    • 提供常用操作的快捷按钮,与菜单栏中的部分选项相对应,如保存、打开、复制、粘贴等按钮,进一步简化用户操作流程。
    • 按钮的布局要合理,美观大方,方便用户点击。
  4. 状态栏

    • 显示当前文本的一些基本信息,如行数、列数、当前的编辑模式(如插入模式或改写模式)、是否有文本被选中以及文件的保存状态等。

四、算法实现

  1. 插入算法

    • 若基于数组:
      • 当在光标位置插入字符时,首先判断数组是否已满,若已满需进行扩容操作(如 std::vector 会自动扩容,但效率问题需关注)。
      • 然后将光标位置及之后的元素依次向后移动一位,腾出插入空间,最后将新字符插入光标位置。
    • 若基于链表:
      • 对于行内插入,找到对应的链表节点,创建新节点并插入到合适位置,修改相邻节点的指针关系。
      • 对于插入新行,创建新的链表表示新行,并插入到行链表结构中的合适位置(如根据光标所在行的前后关系)。
  2. 删除算法

    • 基于数组:
      • 若删除单个字符,将光标位置之后的元素依次向前移动一位,覆盖要删除的字符,同时更新光标位置。
      • 若删除一段文本,类似地移动元素,填补被删除文本的空缺。
    • 基于链表:
      • 对于行内删除,找到要删除的节点,修改相邻节点的指针,使其跳过被删除节点,然后释放该节点内存。
      • 对于删除整行,在行链表中找到该行对应的链表头部,移除该行并释放相关链表节点内存。
  3. 光标移动算法

    • 根据键盘输入的方向键或鼠标点击位置,基于所选的数据结构进行相应的计算和调整。
    • 例如,若基于数组,使用方向键移动光标时,根据方向更新数组索引;若基于链表,需要沿着链表节点依次移动,找到目标位置对应的节点。
  4. 复制、剪切与粘贴算法

    • 复制和剪切:
      • 当选中一段文本后,将选中的文本内容存储到剪贴板中。若基于数组,可通过索引范围提取文本;若基于链表,沿着链表节点遍历提取文本。
    • 粘贴:
      • 将剪贴板中的文本插入到光标所在位置。同样,依据数据结构特点进行插入操作,如基于数组要移动元素腾出空间,基于链表要创建新节点插入。
  5. 撤销与重做算法

    • 可以采用命令模式实现:
      • 将每次编辑操作封装成一个命令对象,命令对象包含执行操作(如插入、删除等)和撤销操作的方法。
      • 维护一个命令栈,每执行一个新操作,将对应的命令对象压入栈中。当需要撤销时,从栈顶弹出命令对象并执行其撤销方法;当需要重做时,在撤销后若栈顶还有可重做的命令对象,执行其执行方法。

五、错误处理与稳定性

  1. 内存管理

    • 无论是使用数组还是链表,都要确保内存的正确分配与释放。在动态分配内存的过程中,如使用 newdeletestd::vector 等容器时,避免内存泄漏、悬空指针等问题。
    • 例如,在删除链表节点时,一定要先正确修改相邻节点的指针关系,再释放节点内存,防止内存错误。
  2. 异常处理

    • 对于文件保存、加载等操作,可能会遇到文件不存在、权限不足等问题,要设置相应的异常处理机制。
    • 比如,在保存文件时,如果因磁盘空间不足或文件被其他程序占用而导致保存失败,应及时向用户反馈错误信息,并提供合理的解决方案建议,如清理磁盘空间或关闭其他占用程序。
  3. 边界情况处理

    • 考虑各种边界情况,如空文本、文本开头或结尾的操作、最大文件容量限制等。
    • 例如,当用户在空文本的基础上进行插入操作时,要确保程序正常运行,不会出现崩溃或异常行为;当文本达到预先设定的最大容量时,要提醒用户并采取适当的限制措施,如禁止继续插入新内容。

通过以上设计思路,可以构建一个具备基本功能、操作流畅、稳定性高的简单文本编辑器。随着进一步深入学习和实践,还可以不断添加诸如文本格式设置、自动保存、多文档编辑等高级功能,使其更加完善。

在这里插入图片描述

相关文章:

C++--------效率和表示

C 效率和表示 效率 时间效率&#xff1a;在 C 中&#xff0c;不同的数据结构和算法有着各异的时间复杂度。例如&#xff0c;访问数组元素的时间复杂度是 O ( 1 ) O(1) O(1)&#xff0c;而遍历链表查找元素的时间复杂度最坏情况下是 O ( n ) O(n) O(n)。选择合适的算法与数据…...

在 Ubuntu 服务器上添加和删除用户

在 Ubuntu 服务器上添加和删除用户通常使用命令行工具&#xff0c;如 adduser、useradd、deluser 等。以下是详细的步骤和说明&#xff1a; 添加用户 使用 adduser 命令 adduser 是一个更为友好的脚本&#xff0c;用于创建新用户并设置相关信息。 添加新用户 sudo adduser 用…...

安卓 SystemServer 启动流程

目录 引言 Android系统服务启动顺序 zygote fork SystemServer 进程 SystemServer启动流程 1、SystemServer.main() 2、SystemServer.run() 3、初始化系统上下文 4、创建系统服务管理 5、启动系统各种服务 总结 引言 开机启动时 PowerManagerService 调用 AudioSer…...

深度分析 es multi_match 中most_fields、best_fields、cross_fields区别

文章目录 1. multi_match 查询的类型1.1 best_fields&#xff08;默认&#xff09;1.2 most_fields1.3 cross_fields 2. 不同类型的示例查询示例数据&#xff1a; 3. 示例 1: 使用 best_fields查询&#xff1a;说明&#xff1a; 4. 示例 2: 使用 most_fields查询&#xff1a;说…...

中职计算机网络技术理实一体化实训室建设方案

构建理实一体化教学模式对于改善中等职业学校计算机网络技术课程的教学现状、提升教学质量和效率具有重要意义。在中职教育不断深化改革的背景下&#xff0c;积极推进理实一体化教学模式的发展&#xff0c;不仅能够提高计算机网络技术课程的教学水平&#xff0c;满足教育改革的…...

Java技术专家视角解读:SQL优化与批处理在大数据处理中的应用及原理

引言 在大厂架构中&#xff0c;提升系统性能和稳定性是技术团队的首要任务。SQL优化与批处理作为两大关键技术手段&#xff0c;对于处理大规模数据和高并发请求具有重要意义。本文将从Java技术专家的视角出发&#xff0c;深入探讨SQL优化与批处理在大数据处理中的应用及原理&a…...

数据结构(Java版)第六期:LinkedList与链表(一)

目录 一、链表 1.1. 链表的概念及结构 1.2. 链表的实现 专栏&#xff1a;数据结构(Java版) 个人主页&#xff1a;手握风云 一、链表 1.1. 链表的概念及结构 链表是⼀种物理存储结构上⾮连续存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的引⽤链接次序实现的。与火车…...

云边端一体化架构

云边端一体化架构是一种将云计算、边缘计算和终端设备相结合的分布式计算模型。该架构旨在通过优化资源分配和数据处理流程&#xff0c;提供更高效、更低延迟的服务体验。 下面是对这个架构的简要说明&#xff1a; 01云计算&#xff08;Cloud Computing&#xff09; — 作为中心…...

人工智能之基于阿里云进行人脸特征检测部署

人工智能之基于阿里云进行人脸特征检测部署 需求描述 基于阿里云搭建真人人脸68个关键点检测模型&#xff0c;模型名称&#xff1a;Damo_XR_Lab/cv_human_68-facial-landmark-detection使用上述模型进行人脸关键点识别&#xff0c;模型地址 业务实现 阿里云配置 阿里云配置…...

基于高云GW5AT-15 FPGA的SLVS-EC桥MIPI设计方案分享

作者&#xff1a;Hello,Panda 一、设计需求 设计一个4Lanes SLVS-EC桥接到2组4lanes MIPI DPHY接口的电路模块&#xff1a; &#xff08;1&#xff09;CMOS芯片&#xff1a;IMX537-AAMJ-C&#xff0c;输出4lanes SLVS-EC 4.752Gbps Lane速率&#xff1b; &#xff08;2&…...

MPLS小实验:利用LDP动态建立LSP

正文共&#xff1a;1234 字 19 图&#xff0c;预估阅读时间&#xff1a;2 分钟 通过上个实验&#xff08;MPLS小实验&#xff1a;静态建立LSP&#xff09;&#xff0c;我们了解到静态LSP不依靠标签分发协议&#xff0c;而是在报文经过的每一跳设备上&#xff08;包括Ingress、T…...

C++ 面向对象编程

面向对象编程&#xff08;Object-Oriented Programming, OOP&#xff09;是C语言的一个重要特性&#xff0c;它允许开发者以更直观和模块化的方式来设计和构建程序。OOP的四个主要原则是&#xff1a;封装&#xff08;Encapsulation&#xff09;、继承&#xff08;Inheritance&a…...

我的Serverless实战——引领云计算的下一个十年,附答案

&#xff08;Serverless模式下&#xff0c;按照实际消耗资源及使用存储进行计费&#xff09; 4.更少的代码&#xff0c;更快的交付速度。 &#xff08;Serverless提供成熟的代码构建发布、版本切换等特性&#xff0c;交付速度更快&#xff09; Serverless由开发者实现的服务端逻…...

有哪些其他方法可以实现数据一致性验证?

数据库约束 主键约束&#xff1a; 主键是表中用于唯一标识每条记录的一列或一组列。例如&#xff0c;在一个“用户表”中&#xff0c;用户ID可以作为主键。当插入或更新数据时&#xff0c;数据库会自动检查主键值是否唯一。如果试图插入一个已存在主键值的记录&#xff0c;数据…...

vue 基础学习

一、ref 和reactive 区别 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head> <body><div id"app"><h1>{{Web.title}}</h1><h1&…...

HarmonyOS NEXT 实战之元服务:静态案例效果---查看国际航班服务

背景&#xff1a; 前几篇学习了元服务&#xff0c;后面几期就让我们开发简单的元服务吧&#xff0c;里面丰富的内容大家自己加&#xff0c;本期案例 仅供参考 先上本期效果图 &#xff0c;里面图片自行替换 效果图1完整代码案例如下&#xff1a; Index代码 import { authen…...

PetaLinux 内核输出信息的获取方式

串口终端: 默认输出方式。 曾尝试过将串口终端的输出重映射到伪终端&#xff0c;失败了。 伪终端: dmesg命令 dmesg是Linux系统重查看内核日志的使用工具&#xff0c;允许查看系统内核的输出消息&#xff0c;包括引导信息&#xff0c;硬件检测&#xff0c;设备驱动和系统错…...

Android使用辅助服务AccessibilityService实现自动化任务

Android 辅助服务&#xff08;AccessibilityService&#xff09;旨在帮助具有视觉、身体或年龄相关限制的用户更轻松地使用 Android 设备和应用。通过辅助服务&#xff0c;可以将一些人工操作自动化&#xff0c;从而解放用户的双手。 因此我们可以使用它来实现一些自动化任务&a…...

工业大数据分析算法实战-day15

文章目录 day15特定数据类型的算法工业分析中的数据预处理工况划分数据缺失时间数据不连续强噪声大惯性系统趋势项消除 day15 今天是第15天&#xff0c;昨日是针对最优化算法、规则推理算法、系统辨识算法进行了阐述&#xff0c;今日主要是针对其他算法中的特定数据类型的算法…...

C语言实现顺序表详解

文章目录 [TOC] 1.前言&#x1f64b;&#x1f3fc;‍♂️2.顺序表&#x1f9e3;2.1 顺序表概念&#x1f9e3;2.2 顺序表特点&#x1f9e3;2.2 顺序表作用&#x1f9e3; 3.顺序表基操&#x1f9e4;3.1 结构体初始化&#x1f389;3.2 顺序表初始化&#x1f389;3.3 顺序表创建&am…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

听写流程自动化实践,轻量级教育辅助

随着智能教育工具的发展&#xff0c;越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式&#xff0c;也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建&#xff0c;…...

在Ubuntu24上采用Wine打开SourceInsight

1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...

网站指纹识别

网站指纹识别 网站的最基本组成&#xff1a;服务器&#xff08;操作系统&#xff09;、中间件&#xff08;web容器&#xff09;、脚本语言、数据厍 为什么要了解这些&#xff1f;举个例子&#xff1a;发现了一个文件读取漏洞&#xff0c;我们需要读/etc/passwd&#xff0c;如…...

计算机基础知识解析:从应用到架构的全面拆解

目录 前言 1、 计算机的应用领域&#xff1a;无处不在的数字助手 2、 计算机的进化史&#xff1a;从算盘到量子计算 3、计算机的分类&#xff1a;不止 “台式机和笔记本” 4、计算机的组件&#xff1a;硬件与软件的协同 4.1 硬件&#xff1a;五大核心部件 4.2 软件&#…...

DeepSeek源码深度解析 × 华为仓颉语言编程精粹——从MoE架构到全场景开发生态

前言 在人工智能技术飞速发展的今天&#xff0c;深度学习与大模型技术已成为推动行业变革的核心驱动力&#xff0c;而高效、灵活的开发工具与编程语言则为技术创新提供了重要支撑。本书以两大前沿技术领域为核心&#xff0c;系统性地呈现了两部深度技术著作的精华&#xff1a;…...

[USACO23FEB] Bakery S

题目描述 Bessie 开了一家面包店! 在她的面包店里&#xff0c;Bessie 有一个烤箱&#xff0c;可以在 t C t_C tC​ 的时间内生产一块饼干或在 t M t_M tM​ 单位时间内生产一块松糕。 ( 1 ≤ t C , t M ≤ 10 9 ) (1 \le t_C,t_M \le 10^9) (1≤tC​,tM​≤109)。由于空间…...

【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅!

【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅! 🌱 前言:一棵树的浪漫,从数组开始说起 程序员的世界里,数组是最常见的基本结构之一,几乎每种语言、每种算法都少不了它。可你有没有想过,一组看似“线性排列”的有序数组,竟然可以**“长”成一棵平衡的二…...

leetcode_69.x的平方根

题目如下 &#xff1a; 看到题 &#xff0c;我们最原始的想法就是暴力解决: for(long long i 0;i<INT_MAX;i){if(i*ix){return i;}else if((i*i>x)&&((i-1)*(i-1)<x)){return i-1;}}我们直接开始遍历&#xff0c;我们是整数的平方根&#xff0c;所以我们分两…...