Tag: 编程

堆数据结构实现— Swift 4

动机 这篇文章旨在帮助您了解堆数据结构并在Swift中实现它。 在进入实现部分之前,必须先具备swift和heap知识。 什么是堆 堆是一种完整的二叉树的特殊类型,它的父节点与其子节点进行比较,从而为您提供数据结构中的最大值或最小值。 通常有两种类型。 最大堆:在最大堆中,父节点将始终大于其子节点。 所有其他节点可以按任何顺序排列 最小堆:在最小堆中,父节点将始终小于其子节点。 所有其他节点可以按任何顺序排列 。 注意: 当您只关心最小值或最大值时,堆数据结构很有用。 所有其他值将是无序且无排序的。 优先级队列是可以使用堆数据结构的典型示例。 实作 现在,我们将实现具有所有功能的最小堆。 实现需要执行以下步骤: 1.向堆添加值 2.从堆中删除最少的元素 3.从堆中获取最少的元素 我们开工吧。 创建堆类 堆可以用数组表示。 一个父节点可以有一个左子节点和一个右子节点。 我们可以通过以下方式获取正确的Child的索引和离开的孩子的索引 左儿童索引= 2 *父索引+1 右子索引= 2 *父索引+2 用同样的方式 ParentIndex =(childIndex-1)/ 2 在堆类中实现所需的方法 将这些方法添加到堆类中。 现在,我们将添加在Heap上执行自定义操作的方法。 添加这些方法 peek()返回堆中的最小元素 poll()与peek一样,但是它也删除了最小元素 add()将元素添加到堆中 removeMin()删除堆中的最小元素 现在您一定在想,什么是heapifyDown()和heapifyUp() 让我们实现它们 堆砌 这是在将元素添加到列表之后发生的过程。 因此,如果要在堆中添加元素,只需将其添加到最后一个元素,然后开始与父元素进行比较,直到堆满足条件为止 HeapifyDown 当您删除列表中的最小元素并且堆必须重新排列自身以满足条件时,就会发生此过程。 对于父节点,它将检查子节点是否小于父节点(如果是),然后交换该值。 它一直持续到堆满足其先决条件为止。 让我们添加printMethod来打印堆 让我们使用这些方法来处理堆。 […]

MapKit JS入门

苹果在WWDC 2018上宣布了MapKit JS,使开发人员能够在浏览器中显示Apple地图。 这意味着您可以将与您在iOS设备上熟悉的丰富程度和交互性相提并论的浏览器。 在这篇文章中,我将解释如何开始使用MapKit JS以及如何在Web应用程序中显示Apple地图。 获取MapKit JS密钥 在开始实施应用程序之前,您需要请求并获取MapKit JS密钥。 这可以在Apple Developer Portal上完成。 单击“ 证书,标识符和配置文件 ”,然后选择地图ID,如以下屏幕截图所示: 使用右上角的添加按钮创建一个新的地图ID,如下所示: 创建地图ID后,下一步就是为该地图ID生成密钥。 如下面的屏幕截图所示,这是在键页面上完成的: 为您的地图ID创建一个密钥,然后下载密钥。 请勿松开钥匙,否则将无法找回钥匙。 再次不要松开钥匙。 注册MapKit JS密钥就差不多了。 在下一节中,我将介绍如何开始在网页上显示地图。 实施节点服务器 Apple提供了两种在网页上显示地图的方式。 我们将研究推荐的方法,该方法还包括在我们的服务器上生成令牌,该令牌随后由Apple进行验证。 如果您对自己生成令牌不感兴趣,那么可以使用这个令人惊叹的网站MapKit JS Helper,只要您输入所有必要的详细信息,它将为您生成令牌。 令牌由标头和有效负载结构组成,如下所示: 您还可以在此处阅读有关规格的更多信息。 如前所述,要使其正常工作,我们将需要实现和配置服务器。 我们的第一个任务是创建一个端点,该端点将向我们返回所需的令牌。 下面的代码在“ / services / jwt ”处创建一个端点,该端点负责创建令牌。 确保从Apple Developer网站下载的私钥是节点项目的一部分。 我们将需要该密钥来对令牌进行签名,如下面的实现所示。 为了对令牌进行签名,我们使用了NPM包“ jsonwebtoken”。 令牌签名后,我们将其作为JSON响应的一部分返回。 甜! 下一步是使用令牌来验证我们对MapKit JS的请求。 显示地图 Apple提供了一些示例,可用于显示和自定义地图的外观。 我们将显示地图,并在地图上添加注释以指向特定的兴趣点。 这是完整的HTML和JavaScript代码。 下载代码 […]

在Swift中实现编程语言—第4部分:解析器

这是“用Swift编写编程语言”教程系列的第四部分。请务必查看 第3部分 。 语言解析被广泛认为是只有经验丰富的程序员才能做的事情。 这是几乎在任何领域都常见的误解。 当然,作为Swift等广泛使用的语言的核心贡献者,意味着您必须在该主题上拥有丰富的经验。 但这适用于每种类型的编程,并且不应使我们害怕创建自己的解析器。 什么是解析器? 解析器的主要目标是将Lexer生成的令牌列表转换成我们语言语法的数据结构,通常,这种“数据结构”是类似树的结构,例如“抽象语法树”。 像计算机科学中的所有内容一样,最好使用Wikipedia(:)来定义这种树。 抽象语法树是用编程语言编写的源代码抽象句法结构的树表示。 哇,这是很多定义不正确的概念。 让我们分解一下: 摘要—事实证明,我们并不关心解析器收到的所有令牌。 考虑表达式2 * (2 + 3) ,这里的树实际上不需要关于左括号和右括号的信息。 只是在其中表达的优先级。 括号已被抽象出来。 语法结构—用Swift的术语来说,这通常意味着任何表示struct , enum或class struct ,它们表示源代码如何以我们的语言语法形成。 自顶向下解析 实现解析器的方法有很多,但是我们今天要看的是自上而下的解析。 在自上而下的解析中,在继续进行更详细的部分之前,将生成语法语法树的最高级别的结构。 通常认为它比同等技术(自下而上)要慢一些,但更容易掌握,因此非常适合本教程。 递归体面解析 自上而下解析的一种非常流行的方法称为递归体面解析。 这种流行并不是巧合,因为它们最容易实现。 正如您可能假设的那样,这种简单性需要付出一定的代价,而您将是对的,因为它们也是性能最低的。 但是我们还是会选择递归体面的方法,以使本教程尽可能简单。 实作 对于我们的解析器,让我们从简单的类定义开始: 类解析器{ 让令牌:[令牌] var index = 0 init(令牌:[令牌]){ self.tokens =代币 } } 在全面实施之前,有必要回顾一下我们的语法: E⇒ | | () 运算符⇒ […]

Swift 4中的桥接模式

桥接模式将抽象与其实现分离开来,以便两者可以独立变化。 当我第一次学到这个时,桥接模式使我非常高兴。 当您不知道确切的业务逻辑要实现时,但是由于项目的截止日期而需要丰富抽象时,它确实可以为您提供帮助。 当业务逻辑来自客户需求时,仅需对业务逻辑进行编码。 类型:结构图案 也称为:手柄/主体 结构体: 参加者: 抽象:定义抽象的接口。 维护对类型为Implementor的对象的引用。 RefinedAbstraction:扩展Abstraction定义的接口。 实现者:定义实现类的接口。 该接口不必与Abstraction的接口完全对应。 实际上,这两个接口可以完全不同。 通常,Implementor接口仅提供原语操作,而Abstraction基于这些原语定义更高级别的操作。 ConcreteImplementor:实现Implementor接口并定义其具体实现。 Swift 4实现: 让我们考虑客户的要求是绘制Circle和Rectangle,但是我们仍然不知道如何实现实际绘制这些图形的代码。 在实际情况下,可能由于缺乏几何知识或我们选择绘制哪个数字的第三方图书馆而发生。 那些不知道桥接模式的人将等到完成实际的图形实现后,这可能会延迟开发。 如果在这种情况下遵循Bridge Pattern ,则无需等待实现细节,只需创建我们的抽象类并在整个项目中使用该类即可。 一切都会清楚,让我们继续前进。 抽象基础类。 实施此基类,我们可以扩展抽象并制作将在项目其他部分中使用的具体类。 在下面的示例中, Shape是基础抽象类,而Circle和Rectangle是我们抽象的具体类。 注意draw()方法,实际上该图不是绘制而是与该类的其他类调用方法链接在一起的。 在这里, GraphicsAPI是称为“实现者”的类。 抽象类调用实现者类的方法,这是Bridge模式的关键部分。 在上面的代码中,编写了所有抽象类。 现在,需要根据业务逻辑/实现选择来实现实现者类。 桥接模式的用法精彩。 桥接模式适合于实现的运行时绑定。 根据我们的示例,您可能会注意到我们有2个具体的实现类。 您可以在运行时选择任何一个。 例如,您可以在运行时使用DirectXAPI / OpenGLAPI绘制“圆形”和“矩形”。 在此处找到完整的源代码:Github

在MacOS和Linux上使用ImageMagick,Vapor 3和Swift对照片加水印

回顾过去(您还记得Web 2.0吗?😉),我过去经常围绕照片进行编程。 在格式之间调整大小,缩放,旋转和转换。 最近,我不得不创建一个Web服务,该服务使用Vapor生成带水印的图像。 事实证明,还没有太多用于图像处理的库,因此这个简单的任务成为研究中一个有趣的问题。 有两个主要的图像处理库:GD和ImageMagick。 ImageMagick有点像高级库,所以我决定首先使用它。 ImageMagick有一个有趣的Swift包装器,称为MagickWand。 不幸的是,它根本不支持文本操作,因此我不得不更深入地研究。 我找不到任何有用的东西,所以我想:“为什么不在Swift中只使用一些ImageMagick C函数呢?”事实证明,这很容易做到! 安装ImageMagick 在ImageMagick网站的开发部分中,您可以找到MagickWand和MagickCore的文档。 这些是用C编写的用于与ImageMagick处理库进行交互的接口。 将其包装到Swift包中非常容易,但是首先让我们安装ImageMagick。 让我们从macOS开始。 您可以自己编译ImageMagick,但对于macOS,仅使用Homebrew会更容易。 ➜brew安装imagemagick @ 6 如果未指定@6 ,则默认情况下将安装最新版本。 我在Linux上的版本7遇到问题,因此我决定将macOS和Linux都使用旧版本。 安装后,您会注意到自制软件未创建符号链接(有关以下信息:仅桶依赖项)。 为了获得有关ImageMagick所需的信息,此部分很重要: 为了使pkg-config查找[受电子邮件保护],您可能需要设置: 导出PKG_CONFIG_PATH =“ / usr / local / opt / imagemagick @ 6 / lib / pkgconfig” 您可以只在终端中在每个pkg-config命令之前添加PKG_CONFIG_PATH ,但是如果使用zsh只需运行,则永久添加它更容易: ➜echo’export PKG_CONFIG_PATH =“ / usr / local / opt / imagemagick […]

我如何成为iOS和网站开发人员

您也可以开始,是什么使您退缩? 欢迎到我的博客! 您可以叫我Lz,我是一个iOS和网站开发人员,他在美国工作,从事Java,Python,Web开发(HTML,CSS和Javascript)和Swift的编程已有3年多了! 通过电子邮件或instagram消息问我的第一个问题是: “如何启动iOS或网站开发?” 问题到了重复和令人讨厌的地步,所以我决定写这个问题。 所以请系好安全带,因为我将向您展示我的故事以及我如何到达今天的位置! 中学 我的故事始于高中(2015年末),当时我选择上计算机科学课。 当时这是一个随机决定,我没有编程知识,也不知道它将带我去哪里。 我们在第一周的首要任务是了解什么是编程及其工作原理。 每个人都被指示要使用Scratch(一种基于块的可视化编程语言)创建任何东西,并使其独一无二。 我创建了一个冰球运动员(一个jpeg图像),他可以根据按键向前或向后移动,最终,如果他向前移动足够长,他会向冰球网射击并得分。 这个项目使我开始爱上编程,因为我能够将自己选择的所有内容放在一起,并创建了一个我的独特作品。 第一周之后,课程将重点放在Java(一种面向对象的语言)上,并将深入探讨对象,方法和类。 我不再觉得自己好像在上学,要时间,而是每天都在经历一个新的自我成长的机会。 课程结束后,我在业余时间构建了小型应用程序,然后开始进行网站开发。 涉足网站开发 大约一年后(2017年初),我开始学习HTML(超文本标记语言)和CSS(级联样式表)。 当时我下载了一个应用程序(SoloLearn),并深入研究了网站的创建方式。 这不是一个好的设计时期,因为我创建的每个网站看起来都很糟糕。 花了几个月的时间来习惯标签和样式。 我不擅长了解如何设置样式和创建某些表格来更改整个网站的标签。 在进入任何代码之前,花了一段时间才将Web开发的思想付诸实践。 一直以来,我从来没有看过什么,也没有独自练习。 许多人认为您可以看着某人做某事,并且您可以在第一次尝试时轻松地做到这一点,而无需再尝试。 这只会使您到目前为止,您将不得不反复参考源。 iOS开发的新手 在2018年中,我为自己购买了MacBook Pro 13”。 我很喜欢iOS应用程序的制作方式,因此我找到了有关Udemy的免费课程,然后跳入了iOS开发。 从一开始我就爱上了Swift,这是一种简单而有趣的语言。 极限似乎无穷无尽。 从课程中构建了一个小型点击游戏之后,我继续为本地企业构建了一个应用程序(不是大型应用程序)。 那里没有完美的地方,并且有大量的错误(这是我的第一个应用程序)。 它于2018年8月中旬推出,具有强大的保留率和用户参与度,这非常令人兴奋和惊奇! 在开发该公司应用程序期间,我决定自己为自己构建一个应用程序。 我从生产力的角度出发,想要构建一个将任务提升到不同水平的应用程序。 想法是,用户会根据每个任务的完成/未命中获得分数。 从2018年9月开始,我开始设计自己的想法。 一开始它是一个快速而小型的应用程序,它专注于用户创建任务,查看他们的分数并拥有一个全球排名委员会来与朋友竞争! 设计,开发和发布Habite花费了将近两个月的时间, Habite于2018年10月24日发布。用户参与度从一开始就飞涨,令人难以置信的是,看到实际的人使用我制造的产品。 习惯将于2019年2月24日开始四个月,与以前完全不同。 现在,它具有白色界面,包含一个高级版本,其中包括每日计划,检查清单,注释和目标,并且每天都在不断增长! 如何开始 我见过很多人想尝试新事物,却花最少的精力。 对于Web或iOS开发,这并不会减少它。 您需要能够编写大量代码,分解并修复错误,并尽可能多地练习。 Udemy是令人难以置信的起点。 他们提供免费和付费课程,几乎可以教授您所有内容。 Teamtreehouse是另一个很好的学习资源。 我没有研究它,但是我听说过很棒的事情! 网络上有更多课程和资源,包括Youtube。 […]

闪电阅读之二:可选的字符串陷阱

前几天,我试图建立一个URL。 检查以下代码块: 初始化?(userId: String? ){ 后卫userId!= nil else {return nil} self.path =“ / user / \(userId)” self.url.appendPathComponent(self.path) } 看起来合法吧? 假设我们将23940作为userId传递给此初始化程序。 根据Swift版本,路径值为: Swift 2.x路径=“ / user / 23940” Swift 3.x路径=“ / user / Optional(” 23940“)” Swift 4.x路径=“ / user / Optional(” 23940“)” 微妙,但令人心碎。 首先,如果您正在处理由于某种原因仍使用Swift 2.x的超老项目,并计划进行迁移,请提防此问题。 其次,我们可以在此处使用Guard-let代替Guard-check语句来解决此问题。 但是,到处都有保护语句并不方便,尤其是当您只想打印内容时。 我创建了以下结构来克服此问题: 公共结构Printable :CustomStringConvertible { 公众让价值:T? public init(_ value:T?){ self.value […]

使用Swift以编程方式布局视图的另一种方法

开始学习Swift时,我对自动布局系统感到困惑。 无论是使用情节提要还是程序限制,它都不适合我。 一些约束在运行时会干扰其他约束,而对所有不同的冲突约束进行分类变得令人沮丧。 我承认在Xcode中使用自动布局功能非常强大,但我相信,除了自动解决方案的替代方法会增加计算成本之外,还会增加其他复杂性。 请注意,在我的标题中,我并不是说这是一种布局视图的“更好”方法,只是一种可以促进进一步实验的不同方法 我觉得有一种更简洁,更省钱的布局视图方式,因此我开始着手开发一个名为View Layout的小型项目。 它只是UIView的扩展,您在其中实例化一个结构(ViewLayout),该结构为您计算视图的位置。 您可能会做的所有数学运算都可以使用CGRect和框架布局视图? 所有这些都封装在“视图布局”结构中。 它使用ViewPosition枚举来确定视图相对于“引导视图”的位置。 我不会尝试描述它,而是显示代码。 这是ViewLayout的初始化,包括分解和解释的步骤。 //您要放置的视图的不同位置选择 枚举ViewPosition { 案例底部中心 案例底部左 案例底部右 案例中心 案例顶部左 案例顶部右 案例中心 剩下的情况 案例权 } //通常除非要以根视图为指导进行布局,否则通常要使用withFrame init init(withFrame ofView:UIView,position:ViewPosition,size:CGSize,padding:(CGFloat,CGFloat)){ self.guide = ofView.frame // 1 self.position =位置// 2 self.size =大小// 3 self.padding =填充// 4 } 1:我设置ViewLayout对象在计算其原点时使用的框架 2:我将框架的位置与指南进行了比较 3:我设置要在ViewLayout中创建的框架的大小 4:我使用元组设置视图的水平和垂直填充。 第一项(padding.0)控制垂直填充,正数增加原点的Y坐标,负数减少原点的Y。第二个数与水平填充相同,正数增加X坐标,负数减少了它。 现在,调用此初始化程序后,您将获得一个ViewLayout对象! 不过您还不能使用它。 您只是获得一个自动配置的框架以供视图使用而已,而仅仅是一个函数调用! 您所要做的就是调用以下功能之一: //不要忘记在实例化结束时调用它! […]

Desarrollar para CocoaPods

不要重复自己。 从iOS上的Desarrollador到seguro es que到lguna vez hayas usado CocoaPods。 Tambiénes muy posible que hay hays preguntado como funciona y como se subencódigosahí。 1. Empezamos el proyecto Primero vamos是一个无代码保护的通用代码,它还可以控制ARControls。 可以通过UIButton和quedarasí的快捷方式查看crero dentro del proyecto: 4. Git Git不能继续播放任何影片。 可以在GitLab存储库中下载自己的Github GitHub。 可能会在存储库中找到最后的名词。 进行中:https://gitlab.com/ArkitectureRepository/ARControls.git 5. Podspec El Podspec es el fichero que us CocoaPods para coger las propiedades que nosotros le […]

在Swift 4中循环

几周前,我开始学习Swift,并从JavaScript中学到了一些东西,对此我总是感到困惑。 我不知不觉间断地将一些模式从JS转移到Swift,JS中的for循环就是其中之一。 如果您了解JS,则可以将其视为编写循环的方式 for(让i = 0; i <= 5; i ++){ … } 好吧,这不是用Swift编写循环的方式。 抱歉 通过学习,我已经能够设计出3种在Swift中用于循环的方法。 1.遍历数组 如果要遍历数组,这就是使用Swift可以完成此操作的方式。 让名字= [“安娜”,“山姆”,“史密斯”] 以名称命名{ … } 上面的代码片段遍历了names数组,并将数组中的每个项目分配给变量name并允许您在块中使用它。 2.循环字典 字典是键值对的无序集合。 [“spider”: 8, “ant”: 6, “cat”: 4]是一本字典,其键为spider,ant,cat和值8、6和4 遍历字典就像这样简单: 让numberOfLegs = [“ spider”:8,“ ant”:6,“ cat”:4] 在numberOfLegs中用于(animalName,legCount){ // animalName:蜘蛛 // legCount:8 // …. } 想象一下需要将数组中的所有值加起来的情况,这是一种简单的方法。 3.用数字范围循环 有时,您需要一个普通的for循环,例如JS片段。 在Swift中,使用数字范围很容易实现。 用于1 … 5中的索引{ … […]