力扣 最长回文字串-5

 最长回文字串-5

//双指针,暴力解法
class Solution {
public:bool is(string s, int l, int r) // 判断是否为回文{while (l < r) {if (s[l] != s[r]) {return false;}l++;r--;}return true;}string longestPalindrome(string s) {int Max = 0;//用来判断找出最长字串int templ = 0, tempr = 0;//用来记录最长字串的头和尾char str[1001];//字符数组用来输出找到的最长字串for (int i = 0; i < s.length(); i++) {//循环控制左指针l,int l = i, r = l + 1;//左值针l初始化为i,右指针初始化为l+1while (r < s.length()) {if (s[l] != s[r]) {//如果两字符不等,r向右移动r++;} else {if (is(s, l, r) && Max < r - l + 1) {//如果是回文并且大于Max记录的之前的最长回文字符串Max = r - l + 1;//Max赋值为新的最长回文字符串的长度templ = l;//记录最长字符串的第一个字符的索引tempr = r;//记录最长字符串的最后一个字符的索引}r++;//向右移动}}}int index = 0;for (int i = templ; i <= tempr; i++) {str[index++] = s[i];}return str;}
};
// 优化,中心扩展法
class Solution {
public:string longestPalindrome(string s) {char str[1001];int Max = 0;// 最大回文长度int templ = 0, tempr = 0; // 存储最长回文子串的起始和结束位置// 中心扩展法for (int i = 0; i < s.length(); i++) {// 对于每个字符,检查以该字符为中心的回文(奇数长度)int l = i, r = i;while (l >= 0 && r < s.length() && s[l] == s[r]) {if (r - l + 1 > Max) {Max = r - l + 1;templ = l;tempr = r;}l--;r++;}// 对于每对相邻字符,检查以这对字符为中心的回文(偶数长度)l = i, r = i + 1;while (l >= 0 && r < s.length() && s[l] == s[r]) {if (r - l + 1 > Max) {Max = r - l + 1;templ = l;tempr = r;}l--;r++;}}int index = 0;for (int i = templ; i <= tempr; i++) {str[index++] = s[i];}return str;}
};

每日问题

什么是 C++ 中的多继承?它有哪些优缺点?

C++ 中的多继承

多继承(Multiple Inheritance)是指一个类(子类)可以继承自多个父类(基类)。在 C++ 中,类可以有多个父类,从而继承多个类的属性和行为。

语法示例

#include <iostream>
using namespace std;// 第一个基类
class Base1 {
public:void method1() {cout << "Method from Base1" << endl;}
};// 第二个基类
class Base2 {
public:void method2() {cout << "Method from Base2" << endl;}
};// 派生类
class Derived : public Base1, public Base2 {
public:void derivedMethod() {cout << "Method from Derived" << endl;}
};int main() {Derived d;d.method1();    // 从 Base1 继承的方法d.method2();    // 从 Base2 继承的方法d.derivedMethod();  // 自己的方法return 0;
}

输出:

Method from Base1
Method from Base2
Method from Derived

在这个示例中,Derived 类继承了 Base1 和 Base2 两个类,能够访问它们的方法。

多继承的优缺点

优点
代码复用:

多继承允许一个子类从多个基类继承行为和属性,从而实现代码的重用。可以将多个基类的功能组合在一个子类中,避免重复编写代码。

更加灵活的类设计:

通过多继承,C++ 提供了更大的灵活性,允许类组合多个功能而不需要通过组合(组合是一种设计模式,也能实现类似的功能)。这使得可以根据需要选择合适的基类来扩展子类的功能。

类功能的组合:

当某些类具有独立的功能时,可以通过多继承将这些功能组合到一个类中,创建更强大的新类。

模拟现实世界中的类关系:

在现实世界中,某个实体可能具有多种功能,C++ 的多继承机制可以模拟这种现象。例如,动物既可以是“哺乳动物”,也可以是“飞行物”,通过多继承可以很好地表示这种双重身份。

缺点
1.菱形继承问题(钻石问题):

最著名的缺点就是 菱形继承(Diamond Problem)。当多个基类继承自同一个父类时,子类将通过多个路径继承父类的同一成员,可能导致不明确或不一致的继承。此问题会导致数据冗余和二义性,且如果处理不当,可能引发不期望的行为。

示例:菱形继承问题

class A {
public:int value;
};class B : public A {
public:void methodB() {cout << "Method from B" << endl;}
};class C : public A {
public:void methodC() {cout << "Method from C" << endl;}
};class D : public B, public C {  // D 继承了 B 和 C
public:void methodD() {cout << "Method from D" << endl;}
};

D 类通过 B 和 C 继承了 A,但 D 可能会遇到访问 A 中成员 value 时的二义性问题,因为 B 和 C 都继承了 A,而且没有明确指定哪个 value 是 D 的成员。

解决方案:虚拟继承

使用 虚拟继承(virtual)来解决菱形继承问题,使得基类 A 的数据成员只被继承一次。

class A {
public:int value;
};class B : virtual public A {
public:void methodB() { cout << "Method from B" << endl; }
};class C : virtual public A {
public:void methodC() { cout << "Method from C" << endl; }
};class D : public B, public C {  // 使用虚拟继承
public:void methodD() { cout << "Method from D" << endl; }
};
2.增加复杂度:

多继承往往使得类的层次结构更加复杂,理解和维护起来更具挑战性。每个类的行为可能受到多个基类的影响,这使得类的功能可能更加难以预测。

3.命名冲突和二义性:

如果不同的基类定义了相同名称的成员(变量、函数等),则子类在访问这些成员时会发生二义性冲突,编译器会无法决定应该调用哪个基类的成员。为解决这个问题,C++ 允许使用作用域解析运算符(::)明确指定调用哪个基类的成员。

示例:命名冲突

class A {
public:void show() { cout << "A's show" << endl; }
};class B {
public:void show() { cout << "B's show" << endl; }
};class C : public A, public B {
public:void callShow() {A::show();  // 使用作用域解析指定调用 A 类的 showB::show();  // 使用作用域解析指定调用 B 类的 show}
};
4.难以管理的复杂接口:

多继承可能导致不同基类的接口混合在一个子类中,这会使得类的接口变得复杂。如果一个类需要继承多个不同功能的基类,那么它的接口可能会变得不清晰。

总结

优点:

        提高代码的重用性。

        提供更灵活的设计,可以模拟现实世界中多重身份的类关系。

        避免重复代码,允许类继承多个独立的功能。

缺点:

        菱形继承问题:可能导致二义性、数据冗余和难以维护的复杂性。

        需要谨慎管理命名冲突和接口的复杂性。

        增加了类的复杂性,使得代码理解和维护变得更加困难。

解决方案:

        使用 虚拟继承 来解决菱形继承问题。

        使用 作用域解析符 来解决命名冲突。

        在设计时,尽量避免过度使用多继承,或者结合其他设计模式(如组合、接口等)来管理复杂性。

什么是虚继承?为什么要使用虚继承?

虚继承 (Virtual Inheritance)

虚继承 是 C++ 中用于解决 菱形继承问题(即“钻石问题”)的一种技术。在 C++ 中,当多个类继承自同一个基类并且这些类再被子类继承时,可能会出现重复继承同一个基类的情况,这会导致 数据冗余 和 二义性。为了避免这个问题,C++ 引入了 虚继承 的概念。

虚继承的定义

虚继承的作用是确保一个基类只会被派生类继承一次。即使有多个类通过不同路径继承同一个基类,最终派生类只会拥有基类的一份成员。这样解决了菱形继承问题,避免了重复数据和二义性问题。

虚继承的语法

在 C++ 中,通过 virtual 关键字来声明虚继承。

class A {
public:int value;
};class B : virtual public A {
public:void methodB() {std::cout << "Method from B" << std::endl;}
};class C : virtual public A {
public:void methodC() {std::cout << "Method from C" << std::endl;}
};class D : public B, public C {
public:void methodD() {std::cout << "Method from D" << std::endl;}
};

在上面的代码中,B 和 C 都虚继承自 A,即使 D 同时继承了 B 和 C,它也只会有一份 A 的成员。

为什么要使用虚继承?

虚继承的主要作用是解决 菱形继承问题,具体包括以下几个方面:

1. 菱形继承问题(钻石问题)

假设有一个类 A,它有两个派生类 B 和 C,然后又有一个类 D 同时继承自 B 和 C,那么 D 类会出现问题:

数据冗余:D 会同时继承 B 和 C 中各自的 A 部分,这样会有两个 A 对象,浪费内存。

二义性:当 D 访问 A 的成员时,编译器不知道该访问 B 中的 A 还是 C 中的 A,从而产生二义性。

这种问题在多继承中很常见,尤其是当多个类继承了同一个基类时,派生类通过不同的路径重复继承了相同的成员。

菱形继承问题的示例:
class A {
public:int value;
};class B : public A {
public:void methodB() {std::cout << "Method from B" << std::endl;}
};class C : public A {
public:void methodC() {std::cout << "Method from C" << std::endl;}
};class D : public B, public C {
public:void methodD() {std::cout << "Method from D" << std::endl;}
};

在上面的代码中,D 类通过 B 和 C 继承了两个 A 类的副本。这样,D 会有两份 A 的成员变量 value,并且访问 A 时会产生二义性错误。

2. 虚继承解决菱形继承问题

通过 虚继承,C++ 可以保证当一个类通过多个路径继承同一个基类时,基类只有一份副本。这样既解决了 数据冗余 的问题,也避免了 二义性 问题。

虚继承解决方案:
class A {
public:int value;
};class B : virtual public A {
public:void methodB() {std::cout << "Method from B" << std::endl;}
};class C : virtual public A {
public:void methodC() {std::cout << "Method from C" << std::endl;}
};class D : public B, public C {
public:void methodD() {std::cout << "Method from D" << std::endl;}
};

解释:

B 和 C 都虚继承自 A,这意味着 D 继承 B 和 C 时,A 只会被继承一次。也就是说,D 只有一个 A 类的副本。

如果 D 访问 A 的成员时,编译器知道只有一个 A 成员,避免了二义性。

3. 虚继承的工作原理

虚继承是通过 虚基类 来实现的。在 C++ 中,虚继承的实现需要额外的内存管理来确保基类只有一份副本。编译器会插入指针来确保在多继承的情况下只存在一个虚基类的实例。

虚继承的内存管理:

虚继承通过引入 虚基类指针 来管理唯一的基类副本,确保无论通过哪个路径继承,基类的成员在派生类中只存在一份。

虚继承通常会带来额外的性能开销,因为每个类对象需要管理虚基类指针。

虚继承的优缺点

优点:

1.解决菱形继承问题:虚继承保证了基类的成员只被继承一次,避免了二义性和数据冗余。

2.内存优化:避免了重复继承相同的基类数据,减少了内存占用。

3.清晰的继承关系:对于多继承的情况,虚继承提供了一种清晰的机制来解决继承路径的冲突。

缺点:

1.复杂性增加:虚继承使得类的设计和理解更加复杂,特别是在类层次深且有多个虚继承时。

2.性能开销:虚继承引入了额外的指针和内存管理机制,会增加一定的性能开销。

3.构造函数调用顺序复杂:虚继承会影响构造函数的调用顺序,虚基类通常是最后被构造的,可能需要特别注意构造函数的顺序。

总结

虚继承 是 C++ 中解决 菱形继承问题 的一种机制,确保基类成员在多继承情况下只有一个副本,从而避免了数据冗余和二义性问题。

虚继承的使用可以提高类设计的灵活性,但也带来了内存开销和复杂性,需要小心设计和使用。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【算法】快速求出 n 最低位的 1

Leetcode 2438. 二的幂数组中查询范围内的乘积 先展示算法具体实现 while (n) {int lowbit n & (-n);powers.push_back(lowbit);n ^ lowbit; }这段代码的核心是通过 n & (-n) 计算出 n 的 最低位的 1&#xff08;即最右边的 1&#xff09; -n 是 n 的二进制补码表…

数据抽取平台pydatax使用案例---11个库项目使用

数据抽取平台pydatax&#xff0c;前期项目做过介绍&#xff1a; 1&#xff0c;数据抽取平台pydatax介绍--实现和项目使用 项目2&#xff1a; 客户有9个分公司&#xff0c;用的ERP有9套&#xff0c;有9个库&#xff0c;不同版本&#xff0c;抽取的同一个表字段长度有不一样&…

.NET9 - Swagger平替Scalar详解(四)

书接上回&#xff0c;上一章介绍了Swagger代替品Scalar&#xff0c;在使用中遇到不少问题&#xff0c;今天单独分享一下之前Swagger中常用的功能如何在Scalar中使用。 下面我们将围绕文档版本说明、接口分类、接口描述、参数描述、枚举类型、文件上传、JWT认证等方面详细讲解。…

shiny动态生成颜色选择器并将其用于绘图

在 Shiny 中使用 uiOutput 和 renderUI 动态生成 UI 控件是一种灵活的方法。结合 uiOutput(ns("colorSelectors")) 的用法&#xff0c;可以实现动态生成颜色选择器&#xff0c;并响应用户选择进行绘图或更新显示。 代码 library(shiny) library(colourpicker)# UI …

【单点知识】基于PyTorch进行模型部署

文章目录 0. 前言1. 模型导出1.1 TorchScript1.1.1 使用 torch.jit.trace1.1.2 使用 torch.jit.script 1.2 ONNX1.2.1 导出为 ONNX 格式 1.3 导出后的模型加载1.3.1 加载 TorchScript 模型1.3.2 加载 ONNX 模型 2. 模型优化2.1 模型量化2.2 模型剪枝 3. 服务化部署3.1 Flask 部…

‌Kotlin中的?.和!!主要区别

目录 1、?.和!!介绍 2、使用场景和最佳实践 3、代码示例和解释 1、?.和!!介绍 ‌Kotlin中的?.和!!主要区别在于它们对空指针的处理方式。‌ ‌?.&#xff08;安全调用操作符&#xff09;‌&#xff1a;当变量可能为null时&#xff0c;使用?.可以安全地调用其方法或属性…

java基础知识(常用类)

目录 一、包装类(Wrapper) (1)包装类与基本数据的转换 (2)包装类与String类型的转换 (3)Integer类和Character类常用的方法 二、String类 (1)String类介绍 1)String 对象用于保存字符串,也就是一组字符序列 2)字符串常量对象是用双引号括起的字符序列。例如:&quo…

《Hello YOLOv8从入门到精通》5,颈部网络(Neck)结构、核心源码和参数调优

YOLOv8的颈部网络&#xff08;Neck&#xff09;是目标检测模型中的关键组成部分&#xff0c;它位于骨干网络&#xff08;Backbone&#xff09;和头部网络&#xff08;Head&#xff09;之间&#xff0c;主要负责进行特征融合和增强。 在YOLOv8中&#xff0c;颈部网络采用了先进…

C#里怎么样实现单向链表?

C#里怎么样实现单向链表? 数据结构,是程序基本表示方法。 不同的数据结构,就需要采用不同的算法。 在软件开发中,使用到的链表还是比较多的。不过,目前C#语言,基本上都类库, 所以需要自己创建链表的机会,基本不存在了。 但是作为理解原理,还是学习一下吧。 下面的例…

Servlet细节

目录 1 Servlet 是否符合线程安全&#xff1f; 2 Servlet对象的创建时间&#xff1f; 3 Servlet 绑定url 的写法 3.1 一个Servlet 可以绑定多个url 3.2 在web.xml 配置文件中 url-pattern写法 1 Servlet 是否符合线程安全&#xff1f; 答案&#xff1a;不安全 判断一个线程…

对比三种UI交互界面的方案

在嵌入式系统的显示应用领域&#xff0c;如何高效、稳定地驱动TFT LCD显示屏至关重要。当下主流方案有三种&#xff1a; 单片机控制芯片屏 &#xff0c;常见的是瑞佑系列芯片单片机串口屏&#xff0c;常见迪文和大彩单片机内建LCD驱动&#xff0c;常见比如ST32F429等 这三种各…

w~视觉~3D~合集3

我自己的原文哦~ https://blog.51cto.com/whaosoft/12538137 #SIF3D 通过两种创新的注意力机制——三元意图感知注意力&#xff08;TIA&#xff09;和场景语义一致性感知注意力&#xff08;SCA&#xff09;——来识别场景中的显著点云&#xff0c;并辅助运动轨迹和姿态的预测…

fastjson不出网打法—BCEL链

前言 众所周知fastjson公开的就三条链&#xff0c;一个是TemplatesImpl链&#xff0c;但是要求太苛刻了&#xff0c;JNDI的话需要服务器出网才行&#xff0c;BCEL链就是专门应对不出网的情况。 实验环境 fastjson1.2.4 jdk8u91 dbcp 9.0.20 什么是BCEL BCEL的全名应该是…

GitLab使用操作v1.0

1.前置条件 Gitlab 项目地址&#xff1a;http://******/req Gitlab账户信息&#xff1a;例如 001/******自己的分支名称&#xff1a;例如 001-master&#xff08;注&#xff1a;master只有项目创建者有权限更新&#xff0c;我们只能更新自己分支&#xff0c;然后创建合并请求&…

MATLAB GUI设计(基础)

一、目的和要求 1、熟悉和掌握MATLAB GUI的基本控件的使用及属性设置。 2、熟悉和掌握通过GUIDE创建MATLAB GUI的方法。 3、熟悉和掌握MATLAB GUI的菜单、对话框及文件管理框的设计。 4、熟悉和掌握MATLAB GUI的M文件编写。 5、了解通过程序创建MATLAB GUI的方法。 二、内…

RabbitMQ简单应用

概念 RabbitMQ 是一种流行的开源消息代理&#xff08;Message Broker&#xff09;软件&#xff0c;它实现了高级消息队列协议&#xff08;AMQP - Advanced Message Queuing Protocol&#xff09;。RabbitMQ 通过高效的消息传递机制&#xff0c;主要应用于分布式系统中解耦应用…

第 36 章 - Go语言 服务网格

服务网格&#xff08;Service Mesh&#xff09;是一种管理服务间通信的方法&#xff0c;它允许开发人员对服务之间的交互进行抽象化处理。通过在基础设施层面上实现这一点&#xff0c;服务网格可以帮助解决微服务架构中常见的复杂性和挑战&#xff0c;比如服务发现、负载均衡、…

【es6】原生js在页面上画矩形及删除的实现方法

画一个矩形&#xff0c;可以选中高亮&#xff0c;删除自己效果的实现&#xff0c;后期会丰富下细节&#xff0c;拖动及拖动调整矩形大小 实现效果 代码实现 class Draw {constructor() {this.x 0this.y 0this.disX 0this.disY 0this.startX 0this.startY 0this.mouseDo…

【前端】JavaScript中的隐式声明及其不良影响分析

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: 前端 文章目录 &#x1f4af;前言&#x1f4af;什么是隐式声明&#xff1f;&#x1f4af;隐式声明的常见情景1. 赋值给未声明的变量2. 非严格模式下的隐式声明3. 函数中的变量漏掉声明4. for 循环中的隐式声明5. 使用…

2024小迪安全基础入门第七课

目录 一、抓包技术-Web&App&小程序&PC-扶墙双层 二、 抓包技术-Web&App&小程序&PC-项目联动 三、抓包技术-Web&App&小程序&PC-全局协议 一、抓包技术-Web&App&小程序&PC-扶墙双层 Wireshark&#xff1a; https://www.wir…