CGAL 5.6.1 - Algebraic Foundations

1. 引言

CGAL 的目标是精确计算非线性对象,特别是定义在代数曲线和曲面上的对象。因此,表示多项式、代数扩展和有限域的类型在相关的实现中扮演着更加重要的角色。为了跟上这些变化,我们引入了这个软件包。由于引入的框架必须特别支持多项式,因此本软件包避免使用数字类型这一术语。相反,软件包区分了类型的代数结构和类型是否可嵌入实数轴,简称实数可嵌入。此外,软件包还引入了可互操作类型的概念,允许明确处理混合操作。

2 代数结构

本节所介绍的代数结构概念来自传统代数中众所周知的对应概念,但我们也必须向现有的类型及其限制致敬。为了保持界面的最小化,我们不希望涵盖所有已知的代数结构,例如,我们没有引入群这样的基本结构概念,也没有引入倾斜域这样的特殊结构概念。

 Figure 1.1 Concept Hierarchy of Algebraic Structures

图 1.1 显示了代数结构概念的细化关系。IntegralDomain(积分域)、UniqueFactorizationDomain(唯一因式分解域)、EuclideanRing(欧几里得环)和 Field(场)对应于同名的代数结构。FieldWithSqrt、FieldWithKthRoot 和 FieldWithRootOf 是分别在 "sqrt"、"k-th root "和 "多项式实根 "运算下封闭的域。概念 IntegralDomainWithoutDivision 也对应于代数意义上的积分域,两者的区别在于某些积分域的实现缺乏(代数上总是定义明确的)积分除法。请注意,Field 精炼了 IntegralDomain。这是因为大多数环论概念,如最大公有除数,对 Field 来说都是微不足道的。因此,我们认为 Field 是对 IntegralDomain 的完善,而不是对更高级的环概念的完善。如果一种算法想要依赖 gcd 或余数计算,那么它就在试图做一些本来不应该在域中做的事情。

代数结构的主要属性收集在代数结构属性(Algebraic_structure_traits)类中。具体来说,每个具体模型 AS 所满足的(最精炼的)概念都编码在标签 Algebraic_structure_traits<AS>::Algebraic_category 中。代数结构至少是可赋值的、可复制构造的、可默认构造的和可等价比较的。此外,我们还要求代数结构可由 int 构建。为了使用方便,而且由于它们的语义足够标准,我们假定它们的存在,通常的算术运算符和比较运算符需要通过 C++ 运算符重载来实现。除法运算符保留给字段中的除法运算。所有其他一元函数(如 sqrt)和二元函数(如 gcd-求两个数的最大公约数、div)必须是众所周知的 STL 概念 AdaptableUnaryFunction 或 AdaptableBinaryFunction 概念的模型,并且是 traits 类的局部函数(如 Algebraic_structure_traits<AS>::Sqrt()(x) )。这种设计使我们能够从 STL 的所有部分及其编程风格中获益,并避免了使用重载函数的旧设计所遇到的名称查找和两次模板编译问题。不过,为了便于使用和向后兼容,所有功能都可以通过定义在 CGAL 命名空间中的全局函数来访问,例如 CGAL::sqrt(x) 。这可以通过函数模板使用 traits 类的相应函数来实现。有关概述,请参阅参考手册中的 "代数基础参考 "部分。

2.2 代数类别

对于 AS 类型,Algebraic_structure_traits<AS> 提供了几个标签。最重要的标签是 "代数类别"(Algebraic_category)标签,它表示 AS 类型满足的最精细的代数概念。该标签可以是:Integral_domain_without_division_tag、Integral_domain_tag、Field_tag、Field_with_sqrt_tag、Field_with_kth_root_tag、Field_with_root_of_tag、Unique_factorization_domain_tag、Euclidean_ring_tag,甚至是 Null_tag 中的一个,以防该类型不是代数结构概念的模型。这些标记相互派生,以反映代数结构概念的层次,例如,Field_with_sqrt_tag 从 Field_tag 派生。

2.3 精确和对数字敏感

此外,Algebraic_structure_traits<AS> 还提供了 Is_exact 和 Is_numerical_sensitive 这两个布尔标签。

如果代数结构概念所要求的所有运算都经过计算,且两个代数表达式的比较总是正确的,那么该代数结构就被认为是精确的。

如果代数结构的性能对算法的条件数敏感,则该代数结构被视为数值敏感结构。请注意,这两个概念其实是有区别的,例如,基本类型 int 并不是数值敏感型,而是由于溢出而被认为是不精确型。相反,leda_real 或 CORE::Expr 类型是精确的,但由于内部使用了多精度浮点运算,因此对数值问题很敏感。我们希望 Is_numerical_sensitive 用于算法的调度,而 Is_exact 则用于启用仅对精确类型进行检查的断言。

标签在调度不同实现时非常有用。下面的示例说明了使用重载函数对 Fields 进行调度。由于代数类别标记反映了代数结构层次,因此该示例只需要两个重载函数。

Algebraic_foundations/algebraic_structure_dispatch.cpp

#include <CGAL/IO/io.h>
#include <CGAL/Algebraic_structure_traits.h>
#include <CGAL/number_utils.h>
#include <CGAL/int.h>
template< typename NT > NT unit_part(const NT& x);
template< typename NT >
NT unit_part_(const NT& x, CGAL::Field_tag);
template< typename NT >
NT unit_part_(const NT& x, CGAL::Integral_domain_without_division_tag);
template< typename NT >
NT unit_part(const NT& x){// the unit part of 0 is defined as 1.if (x == 0 ) return NT(1);typedef CGAL::Algebraic_structure_traits<NT> AST;typedef typename AST::Algebraic_category Algebraic_category;return unit_part_(x,Algebraic_category());
}
template< typename NT >
NT unit_part_(const NT& x, CGAL::Integral_domain_without_division_tag){// For many other types the only units are just -1 and +1.return NT(int(CGAL::sign(x)));
}
template< typename NT >
NT unit_part_(const NT& x, CGAL::Field_tag){// For Fields every x != 0 is a unit.// Therefore, every x != 0 is its own unit part.return x;
}
int main(){// Function call for a model of EuclideanRing, i.e. int.std::cout<< "int:    unit_part(-3  ): " << unit_part(-3  ) << std::endl;// Function call for a model of FieldWithSqrt, i.e. doublestd::cout<< "double: unit_part(-3.0): " << unit_part(-3.0) << std::endl;return 0;
}
// Note that this is just an example
// This implementation for unit part won't work for some types, e.g.,
// types that are not RealEmbeddable or types representing structures that have
// more units than just -1 and +1. (e.g. MP_Float representing Z[1/2])
// From there Algebraic_structure_traits provides the functor Unit_part.
3 可嵌入的实数

大多数数字类型代表实数的某个子集。我们希望这些类型具有计算符号、绝对值或双近似值的功能。特别是,我们可以期望在这种类型上有一个反映沿实数轴顺序的阶。所有这些属性都集合在 RealEmbeddable 概念中。这个概念与代数结构概念是正交的,也就是说,一个类型可能只是 RealEmbeddable 的一个模型,因为这个类型可能只是表示实数轴上的值,而不提供任何算术运算。

至于代数结构,这一概念也是面向特质类的。与 RealEmbeddable 相关的主要功能都集中在 Real_embeddable_traits 类中。特别是,它提供了一个布尔标记 Is_real_embeddable,用于指示一个类型是否是 RealEmbeddable 的模型。比较运算符需要通过 C++ 运算符重载来实现。所有一元函数(如 sign、to_double)和二元函数(如 compare )都是 STL 概念 AdaptableUnaryFunction 和 AdaptableBinaryFunction 的模型,并且是 Real_embeddable_traits 的局部函数。

如果一个类型是 "整除域"(IntegralDomainWithoutDivision)和 "实数可嵌入"(RealEmbeddable)的模型,那么这个类型的对象所代表的数在算术和比较中是相同的。由此可见,该类型所代表的环是整数的超集和实数的子集,因此特征为零。

如果该类型是 Field 和 RealEmbeddable 的模型,那么它就是有理数的超集。

4 实数类型

 每个 CGAL 内核都有两个实数类型(可嵌入实数的数字类型)。其中一个是 FieldNumberType,另一个是 RingNumberType。基本内核对象(点、矢量等)的坐标来自这两种类型之一(笛卡尔内核为 FieldNumberType,齐次坐标内核为 RingNumberType)。

概念 FieldNumberType 结合了概念 Field 和 RealEmbeddable 的要求,而 RingNumberType 则结合了 IntegralDomainWithoutDivision 和 RealEmbeddable 的要求。从代数学角度看,实数类型并不形成独特的结构,因此未列入图 1.1 的概念层次结构中。

5 互操作性 

本节介绍类型互操作性的两个概念,即 ImplicitInteroperable 和 ExplicitInteroperable。虽然 ExplicitInteroperable 是基本概念,但我们还是从 ImplicitInteroperable 开始,因为它更直观。

一般来说,混合操作由重载操作符和函数提供,或仅通过隐式构造函数调用提供。ImplicitInteroperable 概念就反映了这种互操作性。然而,在模板代码中,混合运算的结果类型或所谓的强制类型可能并不明确。因此,软件包引入了 Coercion_traits,通过 Coercion_traits<A,B>::Type 访问两个互操作类型 A 和 B 的强制类型。

一些微不足道的例子是使用胁迫类型 double 的 int 和 double,或者使用胁迫类型 Gmpq 的 Gmpz 和 Gmpq。然而,胁迫类型并不一定是输入类型之一,例如,一个有理类型乘以整数系数的多项式的胁迫类型应该是一个有理系数的多项式。

Coercion_traits 还需要提供一个函数 Coercion_traits<A,B>::Cast(),用于将输入类型转换为强制类型。这实际上是更基本的概念 ExplicitInteroperable 的核心。引入 ExplicitInteroperable 是为了涵盖更复杂的情况,在这些情况下,很难或不可能保证隐式互操作性。请注意,这个函数对 ImplicitInteroperable 类型也很有用,因为它可以用来取消多余的类型转换。

如果两个类型 A 和 B 与强制类型 C 是 ExplicitInteroperable 的,那么对于由 C 的 Algebraic_structure_traits 和 Real_embeddable_traits 提供的所有二进制函数,它们都是有效的参数类型。

5.1 examples

The following example illustrates how two write code for ExplicitInteroperable types.

Algebraic_foundations/interoperable.cpp

#include <CGAL/Coercion_traits.h>
#include <CGAL/IO/io.h>
// this is an implementation for ExplicitInteroperable types
// the result type is determined via Coercion_traits<A,B>
template <typename A, typename B>
typename CGAL::Coercion_traits<A,B>::Type
binary_func(const A& a , const B& b){typedef CGAL::Coercion_traits<A,B> CT;// check for explicit interoperabilityCGAL_static_assertion((CT::Are_explicit_interoperable::value));// CT::Cast is used to to convert both types into the coercion typetypename CT::Cast cast;// all operations are performed in the coercion typereturn cast(a)*cast(b);
}
int main(){// Function call for the interoperable typesstd::cout<< binary_func(double(3), int(5)) << std::endl;// Note that Coercion_traits is symmetricstd::cout<< binary_func(int(3), double(5)) << std::endl;return 0;
}

 下面的示例说明了 ImplicitInteroperable 和 ExplicitInteroperable 类型的调度。二元运算函数(只是乘以两个参数)应该接受两个 ExplicitInteroperable 参数。对于 ImplicitInteroperable 类型,我们选择了一种避免显式转换的变体。

Algebraic_foundations/implicit_interoperable_dispatch.cpp

#include <CGAL/Coercion_traits.h>
#include <CGAL/Quotient.h>
#include <CGAL/Sqrt_extension.h>
#include <CGAL/IO/io.h>
// this is the implementation for ExplicitInteroperable types
template <typename A, typename B>
typename CGAL::Coercion_traits<A,B>::Type
binary_function_(const A& a , const B& b, CGAL::Tag_false){std::cout << "Call for ExplicitInteroperable types: " << std::endl;typedef CGAL::Coercion_traits<A,B> CT;typename CT::Cast cast;return cast(a)*cast(b);
}
// this is the implementation for ImplicitInteroperable types
template <typename A, typename B>
typename CGAL::Coercion_traits<A,B>::Type
binary_function_(const A& a , const B& b, CGAL::Tag_true){std::cout << "Call for ImpicitInteroperable types: " << std::endl;return a*b;
}
// this function selects the correct implementation
template <typename A, typename B>
typename CGAL::Coercion_traits<A,B>::Type
binary_func(const A& a , const B& b){typedef CGAL::Coercion_traits<A,B> CT;typedef typename CT::Are_implicit_interoperable Are_implicit_interoperable;return binary_function_(a,b,Are_implicit_interoperable());
}
int main(){CGAL::IO::set_pretty_mode(std::cout);// Function call for ImplicitInteroperable typesstd::cout<< binary_func(double(3), int(5)) << std::endl;// Function call for ExplicitInteroperable typesCGAL::Quotient<int>           rational(1,3);    // == 1/3CGAL::Sqrt_extension<int,int> extension(1,2,3); // == 1+2*sqrt(3)CGAL::Sqrt_extension<CGAL::Quotient<int>,int> result = binary_func(rational, extension);std::cout<< result << std::endl;return 0;
}
6 分数

除了需要对对象整体进行代数运算外,人们还希望将一些数字类型分解为分子和分母。这不仅适用于有理数(如 Quotient、Gmpq、mpq_class 或 leda_rational),也适用于复合对象(如 Sqrt_extension 或 Polynomial),它们可以分解为(标量)分母和具有更简单系数类型(如整数而非有理数)的复合分子。通常,对这些无分母倍数进行运算的速度会更快。如果类型是分数,相关功能以及分子和分母类型由 Fraction_traits 提供。特别是 Fraction_traits 提供了一个 Is_fraction 标签,可用于分派。

出于向后兼容的考虑,我们保留了一个相关的类 Rational_traits。不过,我们建议使用 Fraction_traits,因为它更通用,而且提供了分派功能。

The following example show a simple use of Fraction_traits:
File Algebraic_foundations/fraction_traits.cpp

#include <CGAL/Fraction_traits.h>
#include <CGAL/IO/io.h>
#ifdef CGAL_USE_GMP
#include <CGAL/Gmpz.h>
#include <CGAL/Gmpq.h>
int main(){typedef CGAL::Fraction_traits<CGAL::Gmpq> FT;typedef FT::Numerator_type Numerator_type;typedef FT::Denominator_type Denominator_type;CGAL_static_assertion((std::is_same<Numerator_type,CGAL::Gmpz>::value));CGAL_static_assertion((std::is_same<Denominator_type,CGAL::Gmpz>::value));Numerator_type numerator;Denominator_type denominator;CGAL::Gmpq fraction(4,5);FT::Decompose()(fraction,numerator,denominator);CGAL::IO::set_pretty_mode(std::cout);std::cout << "decompose fraction: "<< std::endl;std::cout << "fraction   : " << fraction << std::endl;std::cout << "numerator  : " << numerator<< std::endl;std::cout << "denominator: " << denominator << std::endl;std::cout << "re-compose fraction: "<< std::endl;fraction = FT::Compose()(numerator,denominator);std::cout << "fraction   : " << fraction << std::endl;
}
#else
int main(){ std::cout << "This examples needs GMP" << std::endl; }
#endif

下面的示例说明了一个向量(即多项式的系数向量)的积分。请注意,为了使系数增长最小化,Fraction_traits<Type>::Common_factor 被用来计算分母的最小公倍数。

File Algebraic_foundations/integralize.cpp

#include <CGAL/Fraction_traits.h>
#include <CGAL/IO/io.h>
#include <vector>
#include <CGAL/number_utils.h>
template <class Fraction>
std::vector<typename CGAL::Fraction_traits<Fraction>::Numerator_type >
integralize(const std::vector<Fraction>& vec,typename CGAL::Fraction_traits<Fraction>::Denominator_type& d
) {typedef CGAL::Fraction_traits<Fraction> FT;typedef typename FT::Numerator_type Numerator_type;typedef typename FT::Denominator_type Denominator_type;typename FT::Decompose decompose;std::vector<Numerator_type>   num(vec.size());std::vector<Denominator_type> den(vec.size());// decompose each coefficient into integral part and denominatorfor (unsigned int i = 0; i < vec.size(); i++) {decompose(vec[i], num[i], den[i]);}// compute 'least' common multiple of all denominator// We would like to use gcd, so let's think of Common_factor as gcd.typename FT::Common_factor        gcd;d = 1;for (unsigned int i = 0; i < vec.size(); i++) {d *= CGAL::integral_division(den[i], gcd(d, den[i]));}// expand each (numerator, denominator) pair to common denominatorfor (unsigned int i = 0; i < vec.size(); i++) {// For simplicity ImplicitInteroperability is expected in this examplenum[i] *= CGAL::integral_division(d, den[i]);}return num;
}
#ifdef CGAL_USE_GMP
#include <CGAL/Gmpz.h>
#include <CGAL/Gmpq.h>
int main(){std::vector<CGAL::Gmpq> vec(3);vec[0]=CGAL::Gmpq(1,4);vec[1]=CGAL::Gmpq(1,6);vec[2]=CGAL::Gmpq(1,10);std::cout<< "compute an integralized vector" << std::endl;std::cout<<"input vector:  ["<< vec[0] << "," << vec[1] << "," << vec[2] << "]" << std::endl;CGAL::Gmpz d;std::vector<CGAL::Gmpz> integral_vec = integralize(vec,d);std::cout<<"output vector: ["<< integral_vec[0] << ","<< integral_vec[1] << ","<< integral_vec[2] << "]" << std::endl;std::cout<<"denominator  : "<< d <<std::endl;
}
#else
int main(){ std::cout << "This examples needs GMP" << std::endl; }
#endif
7 设计和实现的历史

该软件包自 3.3 版起成为 CGAL 的一部分。当然,该软件包是以 CGAL 以前的 Number 类型支持为基础的。这要追溯到 Stefan Schirra 和 Andreas Fabri。但另一方面,该软件包在很大程度上受到了 Exacus [1] 中数字类型支持经验的影响,这主要可以追溯到 Lutz Kettner、Susan Hert、Arno Eigenwillig 和 Michael Hemmer。不过,该软件包抽象出了对嵌入实轴的数字类型的纯粹支持,从而也允许支持多项式、有限域和代数扩展。另请参见后续相关章节。

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

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

相关文章

docker常见命令

命令 说明 docker pull 拉取镜像 docker push 推送镜像到DockerRegistry docker images 查看本地镜像 docker rmi 删除本地镜像 docker run 创建并运行容器&#xff08;不能重复创建&#xff09; docker stop 停止指定容器 docker start 启动指定容器 docker r…

window环境下使用k8s部署.net core项目

前提&#xff1a;已经部署镜像到Docker 在项目发布目录下新建.yaml文件&#xff0c;内容如下&#xff08;以下仅举例出两种方式内容&#xff0c;可按需自由配置&#xff09; --方式一(创建deployment 、服务、指定命名空间) # ------------------- 注意层级结构&#xff0c;…

电脑远程桌面选项变成灰色没办法勾选怎么办?

有些人在使用Windows系统自带的远程桌面工具时&#xff0c;会发现系统属性远程桌面选项卡中勾选启用“允许远程连接到此计算机”。 导致此问题出现的原因主要是由于组策略或者注册表设置错误造成的。 修复远程桌面选项变灰的两种方法&#xff01; 方法一&#xff1a;设置本地组…

从spark streaming与structured streaming看spark core与spark sql的区别

导读 Spark中针对流式数据处理的方案有&#xff1a; Spark StreamingStructured Streaming 本文通过对比spark streaming与structured streaming&#xff0c;来深入理解spark core与spark sql的区别。 Spark Streaming 基于微批(DStream) Spark Streaming是基于微批(Micro batc…

1.【Labview白话系列】Labview数组精讲

题主经过写文章一段时间的发现&#xff0c;许多同学对该软件的理解和编程能力是不太一样的&#xff0c;有些知识相对一些同学较为简单&#xff0c;但是有些同学提问就比较困难。那么针对这个问题&#xff0c;题主打算出一期说白话系列的专栏&#xff0c;在该栏目中用最通俗的大…

pycharm手动安装常用插件

下载插件 &#xff08;1&#xff09;下载地址&#xff1a;JetBrains Marketplace 这里以语言包为例子 2、中文语言包 进入pycharm中的设置&#xff0c;点击plugins,选从磁盘中安装插件

六、矩阵问题

73、矩阵置零&#xff08;中等&#xff09; 题目描述 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,1,1]] 输出&#xff1a…

应用案例 | Softing echocollect e网关助力汽车零部件制造商构建企业数据库,提升生产效率和质量

为了提高生产质量和效率&#xff0c;某知名汽车零部件制造商采用了Softing echocollect e多协议数据采集网关——从机器和设备中获取相关数据&#xff0c;并直接将数据存储在中央SQL数据库系统中用于分析处理&#xff0c;从而实现了持续监控和生产过程的改进。 一 背景 该企业…

【国家机关办公建筑 大型公共建筑的能耗监测、集中统一管理】安科瑞能耗监测系统整体解决方案

背景 为全面推进大型公建节能管理工作&#xff0c;需建立大型公建节能监管体系&#xff0c;逐步建立起全国联网的大型公建能耗监测平台&#xff0c;在大型公建安装分项计量装置&#xff0c;通过远程传输等手段及时采集分析能耗数据&#xff0c;实现对大型公建的实时动态监测、汇…

Docker数据卷的挂载

目录 1 概念 2 常用命令 3 操作步骤(主要讲在创建容器时的挂载) 3.1 挂载在默认目录 3.2 挂载在自定义目录 4 附加内容(查看容器的挂载情况) 1 概念 数据卷&#xff08;volume&#xff09;是一个虚拟目录&#xff0c;是容器内目录与宿主机目录之间映射的桥梁。这样容器内…

微服务day05-Gateway网关

Gateway网关 为了防止微服务能被任何身份的人访问&#xff0c;需要对访问微服务的人做身份认证和权限校验。网关的功能就是对访问用户进行身份认证和权限校验。网关具有3种功能&#xff1a; 身份验证和权限校验&#xff1a;网关作为微服务入口&#xff0c;需要校验用户是是否…

git 如何将多个提交点合并为一个提交点 commit

文章目录 核心命令详细使用模式总结示例 核心命令 git merge branch2 是将分支branch2的提交点合并到本地当前分支。 而在执行这条命令的时候&#xff0c;加一个选项--squash就表示在合并的时候将多个提交点合并为一个提交点。 git merge --squash branch2 先看squash单词的意…

React Hooks 完全指南:无类组件革命

目录 ​编辑 前言 Hooks的前世 函数组件 类组件 状态和生命周期的管理 Hooks用途以及相应代码 状态管理 用于生命周期管理和副作用操作的 Hooks 用于上下文管理的 Hooks 其他用途的 Hooks 前言 React Hooks 是在 React 16.8 版本中引入的一个非常强大的新特性&…

建筑外窗遮阳系数测试的太阳光模拟器

太阳光模拟器是一种用于测试建筑外窗遮阳系数的高科技设备。它能够模拟太阳光照射房屋的情景&#xff0c;帮助建筑师和设计师更好地了解建筑外窗的遮阳性能&#xff0c;从而提高建筑的能源效率和舒适度。 这种模拟器的工作原理非常简单&#xff0c;它通过使用高亮度的光源和精…

scrapy 爬虫:多线程爬取去微博热搜排行榜数据信息,进入详情页面拿取第一条微博信息,保存到本地text文件、保存到excel

如果想要保存到excel中可以看我的这个爬虫 使用Scrapy 框架开启多进程爬取贝壳网数据保存到excel文件中&#xff0c;包括分页数据、详情页数据&#xff0c;新手保护期快来看&#xff01;&#xff01;仅供学习参考&#xff0c;别乱搞_爬取贝壳成交数据c端用户登录-CSDN博客 最终…

Bee Mobile组件库重磅升级

Bee Mobile组件库重磅升级&#xff01; 丰富强大的组件移动预览快速上手create-bee-mobile Bee Mobile组件库重磅升级&#xff01; Bee Mobile组件库最新 v1.0.0 版本&#xff0c;支持最新的 React v18。 主页&#xff1a;Bee Mobile 丰富强大的组件 一共拥有50多个组件&…

Java面向对象总结 ( 知识点 | 代码详解 )

类和对象 什么是类&#xff1f; ● 概念&#xff1a;具有相同特征&#xff08;同一类&#xff09;事物的抽象描述&#xff0c;如人类&#xff0c;车类&#xff0c;学生类等。 类的结构&#xff1a; ● 变量: 事物属性的描述(名词) ● 方法: 事物的行为&#xff08;可以做…

基于Flask的宠物领养系统的设计与实现

基于Flask的宠物领养系统的设计与实现 涉及技术&#xff1a;python3.10flaskmysql8.0 系统分为普通用户和管理员两种角色&#xff0c;普通用户可以浏览搜索宠物&#xff0c;申请领养宠物&#xff1b;管理员可以分布宠物信息&#xff0c;管理系统等。 采用ORM模型创建数据&am…

QT----云服务器部署Mysql,Navicat连接1698 -Access denied for user ‘root‘@‘‘

阿里云有活动&#xff0c;白嫖了一年的新加坡轻量级服务器&#xff0c;有点卡&#xff0c;有时候要开梯子 白嫖300元优惠券 目录 1 安装启动Mysql服务2 更改连接权限2.1 Navicat连接报错1698 -Access denied for user root 3 qt连接云服务器数据库 1 安装启动Mysql服务 我使用…

f5——>字符串三角

暴力破解&#xff0c;双层循环&#xff0c;注意复制到新列表用append&#xff0c;这样更不容易出错 格式还是“”.join(str)