扩展_扩展欧几里得算法 - CSDN
精华内容
参与话题
  • 2019最好用的谷歌扩展工具

    千次阅读 2019-04-25 16:08:46
    Extensions Manager 安装地址: ... 这是一款很方便的扩展应用和主题管理器,它可以快速轻松地启用、禁用、卸载你的扩展应用,显示你正在操作的扩展应用,并且不处理私人信...

    Extensions Manager

    安装地址:

    https://chrome.google.com/webstore/detail/extensions-manager-aka-sw/lpleipinonnoibneeejgjnoeekmbopbc?hl=en

    这是一款很方便的扩展应用和主题管理器,它可以快速轻松地启用、禁用、卸载你的扩展应用,显示你正在操作的扩展应用,并且不处理私人信息和敏感信息,可以让你的浏览器更加清楚有条理。

    HTTPS Everywhere

    安装地址:

    https://chrome.google.com/webstore/detail/https-everywhere/gcbommkclmclpchllfjekcdonpmejbdp?hl=en

    首先来和你简单介绍下什么是HTTPS。

    “HTTPS”是一种网站协议,可以确保网站在你访问之前是安全的。与之对应的是网站的开头为:HTTP

    所以存在两种区别,即 “HTTPS 和 HTTP”

    简单来讲,访问Https的网站其实是更安全的,而http其实更容易遭受攻击,也意味着这样的网站更存在风险,比如说我的博客,大家可以观察一下,我的博客的链接是:

    很多人会问我,为什么我不去做https?

    我的回答是,因为我的博客是免费给大家看,又不交易,又不下单,所以我懒得搞这个https。

    所以看到这里,你就明白了,因为很多互联网的小白,很多时候察觉不出网站是否被钓鱼,自己判别不出来,那么就可以利用HTTPS Everywhere。

    HTTPS Everywhere在许多站点上自动使用HTTPS 安全性,它会将访问网站的请求重写为Chrome版本,这样就可以确保浏览器生成的是该网站的安全版本,保护你免受各种形式的监视和账户劫持、某些形式的审查。

    当我在我的网站上开启https的时候。

     

    你看我的博客就变成了 https了,这样你就可以安全访问了。

    所以你看是不是非常的使用方便呢?

    对了,类似的工具,还有一款叫,J2Team Security 也非常的好用,可以很好的保护你的网站的隐私。

    Click&Clean

    安装地址

    https://chrome.google.com/webstore/detail/clickclean/ghgabhipcejejjmhhchfonmamedcbeod?hl=en

    这款软件是干什么用的呢?

    如果你的工作经常要搜索、下载资料,那你需要这样一款快速清除历史缓存、提高运行速度的应用。

    其实我们也可以直接在浏览器上清空缓存,但是需要点击两个步骤,比较麻烦,但是通过这个插件,直接一键点击,使用起来非常的方便。

    所以只需轻松点击Click&Clean按钮,就可以清除缓存、网址搜索、网站Cookie和下载记录。

    另外这款工具,它还可以扫描计算机中的病毒,并清理硬盘驱动中未使用的应用软件,帮你提升网速。

    Bitly

    安装地址

    https://chrome.google.com/webstore/detail/bitly-unleash-the-power-o/iabeihobmhlgpkcgjiloemdbofjbdcic

    bitly相信很多人都已经用到过!

    就是一款缩短网址,可以把长链接变成短链接,这样你在外面推广的时候,会让人觉得比较清爽,可靠。

    太长的链接,给人的感觉很不专业,又影响了人的点击欲望,因此就会经常用到缩短工具。该用具就是生成短连接的,玩过新浪微博的人都知道!

    BuzzSumo

    安装地址

    https://chrome.google.com/webstore/detail/buzzsumo/gedpbnanjmblcmlfhgfficjnglidndfo

    这个工具让你能够很简单地查看内容的参与度。还可以用它执行竞争对手分析,让你快速的知道,竞争对手有哪些好的文章是被分享的最多的,哪些文章是给他们带去最大的流量。

    那么你就可以模仿他们的文章,知道写什么样的话题,素材最有用,这是一个非常好的对于内容挖掘的好方法

    Pinterest

    安装地址

    https://chrome.google.com/webstore/detail/pinterest-save-button/gpdjojdkbbmdfjfahjcgigfpmkopogic

    这是一款让你无需离开你正在进行的操作,轻松将内容保存到Pinterest板上的一款应用。

    一句话,利用这个工具,可以很快速的把好看的图片Pin到你的board中。

    因此你可以一次性在你的Pinterest板上面保存多个内容。保存的方法是单击每个博客文章或者图像,以便单独地将每个文章分别固定在你的Pinterest板上,这样使用起来非常的方便。

    Instagram for Chrome

    安装地址

    https://chrome.google.com/webstore/detail/instagram-for-chrome/opnbmdkdflhjiclaoiiifmheknpccalb/related

    这个工具是干什么用的呢?

    如果你想要实时看到Instagram上面的消息,又嫌一直查看手机太麻烦的话,就可以使用这个应用,它能让你直接在浏览器上面查看Instagram的消息。

    Checkbot

    安装地址

    https://chrome.google.com/webstore/detail/checkbot-seo-web-speed-se/dagohlmlhagincbfilmkadjgmdnkjinl?hl=en

    Checkbot是一款结合了SEO优化技术和安全性的应用,帮助你分析对于搜索引擎来说网站的优化程度和安全性。

    你看这个很重要吧。

    很多人砸了很多钱在广告上,可是网站都没有优化好,那投的广告的意义在哪里,对不对。

    我们知道,谷歌等搜索引擎除了看排名中的内容质量以外,网站的安全性也是一个重要的指标考核,因此这款应用对于SEO内容负责人和网站开发人员来说是很有用的。

    Checkbot是一个功能强大的网站审核员,可以在几分钟内检查(每个站点)250个以上网址的网速、SEO、整体安全性,发现损坏的链接、重复的标题、无效的HTML/CSS/JavaScript,不安全的密码表单、重定向链、混合内容错误等。

    对于网站的排查,非常有效。

    MozBar

    安装地址:

    https://chrome.google.com/webstore/detail/mozbar/eakacpaijcpapndcfffdgphdiccmpknp

    我主要是用这个工具看两点:

    第一:网站的PA和DA值

    第二:网页的质量得分

    Check My Links

    安装地址:

    https://chrome.google.com/webstore/detail/check-my-links/ojkcdipcgfaekbeaelaapakgnjflfglf

    这款应用可以快速扫描网页,显示出哪些链接可以正常工作,哪些链接已经打不开。

    其实呢,可以利用这个工具找404的文章,来做外链,那么这个工具必将会派上用场。

    NoFollow

    安装地址: https://chrome.google.com/webstore/detail/nofollow/dfogidghaigoomjdeacndafapdijmiid/related

    句话,利用这个工具可以快速的查看哪些链接是被索引的,哪些链接是不被索引的。

    如果这个工具检测出来,如上图(红色方框)则代表这个链接其实是不被索引的,不被索引的链接,当然也就是不被传递网站的权重。

    “那啥,啥叫权重啊,啥叫索引啊?

    科普科普

    权重怎么说呢,就是一个网站的综合性指标,就好比,我们经常说一个人一样,我们说他的威望很高。

    你的威望越高,就代表你说话越有份量!

    权重和这个威望其实有点相似,一个网站的权重越高,就越代表他的综合排名啊,网站的各项指标都很好,那么搜索引擎对这样的网站是有加权的。

    所以如果你找一个有权重的网站做推广,可是发现对方设置了nofollow,那对不起,这代表,这个链接是不被Google索引的,也就代表对方的网站是不传递权重的。

    所以做SEO的人可以使用这个扩展来确定外部网站是否通过跟踪的链接或者是索引链接做了外链。

    此外,你还可以在不想被抓取的网页上使用Nofollow链接,例如登陆页面或是感谢页面,使用这个应用可以帮助你轻松仔细地检查编码链接是否正确。如上图Nofollow链接用红框标记出来了。

    OneTab

    安装地址

    https://chrome.google.com/webstore/detail/onetab/chphlpgkkbolifaimnlloiipkdnihall

    我们经常会发现,有时候你的浏览器会不自觉的多开了很多窗口,而一旦你同时开了很多窗口,那么你的电脑运行速度其实会变慢的。

    那么这个工具就可以派上用场了。

    你可以单击OneTab图标,将所有标签页转换成一个列表。当你需要再次访问这些标签时,可以单独或全部恢复它们。

    通过这个方法,它能减少谷歌浏览器打开的标签页的数量,这样可以大大节省高达95%的内存!

    AwesomeScreenshot

    安装地址:

    https://chrome.google.com/webstore/detail/awesome-screenshot-screen/nlipoenfbbikpbjkfpfillcgkoblgpmj

    这款工具很简单,就是一个截图工具。

    和我们经常用到的QQ截图啊,微信截图啊,其实是差不多的。

    只是有时候我没有登录qq或者微信,我就可以直接用工具了。

    另外这个屏幕截图扩展工具,还有注释和照片编辑功能,并能保留在浏览器中。

    在截取屏幕选定区域或整个网页的屏幕截图后,还有裁剪、突出显示、绘制形状以及马赛克等功能。

    功能还是很多的!

    Evernote Web Clipper

    安装地址:

    https://chrome.google.com/webstore/detail/evernote-web-clipper/pioclpoplcdbaefihamjohnefbikjilc

    我相信,凡是使用过印象笔记的,应该会对这个裁剪工具会非常熟悉吧

    通过Evernote Web Clipper这个裁剪工具,比如说,你看到一篇非常好的文章,那么你可以不用手动copy复制,因为这样非常的麻烦,你只要一键点击裁剪按钮,然后整篇文章就会被保存在你印象笔记中的账户中。

    这样今后你可以对保存下来的文章,反复的阅读。

    允许我再次强调下,文章的归纳是非常重要的,有太多的人,做的笔记都非常乱,我建议大家还是多花点时间学学,怎么做笔记。

    不要觉得这些很简单,当你知道如何高效的运用笔记,他所给你带来的价值将是巨大的。

    Evernote Web Clipper,这个功能我经常使用,太方便了,强烈推荐!

    Grammarly

    安装地址:

    https://chrome.google.com/webstore/detail/grammarly-for-chrome/kbfnbcaeplbcioakkpcpgfkobkghlhen?hl=en

    这款工具是用于审查在你博客写完英文文章,或者邮件的时候,利用这个工具可以很好的检查你文章的拼写、语法和单词使用是否正确。

    像我们团队中的内容编辑部门和产品运营部门,基本每天都会用到这个工具!

    一把好的剑,只有被懂得人所掌握,才能发挥出他真正的价值,反之,再好的剑,都是一把废铁。

    对于工具来说,显然这个道理同样适用!

    展开全文
  • 扩展

    2019-07-11 11:07:31
    扩展基础 swift的扩展使用关键字extension swift的扩展相当于OC的分类,即只能新增方法不能新增存储属性。 extension Double { var km: Double { return self * 1000 } var cm: Double { return self / ...
    1. 扩展基础
      1. swift的扩展使用关键字extension
      2. swift的扩展相当于OC的分类,即只能新增方法不能新增存储属性。
    extension Double {
        var km: Double {
            return self * 1000
        }
        
        var cm: Double {
            return self / 100.0
        }
        
        var mm: Double {
            return self / 1000.0
        }
    }
    
    var a: Double = 1000
    print(a.cm)
    
    1. 构造器的扩展
      1. 枚举类型和结构体类型只可以有指定构造器没有便利构造器。而类可以有指定构造器和遍历构造器。
      2. 类既可以有构造器也可以有遍历构造器。
      3. 扩展只可以为枚举类型和结构体类型扩展指定构造器,不能扩展遍历构造器。
      4. 扩展只能给类扩展遍历构造器,不能扩展指定构造器。
    //只能给类扩展遍历构造器
    class Test {
        var name: String = ""
        init(name: String) {
            self.name = name
        }
    }
    
    extension Test {
      convenience init(nameStr: String) {
        self.init(name: nameStr)
           self.name = nameStr
        }
    }
    
    //只能给结构体,枚举扩展指定构造器
    struct TestStruct {
        var name: String
        init(name: String) {
            self.name = name
        }
    }
    
    extension TestStruct {
        init(nameStr: String) {
            self.init(name: nameStr)
            self.name = nameStr + "test"
        }
    }
    
    enum TestEnum {
        case one, two ,three
    }
    
    extension TestEnum {
        init(type: String) {
            switch type {
            case "one":
                self = .one
            case "two":
                self = .two
            case "three":
                self = .three
            default:
                self = .one
            }
        }
    }
    
    var a = TestEnum(type: "one")
    
    1. 扩展方法
      1. 可以给结构体,类扩展实例方法,类方法。
      2. 可以给结构体,枚举类型扩展可变实例方法。
    extension Int {
        //1. 扩展实例方法
       func repeatClosure(closure: () -> Void){
            for _ in 0..<self{
                closure()
            }
        }
        
        //2. 扩展可变实例方法 (结构体或者枚举类型用)
        mutating func square(){
            self = self * self
        }
        
        //3. 扩展类方法
        static func sum(_ one: Int, _ two: Int) -> Int{
            return one + two
        }
    }
    
    3.repeatClosure {
        print("Hello World!")
    }
    
    var a = 3
    a.square()
    print(a)
    
    print(Int.sum(3,5))
    
    1. 扩展下标
    extension Int {
        subscript(num: Int) -> Int {
            var numShi = 1
            for _ in 0..<num{
                numShi *= 10
            }
            
           return (self/numShi) % 10
        }
    }
    
    var a = 123456789
    print(a[0])
    print(a[2])
    
    1. 扩展嵌套类型
    extension Int {
        enum Kind: String {
            case negative, zero, positive
        }
        
        var kind: Kind {
            switch self {
            case 0:
                return .zero
            case let x where x > 0:
                return .positive
            default:
                return .negative
            }
        }
    }
    
    func check(numbers: [Int]) {
        for item in numbers {
            switch item.kind {
            case .negative:
                print("-", terminator: " ")
            case .zero:
                print("0", terminator: " ")
            case .positive:
                print("+", terminator: " ")
            }
        }
    }
    
    check(numbers: [3, 19, -27, 0, -6, 0, 7])
    
    1. 总结
      1. 枚举类型的扩展
        1. 可以给枚举类型扩展实例方法,类方法,实例可变方法。
        2. 可以扩展指定构造器。
        3. 可以扩展下标
        4. 可以扩展嵌套类型
      2. 结构体的扩展
        1. 可以扩展计算属性
        2. 可以扩展实例方法,类型方法,实例可变方法。
        3. 可以扩展指定构造器。
        4. 可以扩展下标。
        5. 可以扩展嵌套类型。
      3. 类的扩展
        1. 可以扩展计算属性。
        2. 可以扩展实例方法,类型方法。
        3. 可以扩展便利构造器。
        4. 可以扩展下标
        5. 可以扩展嵌套类型
    展开全文
  • 扩展KMP的详细理解

    万次阅读 2018-05-22 16:37:02
    扩展KMP的详细理解扩展KMP求的是对于原串S1的每一个后缀子串与模式串S2的最长公共前缀。它有一个next[]数组和一个extend[]数组。next[i]表示为模式串S2中以i为起点的后缀字符串和模式串S2的最长公共前缀长度.其中,...

    扩展KMP的详细理解

    扩展KMP求的是对于原串S1的每一个后缀子串与模式串S2的最长公共前缀。它有一个next[]数组和一个extend[]数组。

    next[i]表示为模式串S2中以i为起点的后缀字符串和模式串S2的最长公共前缀长度.

    其中,next[0]=l2;

    next[i]=max{ k|i<=i+k-1<l2 &&S2.substring(i,i+k-1) == S2.substring(0,k-1) }

    其中str.substring(i, j)表示str从位置i到位置j的子串,如果i>j则,substring为空。

    extend[i]表示为以字符串S1中以i为起点的后缀字符串和模式串S2的最长公共前缀长度.

    下面我们先以一组样例来理解扩展KMP的过程


    (1) 第一步,我们先对原串S1和模式串S2进行逐一匹配,直到发生不配对的情况。我们可以看到,S1[0]=S2[0],S1[1]=S2[1],S1[2]=S2[2],S1[3] ≠S2[3],此时匹配失败,第一步结束,我们得到S1[0,2]=S2[0,2],即extend[0]=3;

    (2) Extend[0]的计算如第一步所示,那么extend[1]的计算是否也要从原串S1的1位置,模式串的0位置开始进行逐一匹配呢?扩展KMP优化的便是这个过程。从extend[0]=3的结果中,我们可以知道,S1[0,2]=S2[0,2],那么S1[1.2]=S2[1,2]。因为next[1]=4,所以S2[1,4]=S2[0,3],即S2[1,2]=S[0,1],可以得出S1[1,2]=S2[1,2]=S2[0,1],然后我们继续匹配,S1[3] ≠S2[3],匹配失败,extend[1]=2;

    (3) 因为extend[1]=2,则S1[1,2]=S2[0,1],所以S1[2,2]=S2[0,0],因为next[0]=5,所以S1[0,5]=S2[0,5],所以S2[0,0]=S2[0,0],又回到S1[2,2]=S2[0,0],继续匹配下一位,因为S1[3] ≠S2[1],所以下一位匹配失败,extend[2]=1;

    (4) 到计算原串S1的3号位置(在之前的步骤中能匹配到的最远的位置+1,即发生匹配失败的位置),这种情况下,我们会回到步骤(1)的方式,从原串S1的3号位置开始和模式串的0号位置开始,进行逐一匹配,直到匹配失败,此时的extend[]值即为它的匹配长度。因为S1[3] ≠S2[0],匹配失败,匹配长度为0,即extend[3]=0;

    (5) 计算S1的4号位置extend[]。由于原串S1的4号位置也是未匹配过的,我们也是回到步骤(1)的方式,从原串S1的4号位置开始和模式串S2的0号位置开始进行逐一匹配,可以看到,S1[4]=S2[0],S1[5]=S2[1],S1[6]=S2[2],S1[7]=S2[3],S1[8]=S2[4],S1[9] ≠S2[5],此时原串S1的9号位置发生匹配失败,最多能匹配到原串S1的8号位置,即S1[4,8]=S2[0,4],匹配长度为5,即extend[4]=5;

    (6) 计算S1的5号位置extend[].由于原串S1的5号位置是匹配过的(在步骤(5)中匹配了),我们从extend[4]=5得出,S1[4,8]=S2[0,4],即S1[5,8]=S2[1,4],和步骤(2)的计算方式类似,我们从next[1]=4可知,S2[0,3]=S2[1,4],即S1[5,8]=S2[0,3],然后我们继续匹配原串S1的9号位置和S2的4号位置,S1[9]=S2[4],继续匹配,S1[10]=S2[5],此时原串S1的所有字符皆匹配完毕,皆大欢喜,则S1[5,10]=S2[0,5],extend[5]=6;

    (7) 从原串S1的6号位置到10号位置的extend[]的计算,与原串S1的1号位置到3号位置的计算基本相同。S1[6,10]=S2[1,5],因为next[1]=4,所以S2[1,4]=S[0,3],所以S1[6,9]=S2[0,3],此时不在需要判断匹配下一位的字符了,直接extend[6]=4;(具体原因在后面的分析总结中有说明)

    (8) S1[7,10]=S2[2,5],因为next[3]=2,所以S2[3,4]=S2[0,1],所以S1[8,9]=S2[0,1],匹配长度为2,即extend[7]=3;

    (9) S1[8,10]=S2[3,5],因为next[3]=2,所以S2[3,4]=S2[0,1],所以S1[8,9]=S2[0,1],匹配长度为2,即extend[8]=2;

    (10) S1[9,10]=S2[4,5],因为next[4]=1,所以S2[4,5]=S2[0,0],所以S1[9,9]=S2[0,0],匹配长度为1,即extend[9]=1;

    (11) S1[10,10]=S2[5,5],因为next[5]=0,所以匹配长度为0,即extend[10]=0;

    至此,所有的匹配已经结束,相信,如果你仔细的看了上述的例子,已经对扩展KMP有了一定的了解了,它的计算过程中,主要是步骤一和步骤二的计算过程。下面我们对这两个过程归纳一下:

     

    我们先定义,从0~k的计算过程中,我们已经计算出它们的extend[]值了和在匹配的过程中从Po开始匹配能匹配到的最远位置P,即Po+extend[Po]-1=P;

    步骤一:当前需要计算的extend[k+1],原串S1中k+1号位置还未进行过匹配,则从原串S1的k+1号位置和模式串S2的0号位置开始进行逐一匹配,直到匹配失败,则extend[k+1]=匹配长度,此外,还要相应的更新Po值和最远匹配位置P.

    步骤二:当前需要计算的extend[k+1],原串S1中k+1号位置已经进行过匹配。首先,我们从Po+extend[Po]-1=P中,可以得知S1[Po,P]=S2[0,P-Po],所以S1[k+1,P]=S2[k+1-Po,P-Po],令len=next[k+1-Po]

    (1) 当(k+1)+len-1=k+len<P时,即一下情况:

     

    我们可以得出,len=next[k+1-Po],S2[0,len-1]=S2[k+1-Po,k+Po+len],所以S1[k+1,k+len]=S2[k+1-Po,k+Po+len]=S2[0,len-1],即extend[k+1]=len;

    那么会不会出现S1[k+len+1]=S2[len]的情况呢?答案是否定的

    假如S1[k+len+1]=S2[len],则S1[k+1,k+len+1]=S2[0,len]

    因为k+len<P,所以k+len+1<=P

    所以S1[k+1,k+len+1]=S2[k+1-Po,k+Po+len+1]=S2[0,len]

    此时,next[k+1-Po]=len+1与原假设不符合,所以此时S1[k+len+1]≠S2[len],不需要再次判断。

    (2)当(k+1)+len-1=k+len>=P时,即一下情况:

     

    我们可以看出,由S1[Po,P]=S2[0,P-Po]可得出S1[k+1,P]=S2[k+1-Po,P-po],len=next[k+1-Po],所以S2[0,len-1]=S2[k+1-Po,k+len+Po]

    所以S1[k+1,p]=S2[0,P-k-1]

    由于大于P的位置我们还未进行匹配,所以从原串S1的P+1位置开始和模式串的P-k位置开始进行逐一匹配,直到匹配失败,并更新相应的Po位置和最远匹配位置P,此时extend[k+1]=P-k+后来逐一匹配的匹配长度。

    其实,next[]数组的计算过程与extend[]的计算过程基本一致,可以看成是原串S2和模式串S2的扩展KMP进行计算,每次计算extend[k+1]时,next[i](0<=i<=k)已经算出来了,算出extend[k+1]的时候,意味着next[k+1]=extend[k+1]也计算出来了。

    时间复杂度分析

    通过上面的算法可知,我们原串S1的每一个字符串只会进行一次匹配,extend[k+1]的计算可以通过之前extend[i](0<=i<=k)的值得出,由于需要用相同的方法对模式串S2进行一次预处理,所以扩展KMP的时间复杂度为O(l1+l2),其中,l1为原串S1的长度,l2为模式串S2的长度。

    HDU - 2328 

    Corporate Identity

    题意:给你n个字符串,求这n个字符串的最长公共子串
    思路:有多种方面可以做出这道题,我们这里先找出最短的一个母串,然后枚举它的每一个子串,对于每一个子串和原来的母串进行扩展KMP匹配,然后记录匹配的最大值和对应的位置即可,需要注意的时,多个答案时,输出字典序最小的子串。
    //#include<bits/stdc++.h>
    /*
    next[0]=l2; 
    next[i]=max{ k|i<=i+k-1<l2 &&str.substring(i,i+k-1) == str.substring(0,k-1) } 其中str.substring(i, j)表示str从位置i到位置j的子串,如果i>j则,substring为空。
    next[i]表示为以模式串s2中以i为起点的后缀字符串和模式串s2的最长公共前缀长度.
    extend[i]表示为以字串s1中以i为起点的后缀字符串和模式串s2的最长公共前缀长度.
    */
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #include<map>
    using namespace std;
    const int maxn=100010;   //字符串长度最大值
    const int INF=int(1e9);
    int nxt[maxn],ex[maxn]; //ex数组即为extend数组
    char s1[maxn],s2[maxn];
    char s[5010][210];
    //预处理计算next数组
    void get_next(char *str) {
    	int i=0,j,po,len=strlen(str);
    	nxt[0]=len;//初始化next[0]
    	while(str[i]==str[i+1]&&i+1<len)//计算next[1]
    		i++;
    	nxt[1]=i;
    	po=1;//初始化po的位置
    	for(i=2; i<len; i++) {
    		if(nxt[i-po]+i<nxt[po]+po)//第一种情况,可以直接得到next[i]的值
    			nxt[i]=nxt[i-po];
    		else { //第二种情况,要继续匹配才能得到next[i]的值
    			j=nxt[po]+po-i;
    			if(j<0)j=0;//如果i>po+next[po],则要从头开始匹配
    			while(i+j<len&&str[j]==str[j+i])//计算next[i]
    				j++;
    			nxt[i]=j;
    			po=i;//更新po的位置
    		}
    	}
    }
    //计算extend数组
    bool exkmp(char *s1,char *s2) {
    	int i=0,j,po,len=strlen(s1),l2=strlen(s2);
    	get_next(s2);//计算子串的next数组
    	while(s1[i]==s2[i]&&i<l2&&i<len)//计算ex[0]
    		i++;
    	ex[0]=i;
    	po=0;//初始化po的位置
    	if(ex[0]==l2)
    		return true;
    	for(i=1; i<len; i++) {
    		if(nxt[i-po]+i<ex[po]+po)//第一种情况,直接可以得到ex[i]的值
    			ex[i]=nxt[i-po];
    		else { //第二种情况,要继续匹配才能得到ex[i]的值
    			j=ex[po]+po-i;
    			if(j<0)j=0;//如果i>ex[po]+po则要从头开始匹配
    			while(i+j<len&&j<l2&&s1[j+i]==s2[j])//计算ex[i]
    				j++;
    			ex[i]=j;
    			po=i;//更新po的位置
    		}
    		if(ex[i]==l2)
    			return true;
    	}
    	return false;
    }
    void char_(char *str1,char *str,int l,int r) {    //将str字符串的(l,r)赋值给str1 
    	for(int i=l; i<=r; i++) {
    		str1[i-l]=str[i];
    	}
    	str1[r-l+1]='\0';
    	return ;
    }
    int main() {
    	int n;
    	while(~scanf("%d",&n)&&n) {
    		scanf("%d",&n);
    		int Min=INF,pos;
    		for(int i=1; i<=n; i++) {
    			scanf("%s",s[i]);
    			if(strlen(s[i])<Min) {    //找出最短母串 
    				Min=strlen(s[i]);
    				pos=i;
    			}
    		}
    		int Max=0;
    		int l=strlen(s[pos]);
    		int left,right;
    		for(int i=0; i<l; i++) {   //枚举母串的每一个子串 
    			for(int j=i; j<l; j++) {
    				if((j-i+1)<Max) continue;   //剪枝 
    				char_(s1,s[pos],i,j);
    				int flag=true;
    				for(int z=1; z<=n; z++) {  //每一个子串和原来的母串进行匹配 
    					if(z==pos) continue;
    					if(exkmp(s[z],s1))
    						continue;
    					flag=false;
    					break;
    				}
    				if(flag) {
    					if(j-i+1==Max){      //记录所有母串的最长公共子串,长度相同的情况下记录字典序最小的子串 
    						for(int z=0;z+left<=right;z++){
    							if(s[pos][z+left]<s[pos][z+i])
    							break;
    							else{
    								if(s[pos][z+left]>s[pos][z+i]){
    									left=i;
    									right=j;
    									break;
    								}
    							}
    						}
    					}
    					if(j-i+1>Max) {
    						left=i;
    						right=j;
    						Max=max(Max,j-i+1);
    					}
    				}
    			}
    		}
    		if(Max==0)
    			printf("IDENTITY LOST\n");
    		else {
    			for(int i=left; i<=right; i++) {
    				printf("%c",s[pos][i]);
    			}
    			printf("\n");
    		}
    	}
    	return 0;
    }

     

    展开全文
  • C#的扩展方法详解

    千次阅读 2018-07-06 10:03:55
    扩展方法被定义为静态方法,但它们是通过实例方法语法进行调用的。 它们的第一个参数指定该方法作用于哪个类型,并且该参数以 this 修饰符为前缀。 扩展方法当然不能破坏面向对象封装的概念,所以只能是访问所扩展类...

    扩展方法被定义为静态方法,但它们是通过实例方法语法进行调用的。 它们的第一个参数指定该方法作用于哪个类型,并且该参数以 this 修饰符为前缀。 扩展方法当然不能破坏面向对象封装的概念,所以只能是访问所扩展类的public成员。
      扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样进行调用。
    C#扩展方法第一个参数指定该方法作用于哪个类型,并且该参数以 this 修饰符为前缀。
    扩展方法的目的就是为一个现有类型添加一个方法,现有类型既可以是int,string等数据类型,也可以是自定义的数据类型。
    为数据类型的添加一个方法的理解:一般来说,int数据类型有个Tostring的方法,就是把int 数据转换为字符串的类型,比如现在我们想在转换成字符串的时候还添加一点东西,比如增加一个字符 a .那么之前的Tostring就不好使了,因为它只是它我们的int数据转换为string类型的,却并不能添加一个字母 a.所以这就要用到所谓的扩展方法了。
    首先我们看一个给现有的类型增加一个扩展方法。
    我们想给string 类型增加一个Add方法,该方法的作用是给字符串增加一个字母a.


    实例1:

    1. //必须是静态类才可以添加扩展方法
    2. Static class Program
    3. {
    4. static void Main(string[] args)
    5. {
    6. string str = "quzijing";
    7. //注意调用扩展方法,必须用对象来调用
    8. string Newstr = str.Add();
    9. Console.WriteLine(Newstr);
    10. Console.ReadKey();
    11. }
    12. //声明扩展方法
    13. //扩展方法必须是静态的,Add有三个参数
    14. //this 必须有,string表示我要扩展的类型,stringName表示对象名
    15. //三个参数this和扩展的类型必不可少,对象名可以自己随意取如果需要传递参数,//再增加一个变量即可
    16. public static string Add(this string stringName)
    17. {
    18. return stringName+"a";
    19. }
    20. }</span>

    我们再来尝试给我们自定义的类型增加一个扩展方法,并增加一个传递的参数。

    实例2:

    首先我们声明一个Student类,它包含了两个方法StuInfo,getStuInfo.实例代码如下:

    1. public class Student
    2. {
    3. public string StuInfo()
    4. {
    5. return "学生基本信息";
    6. }
    7. public string getStuInfo(string stuName, string stuNum)
    8. {
    9. return string.Format("学生信息:\n" + "姓名:{0} \n" + "学号:{1}", stuName, stuNum);
    10. }
    11. }</span>

    之后我们再声明一个名为ExtensionStudentInfo的静态类,注意必须为静态

    这个类的作用就是包含一些我们想要扩展的方法,在此我们声明两个Student类型的扩展方法,Student类型为我们自定义的类型。示例代码如下:

    1. public static class ExtensionStudentInfo
    2. {
    3. //声明扩展方法
    4. //要扩展的方法必须是静态的方法,Add有三个参数
    5. //this 必须有,string表示我要扩展的类型,stringName表示对象名
    6. //三个参数this和扩展的类型必不可少,对象名可以自己随意取如果需要传递参数,再增加一个变量即可
    7. public static string ExtensionStuInfo(this Student stuName)
    8. {
    9. return stuName.StuInfo();
    10. }
    11. //声明扩展方法
    12. //要扩展的方法必须是静态的方法,Add有三个参数
    13. //this 必须有,string表示我要扩展的类型,stringName表示对象名
    14. //三个参数this和扩展的类型必不可少,对象名可以自己随意取如果需要传递参数,在此我们增加了两个string类型的参数
    15. public static string ExtensionGetStuInfo(this Student student, string stuname, string stunum)
    16. {
    17. return student.getStuInfo(stuname, stunum)+"\n读取完毕";
    18. }
    19. }</span>

    以上的工作做完之后便可以使用我们的扩展方法了,注意必须要用对象来调用扩展方法。
    1. static void Main(string[] args)
    2. {
    3. Student newstudent = new Student();
    4. //要使用对象调用我们的扩展方法
    5. string stuinfo = newstudent.ExtensionStuInfo();
    6. Console.WriteLine(stuinfo);
    7. //要使用对象调用我们的扩展方法
    8. string stuinformation = newstudent.ExtensionGetStuInfo("quzijing", "20081766");
    9. Console.WriteLine(stuinformation);
    10. Console.ReadKey();
    11. }</span>

    实例3、使用TagBuilder类创建扩展方法

    上面自定义的Span()方法十分简单, 但是有时候我们要构造具有复杂结构的Html元素, 如果用字符串拼接的方法就有些笨拙.

    ASP.NET MVC框架提供了一个帮助我们构造Html元素的类:TagBuilder

    TagBuilder类有如下方法帮助我们构建Html控件字符串:

    方法名称用途
    AddCssClass()添加class=””属性
    GenerateId()添加Id,  会将Id名称中的"."替换为IdAttributeDotReplacement 属性值的字符.默认替换成"_"
    MergeAttribute()添加一个属性,有多种重载方法.
    SetInnerText()设置标签内容, 如果标签中没有再嵌套标签,则与设置InnerHTML 属性获得的效果相同.
    ToString()输出Html标签的字符串, 带有一个参数的重载可以设置标签的输出形式为以下枚举值:
    • TagRenderMode.Normal -- 有开始和结束标签
    • TagRenderMode.StartTag -- 只有开始标签
    • TagRenderMode.EndTag -- 只有结尾标签
    • TagRenderMode.SelfClosing -- 单标签形式,如<br/>

    同时一个TagBuilder还有下列关键属性:

    属性名称用途
    AttributesTag的所有属性
    IdAttributeDotReplacement添加Id时替换"."的目标字符
    InnerHTMLTag的内部HTML内容
    TagNameHtml标签名, TagBuilder只有带一个参数-TagName的构造函数.所以TagName是必填属性
    下面在添加一个自定义的HtmlHelper类扩展方法,同样是输出一个<Span>标签:

    1. public static string Span(this HtmlHelper helper, string id, string text, string css, object htmlAttributes)
    2. {
    3. //创意某一个Tag的TagBuilder
    4. var builder = new TagBuilder("span");
    5. //创建Id,注意要先设置IdAttributeDotReplacement属性后再执行GenerateId方法.
    6. builder.IdAttributeDotReplacement = "-";
    7. builder.GenerateId(id);
    8. //添加属性
    9. builder.MergeAttributes(new RouteValueDictionary(htmlAttributes));
    10. //添加样式
    11. builder.AddCssClass(css);
    12. //或者用下面这句的形式也可以: builder.MergeAttribute("class", css);
    13. //添加内容,以下两种方式均可
    14. //builder.InnerHtml = text;
    15. builder.SetInnerText(text);
    16. //输出控件
    17. return builder.ToString(TagRenderMode.Normal);
    18. }</span>

    在页面上,调用这个方法:

    <% =Html.Span("span.test", "使用TagBuilder帮助构建扩展方法", "ColorRed", new { style="font-size:15px;" })%>

    生成的Html代码为:

    <span id="span-test" class="ColorRed" style="font-size: 15px;">使用TagBuilder帮助构建扩展方法</span>

    实例4

    (1)、扩展方法


    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5. using System.Text.RegularExpressions;
    6. //声明扩展方法的步骤:类必须是static,方法是static,
    7. //第一个参数是被扩展的对象,前面标注this。
    8. //使用扩展方法的时候必须保证扩展方法类已经在当前代码中using
    9. namespace 扩展方法
    10. {
    11. //扩展方法必须是静态的
    12. public static class StringHelper
    13. {
    14. //扩展方法必须是静态的,第一个参数必须加上this
    15. public static bool IsEmail(this string _input)
    16. {
    17. return Regex.IsMatch(_input, @"^\\w+@\\w+\\.\\w+$");
    18. }
    19. //带多个参数的扩展方法
    20. //在原始字符串前后加上指定的字符
    21. public static string Quot(this string _input, string _quot)
    22. {
    23. return _quot + _input + _quot;
    24. }
    25. }
    26. }
    27. </span>

    (2)、使用方法


    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5. namespace 扩展方法
    6. {
    7. class Program
    8. {
    9. static void Main(string[] args)
    10. {
    11. string _myEmail = "abc@163.com";
    12. //这里就可以直接使用string类的扩展方法IsEmail了
    13. Console.WriteLine(_myEmail.IsEmail());
    14. //调用接收参数的扩展方法
    15. Console.WriteLine(_myEmail.Quot("!"));
    16. Console.ReadLine();
    17. }
    18. }
    19. }
    20. </span>

    总结:

    在我们的编程生涯中我们要使用很多很多类库,这些类库有的是我们自己开发的,我们有她的代码,有的是第三方发布的,我们不仅没有他们的代码,连看的机会都没有。

    作为.net程序员,我们每天都要和BCL(Base Class Linbrary)打交道。无疑,BCL做为一个年轻的框架类库,她是成功的,但是还有一些时候我们还是得写一些”Helper”方法来扩展类库,由于我们不能修改类库的源代码,我们只有写一个个的静态类。虽然在使用上也算方便,但作为追求完美的程序员来说总有些不雅。 现在我就碰到这样的事情,前两天奉命写一个从XML文件加载Chart图的设置的方法,从XML加载数据绑定到对象上,这肯定是反射的用武之地了。我经常需要写一些根据对象属性名字来判断这个对象是否有这个属性或者根据属性名获取该属性的值。还是按照平常一样,我很快写了一个PropertyHelper,里面有两个静态方法:HasProperty,GetValueByName。

    PropertyHelper.HasProperty(point, "X"),如此的调用也还过得去,不过在C# 3.0微软为我们提供了扩展方法。现在我们可以直接这样调用了point.HasProperty(“X”);看看我是如何实现这个扩展方法的?

    1. public static class PropertyExtension
    2. {
    3. public static object GetValueByName(this object self, string propertyName)
    4. {
    5. if (self == null)
    6. {
    7. return self ;
    8. }
    9. Type t = self.GetType();
    10. PropertyInfo p = t.GetProperty(propertyName);
    11. return p.GetValue(self, null);
    12. }
    13. }</span>

    我给object类型添加了一个扩展方法,在.net里所有的类都继承自object,那所有的类都默认的拥有这个方法了,真方便,呵呵。

    注意到和普通的静态方法有何差别?在这个方法的第一个参数前面多了一个this关键字。

    扩展方法:

    1 方法所在的类必须是静态的

    2 方法也必须是静态的

    3 方法的第一个参数必须是你要扩展的那个类型,比如你要给int扩展一个方法,那么第一个参数就必须是int。

    4 在第一个参数前面还需要有一个this关键字。

    按照上面的步骤写你就得到了一个“扩展方法”,你可以像调用这个类的原生方法那样去调用它:

    string str = "abc";
    object len = str.GetValueByName("Length");

    好像string类型现在有了GetValueByName这个方法一样,但实际上string并没有这样一个方法。那这又是为什么呢?是我们可爱的编译器在其中做了手脚。为了避开编译器的干扰,我们来直接欣赏MSIL代码:

    L_0008: ldstr "Length"
    L_000d: call object TestLambda.PropertyExtension::GetValueByName(objectstring)

    从MSIL中我们可以看出,这段代码编译后和调用静态方法没有任何的差别(从call指令来看,这是在调用一个静态方法)。

    从这里可以知道扩展方法即可以使用实例调用的方式也可以直接使用静态类调用的方式:

    str.GetValueByName("Length");

    PropertyExtension.GetValueByName(str,"Length");

    下面将对扩展方法做一些细节的介绍:

    Visual Studio 2008对扩展方法有智能感知的支持,如下图:

    在方法的图标上有一个与其他的都不相同,他的突变下面还带有一个蓝色的向下的箭头,这就表明这个方法是一个扩展方法。

    下面是对编写扩展方法要注意的几个原则(当然,仁者见仁、智者见智,这也是一家之言):

    扩展方法有就近原则,也就是如果在你的程序里有两个一模一样的扩展方法,一个和你的使用类是处于同一命名空间里,另外一个处于别的命名空间里,这个时候会优先使用同一命名空间里的扩展方法,也就是说“血缘关系”越近,越被青睐。

    很多人看到扩展方法也许眼里冒出金光,以后在设计的时候不管三七二十一,反正可以扩展。还有一些人会对类任意扩展,将以前一些作为”Helper”的方法统统使用扩展方法代替,注意的是扩展方法有“污染性”,所以我觉得在扩展的时候还是想想,是不是值得这样扩展。

    在扩展的时候也不要对比较高层的类进行扩展,像我上面对object的扩展我觉得就是不可取的,object是所有类的基类,一经扩展,所有的类都被“污染”了。


    展开全文
  • es6 扩展运算符 三个点(...)

    万次阅读 多人点赞 2018-03-21 09:20:04
    1 含义扩展运算符( spread )是三个点(...)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列。console.log(...[1, 2, 3]) // 1 2 3 console.log(1, ...[2, 3, 4], 5) // 1 2 3 4 5 [...document....
  • 浏览器辅助神器油猴Tampermonkey的安装使用教程

    万次阅读 多人点赞 2020-08-08 20:27:55
    Tampermonkey是一款基于浏览器的神奇插件,在国内称为油猴,开发者可以在上面开发满足自己需求的各类浏览器应用脚本。不过经过全球各地无数开发者数年的积累现在其官网已经有一大把的优秀的现成脚本,完全可以满足...
  • 扩展和字扩展

    万次阅读 2017-07-26 18:55:00
    字位扩展 存储信息一般是存储在存储器(ROM、RAM)上的 。在实际应用中,经常出现一片ROM或RAM芯片不能满足对存储器容量需求的情况,这就需要用若干片ROM或RAM组合起来 形成一个存储容量更大的存储器。而组合方式有...
  • 查看php已安装扩展命令

    万次阅读 2013-09-11 12:56:00
    php -m
  • chrome浏览器中有很多有用的扩展程序, 但是可能因为长城防火墙我们不能直接去扩展程序商店进行下载获取, 如果我们自己电脑上已经通过某种方式添加了扩展程序, 想把它移植到其他没有翻墙或者压根没有网的电脑上去...
  • CAN2.0的标准帧和扩展帧格式

    万次阅读 2017-12-21 15:33:57
  • 符号扩展和无符号扩展

    万次阅读 多人点赞 2017-06-18 21:28:18
    MIPS32 指令集架构中,经常会有指令需要将其中的立即数进行符号扩展,或者无符号扩展,一般都是都是将n位立即数扩展为32位。 无符号扩展:直接将扩展后的数据的高(32-n)位置为0。符号扩展:将扩展后的数据的高(32...
  • 在打开一个word时,报错如下: Word无法打开该文件,因为文件格式与文件扩展名不匹配 解决办法: 更改扩展名,我的word这里扩展名是.docx,改为.doc后,可以正常打开了。
  • 查看指定的表空间是否为自动扩展SQL> select file_name,autoextensible,increment_by from dba_data_files where tablespace_name = '表空间名'; 如果不是自动扩展想修改为自动扩展的话需要操作SQL> alter ...
  • windows C盘 增加容量 不能扩展

    万次阅读 2017-10-25 14:08:12
    扩展C盘,需要,查看 C盘右边的盘是否 是 ‘空闲磁盘’,这样的 如果不是,就需要把 C盘 右边的盘(我自己右边是D盘,现在把内容备份到其他盘后,格式化了D磁盘) 格式化;-------注意备份; 然后,就可以 ...
  • 有时候刚下载的Chrome浏览器,无法通过拖拽方式添加扩展程序时(提示“无法从该网站添加应用、扩展程序和用户脚本”),检查下扩展程序页面chrome://extensions/,开发者模式是否开启。  若未开启,则先开启...
  • 扩展与字扩展

    万次阅读 2014-07-28 10:46:15
    1.位扩充:当使用的存储器芯片单元数目符合要求,但每单元的位数较少时,需要进行这种扩充。例如,使用4164(64K*1)扩充64KB存储系统,就需要进行位扩充。  连接示意图如下所示: ... 如图显示的是将两片64K*4...
  • 有的时候打开xls文档时,会提示“文件格式和扩展名不匹配。文件可能已损坏或不安全。除非您信任其来源,否则请勿打开。是否仍要打开它?” 格式与文件扩展名不一致的问题,尝试下面两种方法解决:  格式与文件扩展...
  • 用2007或2010打开.xls格式的excel文件,有时会出现下面这样的提示:您尝试打开的文件**.xls的格式与文件扩展名指定的格式不一致。即格式与文件扩展名不一致。单击“是”,打开后的文件出现乱码问题。  ...
  • IDM 扩展安装版本冲突解决(Chrome尝试对扩展程序进行降级处理) 本人最近折腾了一下IDM,发现IDM扩展安装不上Chrome 的扩展,版本不统一导致Chrome 浏览器显示已经对扩展程序进行降级处理,那我在看完网上的解决...
  • 单片机扩展IO口

    万次阅读 2016-11-27 19:47:28
    单片机如何扩展IO口? 首先我们先讲讲为什么要扩展IO口。在我们使用51单片机的时候,有时候会出现IO口不够用的情况。比如键盘!这个时候IO口的资源就十分有限了。 按键是我们常用的器件,做某些东西的时候又不能缺少...
1 2 3 4 5 ... 20
收藏数 3,030,003
精华内容 1,212,001
关键字:

扩展