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. 边界情况处理

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

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

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/942593.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Mac】终端改色-让用户名和主机名有颜色

效果图 配置zsh 1.打开终端&#xff0c;进入.zshrc配置 cd ~ vim .zshrc2.添加如下配置并保存 # 启用命令行颜色显示 export CLICOLOR1 ## 加载颜色支持 autoload -U colors && colors # 配置 zsh 提示符 PROMPT"%{$fg_bold[red]%}%n%{$reset_color%}%{$fg_bol…

模拟——郑益慧_笔记1_绪论

B站视频链接 模电是数电的基础&#xff1b;参考书&#xff1a; 模拟电子技术基础&#xff08;第四版&#xff09;华成英、童诗白主编&#xff0c;高等教育出版社&#xff1b;电子技术基础 模拟部分 康华光主编&#xff0c;高等教育出版社&#xff1b; 电子技术的发展史 电子…

YOLOv11模型改进-模块-引入多尺度大核注意力Multi-scale Large Kernel Attention

MLKA 的提出源于图像超分辨率任务的挑战性&#xff0c;该任务需重建低质量图像缺失的高频信息&#xff0c;但因 LR 与 HR 图像对应关系复杂&#xff0c;寻找像素相关性困难。此前模型扩展容量的方法增加了训练负担和数据收集成本&#xff0c;而采用的注意力机制无法同时获取局部…

【gym】给定的强化学习环境简介(二)

文章目录 环境介绍一 box2dbipedal_walkercar_dynamicscar_racinglunar_lander 二、 classic_controlacrobotCartPolecontinuous_mountain_carmountain_carpendulum 三、toy_textblackjackcliffwalkingfrozentaxi 四、mujocoAnt&#xff1a;HalfCheetah&#xff1a;Hopper&…

基于支付宝百宝箱构建自己的Agent的基本简易流程(Datawhale AI冬令营)

一&#xff0c;使用支付宝百宝箱 官网地址&#xff1a;百宝箱 (alipay.com) 二&#xff0c;应用构建 点击左上角的新建应用 然后按自己的需求选择对应的模块 以下是我的示例 点击确认之后&#xff0c;进入模型设置界面 按需设计便可以&#xff0c;以下是我的设计 当你写好…

攻防世界 - Web - Level 1 unseping

关注这个靶场的其它相关笔记&#xff1a;攻防世界&#xff08;XCTF&#xff09; —— 靶场笔记合集-CSDN博客 0x01&#xff1a;Write UP 本关是一个 PHP 代码审计关卡&#xff0c;考察的是 PHP 反序列化漏洞以及命令执行的一些绕过手段&#xff0c;下面笔者将带你一步步过关。…

Java进阶学习笔记|面向对象

第一章.类和对象 1.面向对象的介绍 1.面向过程:自己的事情自己干,代表语言C语言洗衣服:每一步自己要亲力亲为 -> 找个盆,放点水,找个搓衣板,搓搓搓 2.面向对象:自己的事情别人帮忙去干,代表语言Java语言 洗衣服:自己的事情别人干 -> 全自动洗衣机3.为啥要使用面向对…

前端性能优化之大文件上传

大文件上传是前端开发中常见的需求之一&#xff0c;特别是在需要处理较大的Excel表格数据、高清图片、视频或其他大型文件时。优化大文件上传不仅可以提升用户体验&#xff0c;还能有效减轻服务器负担。本文将深入探讨大文件上传的几种常见优化技术&#xff0c;包括文件切片与并…

数据结构之线性表之顺序表

定义&#xff1a; 由n&#xff08;n>0&#xff09;个数据特性相同的元素构成的有限序列称为线性表 简单来说n个相同数据类型的数据组wsw合在一起的这么一个集合就是一个线性表 线性表包括顺序表和链表 1. 顺序表&#xff08;我们所有的代码实现都用函数来封装&#xff09…

Matlab 和 R 语言的数组索引都是从 1 开始,并且是左闭右闭的

文章目录 一、前言二、主要内容三、小结 &#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 一、前言 在早期的计算机科学中&#xff0c;数组索引从 1 开始是很常见的。例如&#xff0c;Fortran 和 Pascal 等编程语言也采用了从 1 开始的索引。 这种索引…

突发!!!GitLab停止为中国大陆、港澳地区提供服务,60天内需迁移账号否则将被删除

GitLab停止为中国大陆、香港和澳门地区提供服务&#xff0c;要求用户在60天内迁移账号&#xff0c;否则将被删除。这一事件即将引起广泛的关注和讨论。以下是对该事件的扩展信息&#xff1a; 1. 背景介绍&#xff1a;GitLab是一家全球知名的软件开发平台&#xff0c;提供代码托…

瑞吉外卖项目学习笔记(八)修改菜品信息、批量启售/停售菜品

瑞吉外卖项目学习笔记(一)准备工作、员工登录功能实现 瑞吉外卖项目学习笔记(二)Swagger、logback、表单校验和参数打印功能的实现 瑞吉外卖项目学习笔记(三)过滤器实现登录校验、添加员工、分页查询员工信息 瑞吉外卖项目学习笔记(四)TableField(fill FieldFill.INSERT)公共字…

C++小碗菜之五:关键字static

“一个人的命运啊&#xff0c;当然要靠自我奋斗&#xff0c;但也要考虑到历史的行程。” ——2009年4月23日在视察中国联合工程公司时的讲话 目录 ​编辑 前言 static在局部作用域中的作用 给出例子&#xff1a; 修改上面给出的例子&#xff1a; 为什么不使用全局变量…

开源云原生数据仓库ByConity ELT 的测试体验

ByConity 是分布式的云原生SQL数仓引擎&#xff0c;擅长交互式查询和即席查询&#xff0c;具有支持多表关联复杂查询、集群扩容无感、离线批数据和实时数据流统一汇总等特点。 ByConity 是一个云原生的、高性能的实时数据仓库&#xff0c;而 ELT&#xff08;Extract&#xff0c…

Linux -- 线程的优点、pthread 线程库

目录 线程的优点 pthread 线程库 前言 认识线程库 简单验证线程的独立栈空间 线程的优点 与进程之间的切换相比&#xff0c;线程之间的切换需要操作系统做的工作要少得多。 调度进程时&#xff0c;CPU 中有一个 cache&#xff08;缓存&#xff0c;提高运行效率&#xff0…

数字IC前端学习笔记:脉动阵列的设计方法学(四)

相关阅读 数字IC前端https://blog.csdn.net/weixin_45791458/category_12173698.html?spm1001.2014.3001.5482 引言 脉动结构&#xff08;也称为脉动阵列&#xff09;表示一种有节奏地计算并通过系统传输数据的处理单元(PEs)网络。这些处理单元有规律地泵入泵出数据以保持规则…

观察者模式和发布-订阅模式有什么异同?它们在哪些情况下会被使用?

大家好&#xff0c;我是锋哥。今天分享关于【观察者模式和发布-订阅模式有什么异同&#xff1f;它们在哪些情况下会被使用&#xff1f;】面试题。希望对大家有帮助&#xff1b; 观察者模式和发布-订阅模式有什么异同&#xff1f;它们在哪些情况下会被使用&#xff1f; 1000道 …

【LeetCode】726、原子的数量

【LeetCode】726、原子的数量 文章目录 一、递归: 嵌套类问题1.1 递归: 嵌套类问题 二、多语言解法 一、递归: 嵌套类问题 1.1 递归: 嵌套类问题 遇到 ( 括号, 则递归计算子问题 遇到大写字母, 或遇到 ( 括号, 则清算历史, 并开始新的记录 记录由两部分组成: 大写字母开头的 …

【Select 语法全解密】.NET开源ORM框架 SqlSugar 系列

系列文章目录 &#x1f380;&#x1f380;&#x1f380; .NET开源 ORM 框架 SqlSugar 系列 &#x1f380;&#x1f380;&#x1f380; 文章目录 系列文章目录前言一、Select 执行位置二、返回一个字段和多个字段三、单表返回DTO四、多表返回DTO4.1 手动DTO4.2 实体自动映射14.…

WebRTC服务质量(11)- Pacer机制(03) IntervalBudget

WebRTC服务质量&#xff08;01&#xff09;- Qos概述 WebRTC服务质量&#xff08;02&#xff09;- RTP协议 WebRTC服务质量&#xff08;03&#xff09;- RTCP协议 WebRTC服务质量&#xff08;04&#xff09;- 重传机制&#xff08;01) RTX NACK概述 WebRTC服务质量&#xff08;…