精华内容
下载资源
问答
  • 【创新设计】(广东专用)2015高考英语 大二轮总复习测试 阅读理解专题 专题五 瞻前顾后 妙选信息匹配
  • 2015年高考英语二轮名校精讲精练讲义 专题 阅读理解(2014新题)赏析(信息匹配题;概括主题题)
  • 陕西省2013年高考英语二轮复习 专题升级训练卷十六 史地、自然、科普、新闻类阅读理解、信息匹配(一)
  • 陕西省2013年高考英语二轮复习 专题升级训练卷十七 史地、自然、科普、新闻类阅读理解、信息匹配(二)
  • 论文阅读-文本匹配(一) 孪生LSTM

    千次阅读 2017-12-11 18:26:53
    信息检索(IR)等其他应用场景可设置不一样(untied weights)。 2.度量方式使用基于 曼哈顿距离d的dis=e^(-d) ,由于得分在1-5,因此做了 dis*4.0+1.0 的处理。简单的度量方式,让句子表示更好地表达复杂的语义...

    版权声明:本文为博主原创文章,未经博主允许不得转载。禁止抄袭。

    由于作者资历尚浅,有理解错误的地方欢迎大家指正和交流。


    论文简介

    论文题目: Siamese Recurrent Architectures for Learning Sentence Similarity

    论文地址:https://www.aaai.org/ocs/index.php/AAAI/AAAI16/paper/view/12195/12023

    作者:Jonas Mueller,Aditya Thyagarajan

    作者单位:Massachusetts Institute of Technology(MIT CSAIL)、M. S. Ramaiah Institute of Technology(印度 MSRIT)

    出版单位:the Association for the Advance of Artificial Intelligence(AAAI

    发表时间:2016.2


    模型图



    贡献点:

    1.提出新的度量方式(基于曼哈顿距离,见细节2)。优于欧几里得距离(梯度消失)、余弦相似度。【回归

    2.通过明确的指导(距离),使用简单LSTM能够建模复杂的语义。

    3.使用MaLSTM features输入给SVM来进行分类。【分类


    实验数据:

    1.The SICK data set (10k条): http://clic.cimec.unitn.it/composes/sick.html

    - sentence_A: sentence A
    - sentence_B: sentence B
    - entailment_label: textual entailment gold label (NEUTRAL, ENTAILMENT, or CONTRADICTION)
    - relatedness_score: semantic relatedness gold score (on a 1-5 continuous scale)

    1.1 回归问题,得分在1-5

    1.2 分类问题,三类【entailment, contradiction, or neutral】


    细节:

    1.LSTM(a)和LSTM(b)权重设置一样(tied weights、主题一样)。在信息检索(IR)等其他应用场景可设置不一样(untied weights)。

    2.度量方式使用基于曼哈顿距离d的dis=e^(-d),由于得分在1-5,因此做了dis*4.0+1.0的处理。简单的度量方式,让句子表示更好地表达复杂的语义关系。

    3.LOSS函数使用MSE。训练使用BPTT。

    4.词向量预训练(实验数据只有10k条),利用同义词扩充来数据增强

    5.input维度(300维)、hidden维度(50维)





    展开全文
  • 动态规划 立体匹配 半全局立体匹配

    热门讨论 2015-06-14 20:48:54
    根据论文Accurate and Efficient Stereo Processing by Semi-Global Matching and Mutual Information写的双目立体匹配代码,matlab编写方便阅读,带测试图片,注意算法只实现了4个方向,即左右,右左,上下,下上四...
  • scala大量使用模式匹配(match case)Scala的模式匹配,与Java的switch case的区别:1.不仅可以匹配值,可以匹配类型2.可以匹配数组的集合 相同数组、长度相同的数组、以某个元素开头的数组 对于长度相同的数组,...

    java switch-case(对值)
    scala不仅对值,而且可以对类型,集合(map,list元数据匹配),object,class
    scala大量使用模式匹配(match case)

    Scala的模式匹配,与Java的switch case的区别

    1.不仅可以匹配值,可以匹配类型

    2.可以匹配数组的集合
    相同数组、长度相同的数组、以某个元素开头的数组
    对于长度相同的数组,会进行自动变量赋值

    3.匹配class - 样例类case class
    类似于Java里的Bean
    一般都不可改变,默认只有getter
    可用于消息通信
    基类传参数,用match匹配不同的子类去接收和处理
    Some()和None(),在模式匹配时表示匹配到和匹配不到
    case class 和 case object区别前者会生成多个实例,后者只有一个实例,就是它本身

    data输入数据,是一个String
    下划线表示既不是spark也不是hadoop
    简单示例
    这里写图片描述

    类似于switch case语句
    下划线代表默认情况
    可以在默认下用if进行分支判断

    def bigData(data: String, age: Int){
    data match{
    case "Spark" => println("Wow!!") 
    case "Hadoop" => println("OK!!")
    case data_ if(age>18) => println("adult")
    case _ => println("nothing")
    }
    }

    传入两个参数
    这里写图片描述
    传入两个参数改写
    这里写图片描述

    match外的变量,可以自动传给match里的变量
    data赋值给data_

    def bigData(data : String){
       data match{
        case "Spark" => println("wow")
        case "Hadoop" => println("ok")
        case data_ if data_ == "Flink" => println("cool"+data_)
        case _ => println("something else")
       }
    }

    输出结果
    输出结果

    类型匹配
    异常类型进行匹配,第一种类型匹配,匹配FileNotFound,Exception本身打印出来,包括完整的包名,类名,后面是填入的信息oops

    import java.io._
    def exception(e :Exception){
    e match{
    case fileException : FileNotFoundException => println("File Not Found:"+fileException)
    case _: Exception => println("Exception getting thread dump from $executorId",e)
    }
    }

    这里写图片描述

    集合匹配
    数组,数组中指定的元素,指定个数的元素的数组,以及数组以某元素开头的数组,Set,list一致的
    Array的模式匹配
    传入三个元素,分别赋值给spark,hadoop,flink(它们是三个变量)

    def data(array:Array[String])
    {
    array match{
    case Array("Scala") => println("Scala")
    case Array(spark,hadoop,flink) => println(spark+" : "+hadoop+" : "+flink)
    case Array("Spark", _*) => println("Spark ...")//以Spark开头
    case _ => println("Unknown")
    }

    这里写图片描述

    类匹配
    case class 相当于java中javabean 默认是val类型 只有getter方法 ,通过case class可以进行类的模式匹配

    def sayHi(person:Person){
    person match{
          case Student(name,score) => println("I am a studnet:"+name+score)
          case Worker(name,salary) => println("I am a worker:"+name+salary)
          case _ =>println("Unknow")
         }
         }

    自动匹配到worker(worker,student是person的子类)
    这里写图片描述

    case class 生成多个实例
    case object 只有一个实例

    泛型函数

    class Person[T](val content : T){
    def getContent(id : T) = id + " _ " + content  
    }
    
    val p = new Person[String]("Spark")
    p.getContent("Scala")//必须为String 类型

    这里写图片描述

    类型体系

    泛型类、泛型函数、类型界定(upperBound)、视图界定(View Bounds)、协变和逆变等

    类型参数,主要用于类型限定,加强代码的健壮性

    1.泛型类和泛型函数

    2.类型界定

    对类型也可以限定边界,upperBounds(<:表示,上边界,是它或它的子类),(>:表示,下边界,是某个类的父类或类本身)

    3.视图界定

    视图界定(View Bounds)
    View Bounds隐式转换
    对类型进行implicit隐式转换

    implict  def rddToSequendeFileRDDFuncions[K <% Wirtable:ClassTag,V <% Writable:ClassTag]

    类型[T],在上下文中注入隐式值,而且注入的过程是自动的

    class Compare[T :ordering](val n1:T,val n2:T){
    def bigger(implicit ordered :Ordering[T])=
    }

    Manifest->ClassTag
    T:ClassTag,T是泛型,运行时有更完善的类型匹配,反射获取类型的信息

    展开全文
  • 上面的代码结构很清晰,阅读起来也相当简单,对复杂情况的封装也很好。 就是这样,我们已经成功滴实现了我们的交易引擎。然而,这个解决方案还是有点繁琐;我们在想是否还有对其进行改进的模式匹配方案。所以,让...

    怒戳查看最终稿@SwiftGG

    在众多 Swift 提供给 Objective-C 程序员使用的新特性中,有个特性把自己伪装成一个无聊的老头,但是却在如何优雅滴解决“鞭尸金字塔“的问题上有着巨大的潜力。很显然我所说的这个特性就是 switch 语句, 对于很多 Objective-C 程序员来说,除了用在 Duff’s Device 上比较有趣之外,switch 语句非常笨拙,与多个 if 语句相比,它几乎没有任何优势。

    不过 Swift 中的 switch 语句能做的就多了。在接下来的教程里,我会更加详细滴讲解这些新特性的各种用途。我会忽略那些与Objective-C 和 C 中 switch 语句相比没有任何优势的解决方案。这篇文章基础的部分写于 2014 年 7 月,但是很多我写的模式都会导致编译器崩溃,所以我只好推迟这些内容的编写,直到编译器能提供更好的支持。

    这篇博客还有如下语言的版本:

    日语 (感谢 M Ono!)

    开始咯

    switch 语句主要的特性当然是模式匹配咯,模式匹配可以对值进行解构,然后根据相应 case 的正确匹配值来进行匹配。

    // 历史上最坏的一个例子:二进制->十进制的转换
    let bool1 = 1
    let bool2 = 0
    switch (bool1, bool2) {
       case (0, 0): print("0")
       case (0, 1): print("1")
       case (1, 0): print("2")
       case (1, 1): print("3")
    }

    模式匹配很早以前就在其他语言中存在了,这些语言包括 Haskell、Erlang、Scala和Prolog。这是一个福音,因为这允许我们观察那些语言是如何利用模式匹配来解决它们的问题的。我们甚至可以通过观察它们的例子来找到最实用的那个。

    一个交易引擎

    于是华尔街联系你了,他们需要一个新的运行在 iOS 设备上的交易平台。因为是交易平台,所以你需要给交易定义一个 enum

    第一步

    enum Trades {
        case Buy(stock: String, amount: Int, stockPrice: Float)
        case Sell(stock: String, amount: Int, stockPrice: Float)
    }

    同时还会提供如下的 API 给你来进行交易处理。注意销售订单的金额是如何变成负数的,而且你还会被告知股票的价格是不重要的,他们的引擎会在内部选择一个。

    /**
     - 参数 stock: 股票的名字
     - 参数 amount: 金额, 负数表示销售额, 正数表示购买额
    */
    func process(stock: String, _ amount: Int) {
        print ("\(amount) of \(stock)")
    }

    下一步就是对交易进行处理。你会发现模式匹配在写这个业务时表现出的强大处理能力:

    let aTrade = Trades.Buy(stock: "APPL", amount: 200, stockPrice: 115.5)
    
    switch aTrade {
    case .Buy(let stock, let amount, _):
        process(stock, amount)
    case .Sell(let stock, let amount, _):
        process(stock, amount * -1)
    }
    // 输出 "buy 200 of APPL"

    Swift 可以让我们非常方便滴从 enum 中解构/提取出我们真正想要的信息。在这个例子中只有 stockamount 被解构出来。

    真棒,现在你可以去华尔街展示这个极好的交易平台了。然而,现实往往比美好的想象要残酷得多。你以为交易就是你以为的交易么?

    • 你必须根据不同的交易方式计算费用。
    • 机构越小,费用越高
    • 而且,机构越大,优先级越高。

    华尔街的人也意识到要处理这些问题你需要新的 API,所以他们给了你下面的两个:

    func processSlow(stock: String, _ amount: Int, _ fee: Float) { print("slow") }
    func processFast(stock: String, _ amount: Int, _ fee: Float) { print("fast") }

    交易类型

    于是你回到绘图板重新增加了一个 enum。交易类型也是每个交易的一部分。

    enum TraderType {
    case SingleGuy
    case Company
    } 
    
    enum Trades {
        case Buy(stock: String, amount: Int, stockPrice: Float, type: TraderType)
        case Sell(stock: String, amount: Int, stockPrice: Float, type: TraderType)
    }

    所以,如何去最好滴实现这一新的机制呢?你可以用一个 if / else 分支来实现购买和销售,但是这会导致代码嵌套以至于很快代码就变的不清晰了——而且谁知道那些华尔街人会不会给你找新的麻烦。所以你应该把它定义为模式匹配的一个新要求:

    let aTrade = Trades.Sell(stock: "GOOG", amount: 100, stockPrice: 666.0, type: TraderType.Company)
    
    switch aTrade {
    case let .Buy(stock, amount, _, TraderType.SingleGuy):
        processSlow(stock, amount, 5.0)
    case let .Sell(stock, amount, _, TraderType.SingleGuy):
        processSlow(stock, -1 * amount, 5.0)
    case let .Buy(stock, amount, _, TraderType.Company):
        processFast(stock, amount, 2.0)
    case let .Sell(stock, amount, _, TraderType.Company):
        processFast(stock, -1 * amount, 2.0)
    }

    这段代码的优雅之处在于它非常简洁的描述了不同可能的组合。注意我们是如何把 .Buy(let stock, let amount) 修改成 let .Buy(stock, amount) 来让事情更简单一些。这样就可以用更少的语句来像之前一样对 enum 进行解构。

    警卫!警卫!呼叫警卫!

    于是你再次向你的华尔街用户展示你的开发成果,而他们则又提出了新的问题(你真应该把项目的细节问得更清楚一点)。

    • 交易总额超过 1.000.000$ 的销售订单通常需要更快进行处理,就算是个人客户也得这样。
    • 交易总额小于 1.000$ 的购买订单通常处理更慢。

    如果使用传统的 if 语句,这时代码就应该已经有点凌乱了,而 switch 就不会。Swift 为 switch cases 提供了保护机制,这种机制可以让你进一步滴对可能匹配的 case 进行约束。

    你只需要对 switch 语句稍作修改就可以满足新的变化。

    let aTrade = Trades.Buy(stock: "GOOG", amount: 1000, stockPrice: 666.0, type: TraderType.SingleGuy)
    
    switch aTrade {
    case let .Buy(stock, amount, _, TraderType.SingleGuy):
        processSlow(stock, amount, 5.0)
    case let .Sell(stock, amount, price, TraderType.SingleGuy)
        where price*Float(amount) > 1000000:
        processFast(stock, -1 * amount, 5.0)
    case let .Sell(stock, amount, _, TraderType.SingleGuy):
        processSlow(stock, -1 * amount, 5.0)
    case let .Buy(stock, amount, price, TraderType.Company)
        where price*Float(amount) < 1000:
        processSlow(stock, amount, 2.0)
    case let .Buy(stock, amount, _, TraderType.Company):
        processFast(stock, amount, 2.0)
    case let .Sell(stock, amount, _, TraderType.Company):
        processFast(stock, -1 * amount, 2.0)
    }

    上面的代码结构很清晰,阅读起来也相当简单,对复杂情况的封装也很好。

    就是这样,我们已经成功滴实现了我们的交易引擎。然而,这个解决方案还是有点繁琐;我们在想是否还有对其进行改进的模式匹配方案。所以,让我们继续深入研究一下模式匹配。

    模式匹配进阶

    现在我们在实战中已经见过了几种模式。但其语法是什么?还能匹配什么?Swift 将这些模式分为 7 种。我们现在就来认识一下它们。

    所有的这些模式不仅能用在 switch 关键词上,而且可以用在 ifguardfor 关键词上。如需了解详情,接着看下面的内容。

    1. 通配符模式

    通配符模式会忽略需要匹配的值,这种 case 下任何值都是有可能的。这和 let _ = fn() 一样的模式,在这个模式下, _ 表示你将不再使用这个值。有意思的是这个模式可以匹配包括 nil 在内的所有值 1 。如果增加一个 ?,它甚至可以匹配可选值:

    let p: String? = nil
    switch p {
    case _?: print ("Has String")
    case nil: print ("No String")
    }

    就像你在交易例子里面看到的一样,它也允许你忽略需要匹配的 enum 或者 tuples 中无用的数据:

    switch (15, "example", 3.14) {
        case (_, _, let pi): print ("pi: \(pi)")
    }

    2. 标示模式

    匹配一个具体的值。这个和 Objective-C 的 switch 实现是一样的:

    switch 5 {
      case 5: print("5")
    }

    3. 值绑定模式

    这种模式和通过 let 或者 var 绑定值到变量中一样。而且仅仅只在一个 switch 语句中实现。因为你之前已经见到过,所以我只给出一个非常简单的例子:

    switch (4, 5) {
      case let (x, y): print("\(x) \(y)")
    }

    4. 元组模式

    关于元组我已经写了一整篇博文,这篇博文所提供的信息远远比这里多,但是我还是在这里给出一个简短的例子:

    let age = 23
    let job: String? = "Operator"
    let payload: AnyObject = NSDictionary()
    
    switch (age, job, payload) {
      case (let age, _?, _ as NSDictionary):
      print(age)
      default: ()
    }

    在这里,我们把 3 个值结合放到一个元组中(假想它们是通过调用不同的 API 得到的),然后一口气匹配它们,注意这个模式完成了三件事情:

    1. 提取 age
    2. 确保存在一个 job,就算我们不需要它
    3. 确保 payload 的类型是 NSDictionary,尽管我们同样不需要访问它的具体值。

    5. 枚举 Case 模式(Enumeration Case Pattern)

    就如你在交易例子中所见,模式匹配对 Swift 的 enum 支持得相当棒。这是因为 enum cases 就像密封、不可变且可解构的结构体。这非常像 tuples,你可以打开正好匹配上的某个单独 case 的内容然后只抽取出你需要的信息2

    假想你正在用函数式的风格写一个游戏,然后你需要定义一些实体。你可以使用 structs 但是你的实体的状态很少,你觉得这样有点矫枉过正。

    enum Entities {
        case Soldier(x: Int, y: Int)
        case Tank(x: Int, y: Int)
        case Player(x: Int, y: Int)
    }

    现在你需要实现绘图循环。这里我们只需要 X 和 Y 坐标:

    for e in entities() {
        switch e {
        case let .Soldier(x, y):
          drawImage("soldier.png", x, y)
        case let .Tank(x, y):
          drawImage("tank.png", x, y)
        case let .Player(x, y):
          drawImage("player.png", x, y)
        }
    }

    6. 类型转换模式

    就像名字所表示的一样,这种模式转换或者匹配类型。它有两种不同的关键词:

    • is 类型:匹配右手边内容的运行时类型(或者类型的子类)。它会做类型转换但是不关注返回值。所以你的 case 块不知道所匹配的类型是什么。
    • 模式 as 类型:和 is 模式做同样的匹配操作,但是如果成功的话会把类型转换到左侧指定的模式中。

    下面是这两种关键词的例子:

    let a: Any = 5 
    switch a {
      // 这会失败因为它的类型仍然是 `Any`
      // 错误: binary operator '+' cannot be applied to operands of type 'Any' and 'Int'
      case is Int: print (a + 1)
      // 有效并返回 '6'
      case let n as Int: print (n + 1)
      default: ()
    }

    注意 is 前没有 pattern。它直接和 a 做匹配。

    7. 表达模式

    表达模式非常强大。它可以把 switch 的值和实现了 ~= 操作符的表达式进行匹配。而且对于这个操作符有默认的实现,比如对于范围匹配,你可以这样做:

    switch 5 {
     case 0..10: print("In range 0-10")
    }

    然而,更有趣的可能是自己重写操作符,然后使你的自定义类型可以匹配。我们假定你想重写之前写的士兵游戏,而且你无论如何都要使用结构体。

    struct Soldier {
      let hp: Int
      let x: Int
      let y: Int
    }

    现在你想轻松滴匹配所有血量为 0 的实体。我们可以像下面一样实现 ~= 操作符。

    func ~= (pattern: Int, value: Soldier) -> Bool {
        return pattern == value.hp
    }

    现在我们就可以对一个实体做匹配了:

    let soldier = Soldier(hp: 99, x: 10, y: 10)
    switch soldier {
       case 0: print("dead soldier")
       default: ()
    }

    不幸滴是,对元组做全匹配似乎不好使。如果你实现下面的代码,就会出现类型检查错误。

    func ~= (pattern: (hp: Int, x: Int, y: Int), value: Soldier) -> Bool {
       let (hp, x, y) = pattern
       return hp == value.hp && x == value.x && y == value.y
    }

    一个可能解决上述类似问题的方案是给你的 struct 增加一个 unapply 方法然后再进行匹配:

    extension Soldier {
       func unapply() -> (Int, Int, Int) {
          return (self.hp, self.x, self.y)
       }
    }
    
    func ~= (p: (Int, Int, Int), t: (Int, Int, Int)) -> Bool {
       return p.0 == t.0 && p.1 == t.1 && p.2 == t.2 
    }
    
    let soldier = Soldier(hp: 99, x: 10, y: 10)
    print(soldier.unapply() ~= (99, 10, 10))

    但是这相当麻烦而且没有利用好模式匹配背后的大量魔法。

    在这篇博文之前的版本中我写过 ~= 不适用于协议,但是我错了。我记得我在一个 Playground 中试过。而这个例子(由 reddit 上的 latrodectus 友情提供)是完全可用的:

    protocol Entity {
        var value: Int {get}
    }
    
    struct Tank: Entity {
        var value: Int
        init(_ value: Int) { self.value = value }
    }
    
    struct Peasant: Entity {
        var value: Int
        init(_ value: Int) { self.value = value }
    }
    
    func ~=(pattern: Entity, x: Entity) -> Bool {
        return pattern.value == x.value
    }
    
    switch Tank(42) {
        case Peasant(42): print("Matched") // 匹配成功
        default: ()
    }

    你可以利用 Expression Patterns 做很多事情。如果想要了解更多表达模式的细节,看看这篇由 Austin Zheng 写的超棒博文

    现在我们已经讲完了所有可能的 switch 模式。在我们继续讲解之前,还需要讨论最后一件事情。

    fallthrough,break 和标签

    下面的内容和模式匹配没有直接关系,仅仅是和 switch 关键词有关,所以我就简单说了。默认来说,和 C/C++/Objective-C不一样的是:switch cases 不会自动进入下一个 case,这也是为什么 Swift 不需要给每个 case 都写上 break。你可以选择使用 fallthrough 关键词来实现传统的自动进入下一个 case 的行为。

    switch 5 {
       case 5:
        print("Is 5")
        fallthrough
       default:
        print("Is a number")
    }
    // 会在命令行输出: "Is 5" "Is a number"

    另外,你可以使用 break 来提前跳出 switch 语句。既然不会默认进入下一个 case,为什么还需要这么做呢?比如你知道在一个 case 中有一个必须的要求是不满足的,这样你就不能继续执行这个 case 了:

    let userType = "system"
    let userID = 10
    switch (userType, userID)  {
       case ("system", _):
         guard let userData = getSystemUser(userID) else { break }
         print("user info: \(userData)")
         insertIntoRemoteDB(userData)
       default: ()
    }
    ... 更多你需要执行的代码

    在这段代码中,当 getSystemUser 返回的结果是 nil 时你不想再继续调用 insertIntoRemoteData。当然,你可以在这里使用 if let,但是如果多个这样的情况结合到一起的时候,很快你就会得到一堆可怕丑陋的 if lets 嵌套代码。

    但是如果你是在一个 while 循环中执行你的 switch 语句,然后你想跳出循环,而不是 switch 的时候,你需要怎么做呢?对与这种情况, Swift 允许你定义一个 labels ,然后 break 或者 continue 到这个 labels

    gameLoop: while true {
      switch state() {
         case .Waiting: continue gameLoop
         case .Done: calculateNextState()
         case .GameOver: break gameLoop
      }
    }

    我们已经讨论过 switch 和模式匹配的语法和实现细节。现在,让我们来看一些有趣(多少有点)的真实案例。

    真实案例

    可选值

    对可选值进行解包的方式有很多种,模式匹配就是其中一种。可能到现在这种方法你已经用得非常频繁了,但还是给一个简短的例子吧:

    var result: String? = secretMethod()
    switch result {
    case .None:
        println("is nothing")
    case let a:
        println("\(a) is a value")
    }

    如果是 Swift 2.0 的话,这会更简单:

    var result: String? = secretMethod()
    switch result {
    case nil:
        print("is nothing")
    case let a?:
        print("\(a) is a value")
    }

    正如你所见,result 可以是一个字符串,但是它也可能是 nil,因为它是 optional 值。通过对 result 执行 switch。我们可以确定它是 .None 或者是一个确定的值。更进一步,如果他是一个确定的值,我们可以在 a 这种情况下马上把这个值绑定到一个变量。这段代码代码的优美之处在于:变量 result 可能存在的两种状态被非常明显滴区分开来。

    类型匹配

    做为强类型体系,Swift 通常不会像 Objective-C 那样经常需要运行时类型检查。然而,当你需要与传统的 Objective-C 代码交互时(这还没有更新到简单泛型的反射一文中),那你就经常会碰到需要做类型检查的代码。假想你得到了一个包含 NSStringNSNumber 元素的数组:

    let u = NSArray(array: [NSString(string: "String1"), NSNumber(int: 20), NSNumber(int: 40)])

    当你遍历这个 NSArray 时,你永远不知道你得到的是什么类型。然而, switch 语句可以让你很简单滴在这里测试这些类型:

    for x in u {
        switch x {
        case _ as NSString:
        print("string")
        case _ as NSNumber:
        print("number")
        default:
        print("Unknown types")
        }
    }

    按范围做分级

    现在你正在给你当地的高校写分级的 iOS 应用。老师想要输入一个 0 到 100 的数值,然后得到一个相应的等级字符(A-F)。模式匹配现在要来拯救你了:

    let aGrade = 84
    
    switch aGrade {
    case 90...100: print("A")
    case 80...90: print("B")
    case 70...80: print("C")
    case 60...70: print("D")
    case 0...60: print("F")
    default:
        print("Incorrect Grade")
    }

    字频率统计

    有一系列的数据对,每个数据对代表一个字和它在某段文字中出现的频率。我们的目标就是把那些低于或者高于某个固定阈值的数据对过滤掉,然后只返回剩下的不包含其频率的所有字。

    这是我们的字集:

    let wordFreqs = [("k", 5), ("a", 7), ("b", 3)]

    一个简单的解决方案是使用 mapfilter 进行建模:

    let res = wordFreqs.filter({ (e) -> Bool in
        if e.1 > 3 {
        return true
        } else {
        return false
        }
    }).map { $0.0 }
    print(res)

    然而,因为 flatmap 只能返回非空元素,所以这个解决方案还有很大的改进空间。首先最重要的是,我们可以放弃使用 e.1 而利用元组来做适当的解构(你猜对了)。然后我们只需要调用一次 flatmap,就可以减少先 filter 然后 map 所带来的不必要的性能开销。

    let res = wordFreqs.flatMap { (e) -> String? in
        switch e {
        case let (s, t) where t > 3: return s
        default: return nil
        }
    }
    print(res)

    遍历目录

    假想你需要遍历一个文件树然后查找以下内容:

    • 所有 customer1 和 customer2 创建的 “psd“文件
    • 所有 customer2 创建的 “blend“文件
    • 所有用户创建的 “jpeg“文件
    guard let enumerator = NSFileManager.defaultManager().enumeratorAtPath("/customers/2014/")
    else { return }
    
    for url in enumerator {
        switch (url.pathComponents, url.pathExtension) {
    
        // customer1 和 customer2 创建的 “psd“文件
        case (let f, "psd") 
            where f.contains("customer1") 
            || f.contains("customer2"): print(url)
    
        // customer2 创建的 “blend“文件
        case (let f, "blend") where f.contains("customer2"): print(url)
    
        // 所有的 “jpeg“文件
        case (_, "jpg"): print(url)
    
        default: ()
        }
    }

    注意 contains 在第一个匹配就结束然后就不用遍历完整的路径了。同样,模式匹配的代码非常简洁明了。

    Fibonacci

    同样,来看一下使用模式匹配实现的 fibonacci 算法有多优美3

    func fibonacci(i: Int) -> Int {
        switch(i) {
        case let n where n <= 0: return 0
        case 0, 1: return 1
        case let n: return fibonacci(n - 1) + fibonacci(n - 2)
        }
    }
    
    print(fibonacci(8))

    当然,如果是大数的话,程序栈会爆掉。

    传统的 API 和值提取

    通常情况下,当你从外部源取数据的时候,比如一个库,或者一个 API,它不仅是一种很好的做法,而且通常在解析数据之前需要检查数据的一致性。你需要确保所有的 key 都是存在的、或者数据的类型都正确、或者数组的长度满足要求。如果不这么做就会因为bug(有的 key 没有)而导致 app 崩溃(索引不存在的数组项)。而传统的做法通常是嵌套 if 语句。

    假想有 API 返回一条用户信息。但是有两种类型的用户:系统用户——如管理员或者邮政局长——和本地用户——如 “John B“、“Bill Gates“等。因为系统的设计和增长,API 的使用者需要处理一些麻烦的事情:

    • systemlocal 用户来自同一个 API 调用。
    • 因为早期版本的数据库没有 department 这个字段,所以这个 key 可能是不存在的,而且早期的雇员从来都不需要填写这个字段。
    • 根据用户被创建的时间,name 数组可能包含 4 个元素(username,middlename,lastname 和 firstname)或者 2 个元素(full name,username)
    • age 是代表用户年龄的整型数

    我们的系统需要给这个 API 返回的所有系统用户创建用户账号,账号信息只包含如下信息:username 和 department。我们只需要 1980 年以前出生的用户。如果没有指定 department,就指定为 “Corp“。

    func legacyAPI(id: Int) -> [String: AnyObject] {
        return ["type": "system", "department": "Dark Arts", "age": 57, 
           "name": ["voldemort", "Tom", "Marvolo", "Riddle"]] 
    }

    我们为给定的约束实现一个模式来进行匹配:

    let item = legacyAPI(4)
    switch (item["type"], item["department"], item["age"], item["name"]) {
       case let (sys as String, dep as String, age as Int, name as [String]) where 
          age < 1980 &&
          sys == "system":
         createSystemUser(name.count == 2 ? name.last! : name.first!, dep: dep ?? "Corp")
      default:()
    }
    
    // 返回 ("voldemort", "Dark Arts")

    注意这段代码做了一个很危险的假设:就是如果 name 数组元素的个数不是 2 个的话,那么它一定包含 4 个元素。如果这种假设不成立,我们获得了包含 0 个元素的数组,这段代码就会崩溃。

    除了这一点,模式匹配向你展示了它是如何在只有一个 case 的情况下帮助你编写干净的代码和简化值的提取的。

    同样来看看我们是怎么写紧跟在 case 之后 let 的,这样一来就不必在每一次赋值的时候都重复写它。

    模式和其他关键词

    Swift 的文档指出不是所有的模式都可以在 iffor 或者 guard 语句中使用。然而,这个文档似乎不是最新的。所有 7 种模式对这三个关键词都有效。

    我为那些感兴趣的人编了一个例子要点,为每个模式和每个关键词都写了一个例子。

    你可以在这里查看所有的样例模式

    来看一个对三个关键词使用 值绑定元组类型转换模式的简短例子:

    // 到吗编译后只是一个关键词的集合。其本身没有任何意义
    func valueTupleType(a: (Int, Any)) -> Bool {
        // guard case 的例子
        guard case let (x, _ as String) = a else { return false}
        print(x)
    
        // for case 的例子
        for case let (a, _ as String) in [a] {
        print(a)
        }
    
        // if case 的例子
        if case let (x, _ as String) = a {
           print("if", x)
        }
    
        // switch case example
        switch a {
        case let (a, _ as String):
        print(a)
        return true
        default: return false
        }
    }
    let u: Any = "a"
    let b: Any = 5
    print(valueTupleType((5, u)))
    print(valueTupleType((5, b)))
    // 5, 5, "if 5", 5, true, false

    我们可以带着这个想法详细地看一看每一个关键词。

    使用 for case

    到了 Swift 2.0 后,模式匹配变得更加重要,因为它被扩展到不仅可以支持 switch ,还可以支持其他的关键词。比如,让我们写一个简单的只返回非空元素的数组函数:

    func nonnil<T>(array: [T?]) -> [T] {
       var result: [T] = []
       for case let x? in array {
          result.append(x)
       }
       return result
    }
    
    print(nonnil(["a", nil, "b", "c", nil]))

    关键词 case 可以被 for 循环使用,就像 switch 中的 case 一样。下面是另外一个例子。还记得我们之前说的游戏么?经过第一次重构之后,现在我们的实体系统看起来是这样的:

    enum Entity {
        enum EntityType {
        case Soldier
        case Player
        }
        case Entry(type: EntityType, x: Int, y: Int, hp: Int)
    }

    真棒!这可以让我们用更少的代码绘制出所有的项目:

    for case let Entity.Entry(t, x, y, _) in gameEntities()
    where x > 0 && y > 0 {
        drawEntity(t, x, y)
    }

    我们用一行就解析出了所有必需的属性,然后确保我们不会在 0 一下的范围绘制,最后我们调用渲染方法(drawEntity)。

    为了知道选手是否在游戏中胜出,我们想要知道是否有至少一个士兵的血量是大于 0 的。

    func gameOver() -> Bool {
        for case Entity.Entry(.Soldier, _, _, let hp) in gameEntities() 
        where hp > 0 {return false}
        return true
    }
    print(gameOver())

    好的是 Soldier 的匹配是 for 查询的一部分。这感觉有点像 SQL 而不是命令循环编程。同时,这也可以让编译器更清晰滴知道我们的意图,从而就有了打通调度增强这条路的可能性。另外一个很好的体验就是我们不需要完成滴拼写出 Entity.EntityType.Soldier。就算我们像上面一样只写 .Soldier,Swift 也能明白我们的意图。

    使用 guard case

    另外一个支持模式匹配的关键词就是新引入的 guard 关键词。它允许你像 if let 一样把 optionals 绑定到本地范围,而且不需要任何嵌套:

    func example(a: String?) {
        guard let a = a else { return }
        print(a)
    }
    example("yes")

    guard let case 允许你做一些类似模式匹配所介绍的事情。让我们再来看一下士兵的例子。在玩家的血量变满之前,我们需要计算需要增加的血量。士兵不能涨血,所以对于士兵实体而言,我们始终返回 0。

    let MAX_HP = 100
    
    func healthHP(entity: Entity) -> Int {
        guard case let Entity.Entry(.Player, _, _, hp) = entity 
        where hp < MAX_HP 
        else { return 0 }
        return MAX_HP - hp
    }
    
    print("Soldier", healthHP(Entity.Entry(type: .Soldier, x: 10, y: 10, hp: 79)))
    print("Player", healthHP(Entity.Entry(type: .Player, x: 10, y: 10, hp: 57)))
    
    // 输出:
    "Soldier 0"
    "Player 43"

    这是把我们目前讨论的各种机制用到极致的一个例子。

    • 它非常清晰,没有牵扯到任何嵌套
    • 状态的逻辑和初始化是在 func 之前处理的,这样可以提高代码的可读性
    • 非常简洁

    这也是 switchfor 的完美结合,可以把复杂的逻辑结构封装成易读的格式。当然,它不会让逻辑变得更容易理解,但是至少会以更清晰的方式展现给你。特别是使用 enums 的时候。

    使用 if case

    if case 的作用和 guard case 相反。它是一种非常棒滴在分支中打开和匹配数据的方式。结合之前 guard 的例子。很显然,我们需要一个 move 函数,这个函数允许我们说一个实体在朝一个方向移动。因为我们的实体是 enums,所以我们需要返回一个更新过的实体。

    func move(entity: Entity, xd: Int, yd: Int) -> Entity {
        if case Entity.Entry(let t, let x, let y, let hp) = entity
        where (x + xd) < 1000 &&
            (y + yd) < 1000 {
        return Entity.Entry(type: t, x: (x + xd), y: (y + yd), hp: hp)
        }
        return entity
    }
    print(move(Entity.Entry(type: .Soldier, x: 10, y: 10, hp: 79), xd: 30, yd: 500))
    // 输出: Entry(main.Entity.EntityType.Soldier, 40, 510, 79)

    限制

    一些限制已经在文章中说过,比如有关 Expression Patterns 的问题,看起来它似乎不能匹配 tuples (那样的话就真的很方便了)。在 Scala 和 Clojure 中,模式匹配在集合上同样可用,所以你可以匹配它的头部、尾部和部分等。4。这在 Swift 中是不支持的(尽管 Austin Zheng 在我之前链接的博客里差不多实现了这一点

    另外一种不可用的的情况是(这一点 Scala 同样做得很好)对类或者结构体进行解构。Swift 允许我们定义一个 unapply 方法,这个方法做的事情大体和 init 相反。实现这个方法,然后就可以让类型检查器对类进行匹配。而在 Swift 中,它看起来就像下面一样:

    struct Imaginary {
       let x: Int
       let y: Int
       func unapply() -> (Int, Int) {
         // 实现这个方法之后,理论上来说实现了解构变量所需的所有细节
         return (self.x, self.y)
       }
    }
    // 然后这个就会自动 unapply 然后再进行匹配
    guard case let Imaginary(x, y) = anImaginaryObject else { break }

    更新

    08/21/2015 结合 Reddit 上 foBrowsing 的有用反馈

    • 增加 guard case let
    • 增加简化版的 let 语法(如:let (x, y) 替代 (let x, let y)

    08/22/2015 似乎有一些东西我没测试好。我列举的一些限制实际上是可用的,另外一个 Reddit 上的评论者(latrodectus)提出了一些非常有用的指正。

    • 将之前的修正为:所有的模式对三个关键词都适用,然后增加了一些要点案例
    • 关于协议和表达式模式无效这个限制,其实没有的
    • 增加 “模式可用性“章节

    08/24/2015

    • 增加 if case 样例,重命名了一些章节。
    • 修复了一些文本拼写错误。尤其我不小心写道:_ 不能匹配 nil。那当然是不对的,_ 可以匹配所有的东西。(感谢 obecker

    09/18/2015

    • 添加了日语翻译的链接

    1.可以把它当做 shell 里面的 * 通配符

    2.我不清楚编译器是否在对这点进行了优化,但理论上来说,它应该能计算出所需数据的正确位置,然后忽略 enum 的其他情况并内联这个地址

    3.当然,不是 Haskell实现的对手:
    fib 0 = 0
    fib 1 = 1
    fib n = fib (n-1) + fib (n-2)

    4.比如:switch [1, 2, 4, 3] {
    case [, 2, , 3]:
    }

    展开全文
  • 2.1 特征的检测与匹配 SLAM系统中,是以环境中的路标点为基础的。 单目视觉系统无法从单帧图像恢复深度。如何 利用图像特征检测与匹配获得高质量的路标,关系到单目视觉SLAM的鲁棒性。 图像特征可分为:点特征、...

    2.1 特征的检测与匹配

    SLAM系统中,是以环境中的路标点为基础的。

    单目视觉系统无法从单帧图像恢复深度。如何 利用图像特征检测与匹配获得高质量的路标,关系到单目视觉SLAM的鲁棒性。

    图像特征可分为:点特征、直线特征、边缘、轮廓

    相比于其他,点特征具有对遮挡相对鲁棒,识别性好,提取速度快。点特征的检测和匹配来实现SLAM数据关联。

    2.1.1 角点特征

    角点在保留图像重要特征时,可以有效减少信息数据量,使其信息含量很高,有效提高计算速度,有利于图像可靠匹配,有利于实时。

    Harris角点:

    • Harris角点是Harris在1988年提出的一种基于信号的点特征提取算子,前身是Moravec 算子。
    • Harris角点使用自相关矩阵 改进了Moravex方法, 避免了使用离散的方向和偏移,它在窗口内使用高斯函数加权导数,取代了简单的求和。
    • 如果自相关矩阵有2个较大的特征值就表示该店为检测到的特征点。
    • 但其对亮度和对比度变化不敏感,具有旋转不变形,不具备尺度不变形。

    Shi-Tomasi角点:

    • Shi1994年 采用不同的响应函数来提取图像角点,其方式是如果2个特征值中较小的一个大于最小阈值,则判定为角点。
    • Shi的角点判定 方法比较充分,很多情况下都比Harriss算法结果更好

    FAST(features from accelerated segment test)角点:

    • Rosten在2006年提出的一种简单快速的角点检测算法。
    • 该算法检测的角点定义为在像素点的周围邻域内有足够多的像素点与该点处于不同的区域
    • 在灰度图像中,即有足够多的像素点灰度值大于该点的灰度值或者小于该点的灰度值
    • 由于FAST算法能在短时间生成大量角点,因此广泛用于实时性较高的SLAM系统中。

    2.1.2 SIFT和SURF特征

    SIFT(scale invariant feature transform)方法:

    • SIFT是Lowe在1999年提出的一种特征点提取方法。
    • SIFT特征对图像的尺度变化、图像缩放、旋转甚至仿射变换具有不变形
    • 对光照变换和图像变形具有较强的适应性
    •  首先检测由高斯差分构建的尺度空间上的局部极值点,并将其作为候选特征点,排除不太稳定的和对比度低的,从而确定关键点,接下来 为关键点分配方向,并通过采样关键点周围图像块图像梯度的幅值和方向来建立SIFT特征描述子
    • 由于SIFT特征提取和匹配存在大量的浮点运算,时间 复杂度较高,不能保证实时性,因此在单目SLAM应用不多
    • 利用GPU加速后克服了浮点运算,因此有一些GPU-SIFT作为特征检测和匹配方法。

    SURF(speeded up robust features)方法:

    • 是对SIFT的改进,基本结构、步骤与SIFT相近
    • 速度快,且稳定性高,广泛应用

    2.1.3 BRIEF与ORB特征

    BRIEF(binary robust independent elementary features)特征:

    •  Calonder在2010年提出的可以快速计算且表达方式为二进制编码的描述子
    • 主要思路是在特征点附近随机选取若干点对,将这些点对的灰度值的大小,组合成一个长为256 的二进制串,并将这个二进制串作为该特征点的特征描述子。由于其描述子利用二进制编码,因此在特征匹配时只需计算2 个特征点描述子的Hamming 距离。经过大量实验数据测试,不匹配特征点的描述子的Hamming 距离在128 左右,匹配点对描述子的Hamming 距离则远小于128。由于BRIEF 的匹配速度远高于SURF 和SIFT,因此被很多系统采用。

    ORB(oriented brief)特征:

    • 由于BRIEF 特征不具备旋转不变性,因此很难用于旋转比较剧烈的环境。
    • 为了解决这一问题,EthanRublee在2011 年提出了ORB( oriented brief)特征,较好地解决了尺度不变性。
    • 在尺度变化不大的环境,ORB 特征在SLAM 系统中获得了大量应用 
    展开全文
  • #!coding:utf-8 ...# 测试匹配中文信息 def TestReChinese( ): reload(sys) sys.setdefaultencoding( "utf-8" ) # 这段HTML代码是从博客列表页面中摘取出来的单个博客的信息, 我们要从中摘取出
  • 例如,在没有对应信息的情况下,发现英语和德语文章聚类之间的对应关系,例如不同语言下使用词汇的对应关系、同语义语句对应关系等。在作者的模型中,所有语言中的文档具有共同的主题,主题在所有语言中是共享的。每...
  • NLP之文本匹配及语义匹配应用介绍

    万次阅读 多人点赞 2019-07-11 18:11:57
    2、文本匹配方法概述2-1 传统文本匹配方法2-2 主题模型2-3 深度语义匹配模型表示型交互型3、语义匹配应用介绍3-1 短文本-短文本语义匹配3-2 短文本-长文本语义匹配案例1-用户查询-广告页面相似度案例2:文档关键词...
  • 瑞克斯情绪 带有 Rijksmuseum 和 Sightcorp api 的 Hyper Island 项目。 我们将人们的情感与挂在博物馆墙上的亲戚相匹配。 一个为期 4 周的项目,用于学习代码和连接 api。 阅读有关该项目的更多信息
  • 提示:文章写完后,目录可以...图像匹配一般由两部分组成,即匹配特征的性质和匹配策略 area-based method:采用局部或者整体的相似性测量,而不用检测整体图像结构 特点:基于区域的图像匹配计算成本高昂,对图像失真敏
  • opencv双目匹配定位之匹配点的输出

    千次阅读 2016-10-08 14:15:56
    阅读文献后决定选取sift进行特征点匹配的方法实现。去年已经完成了,立体匹配信息还原在mattlab上的实现,但是特征点却是选取最不智能的手选。。。。于是赶在十一放假结束前使用opencv进行下特征点的选取,并将...
  • 语义匹配应用介绍

    千次阅读 2018-01-26 15:46:31
    语义匹配 工业界的很多应用都有在语义上衡量本文相似度的需求,我们将这类需求统称为“语义匹配”。根据文本长度的不同,语义匹配可以细分为三类:短文本-短文本语义匹配,短文本-长文本语义匹配和长文本-长文本...
  • 详解字符串的快速匹配算法:KMP

    千次阅读 多人点赞 2018-08-14 00:44:06
    在字符串匹配算法里,有两种较为常见的方式,BF 算法与 KMP 算法...而 KMP 算法则是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数来实现快速匹配,当出现匹配不相等时,不需要回溯,只需利用已经得到的匹配...
  • 匹配追踪算法(MP)简介

    千次阅读 多人点赞 2017-10-11 23:17:17
    经典的算法有匹配追踪(Matching Pursuit,MP)、正交匹配追踪(Orthogonal Matching Pursuit,OMP)、基追踪(Basis Pursuit,BP)算法等. MP算法是稀疏表征中用于稀疏求解的最基本方法之一. 我在学习过程中参考网上...
  • 向AI转型的程序员都关注了这个号????????????机器学习AI算法工程 公众号:datayx针对互联网求职招聘场景的人岗匹配推荐问题,本文提出了一种建模求职者与招聘者双方偏好的新型...
  • 步骤一 构造前缀树步骤二 设置每一个节点的Failure Node步骤三 收集每个节点的所有匹配模式串信息步骤四 对目标串进行搜索匹配 AC自动机进行字符串匹配的过程,可以参考维基百科的说明: htt
  • 文本匹配:语义相关性

    千次阅读 2018-08-19 19:52:46
    语义相关性,比如搜索,查询词和文档如果关键字不一样,但两者是多词一义,则模型不理解语义,做语义上的匹配解决不了问题。在推荐中,商品可以由一...适用场景:阅读理解,QA,搜索,语义蕴含,推荐,广告等。  ...
  • java 正则匹配 Pattern

    千次阅读 2013-03-05 19:39:12
    java正则表达式通过java.util.regex包下的Pattern类与Matcher类实现(建议在阅读本文时,打开java API文档,当介绍到哪个方法时,查看java API中的方法说明,效果会更佳).  Pattern类用于创建一个正则表达式,也可以说...
  • 深入分析Intent匹配查询

    千次阅读 2014-12-30 22:37:41
    在前面的一篇文章中,我们详细分析了PackageManagerService的启动过程(在后面的文章中,为了...在这篇文章中,我们会接着前面一篇文章继续分析Intent匹配查询过程,如果对PMS不是很熟悉的同学建议先去阅读前面一篇文章
  • 匹配滤波器的物理解释

    万次阅读 多人点赞 2017-01-27 21:33:54
    匹配滤波器的物理解释    匹配滤波器是一种非常重要的滤波器,广泛应用与通信、雷达等系统中。匹配滤波器的推导数学公式看起来很负责,在通信系统、雷达系统、随机信号处理等很多教科书中都有详细的推导过程。...
  • 短文本匹配的一些经典方法和常用深度学习方法的论文阅读
  • 基于异常检测与聚类优化的深度文本匹配模型,杨靖城,詹舒波,文本匹配在例如信息检索、自动问答、对话系统、阅读理解等多项自然语言处理任务中有广泛应用。传统方法主要使用词袋或人工特征,
  • java中字符串的精确匹配 在使用Java编程语言时,我们将继续讨论与建议的实践有关的系列文章,我们将讨论String性能调优。 我们将专注于如何有效地处理字符串创建, 字符串更改和字符串匹配操作。 此外,我们将提供...
  • 感兴趣的读者可以对比阅读这两个实现,里面的B_VALUE选值不一样。 在目标串char text[] = "text is abcdef 123456 abx456 12xdef 12cdef ab3456 ab3457"中查找以下下几个模式串 "abcdef" "123456" ...
  • 图像文本匹配,顾名思义,就是度量一幅图像和一段文本的相似性,该技术是多个模式识别任务的核心算法。例如,在图像文本跨模态检索任务中,当给定查询文本,需要依据图像文本的相似性去检索内容相似的图像;在图像...
  • phpstorm正则匹配删除注释行

    千次阅读 2017-09-28 21:01:16
    phpstorm正则匹配删除注释行(替换注释行为空行) ...遇到了一个需求,有时候在阅读框架源代码的时候 , 想过滤(删除)掉源代码中的注释行,如果手动逐行删除显示不够科学。 当然想到了强大的正则匹配(regExp regula

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 169,712
精华内容 67,884
关键字:

信息匹配阅读