使用马尔可夫链构建文本生成器

中将介绍一个流行的机器学习项目——文本生成器,你将了解如何构建文本生成器,并了解如何实现马尔可夫链以实现更快的预测模型。

文本生成器简介

文本生成在各个行业都很受欢迎,特别是在移动、应用和数据科学领域。甚至新闻界也使用文本生成来辅助写作过程。

在日常生活中都会接触到一些文本生成技术,文本补全、搜索建议,Smart Compose,聊天机器人都是应用的例子,

本文将使用马尔可夫链构建一个文本生成器。这将是一个基于字符的模型,它接受链的前一个字符并生成序列中的下一个字母。

通过使用样例单词训练我们的程序,文本生成器将学习常见的字符顺序模式。然后,文本生成器将把这些模式应用到输入,即一个不完整的单词,并输出完成该单词的概率最高的字符。

文本生成是自然语言处理的一个分支,它根据之前观察到的语言模式预测并生成下一个字符。

在没有机器学习之前,NLP是通过创建一个包含英语中所有单词的表,并将传递的字符串与现有的单词匹配来进行文字生成的。这种方法有两个问题。

  • 搜索成千上万个单词会非常慢。
  • 生成器只能补全它以前见过的单词。

机器学习和深度学习的出现,使得NLP允许我们大幅减少运行时并增加通用性,因为生成器可以完成它以前从未遇到过的单词。如果需要NLP可以扩展到预测单词、短语或句子!

对于这个项目,我们将专门使用马尔可夫链来完成。马尔可夫过程是许多涉及书面语言和模拟复杂分布样本的自然语言处理项目的基础。

马尔可夫过程是非常强大的,以至于它们只需要一个示例文档就可以用来生成表面上看起来真实的文本。

什么是马尔可夫链?

马尔可夫链是一种随机过程,它为一系列事件建模,其中每个事件的概率取决于前一个事件的状态。该模型有一组有限的状态,从一个状态移动到另一个状态的条件概率是固定的。

每次转移的概率只取决于模型的前一个状态,而不是事件的整个历史。

例如,假设想要构建一个马尔可夫链模型来预测天气。

在这个模型中我们有两种状态,晴天或雨天。如果我们今天一直处于晴朗的状态,明天就有更高的概率(70%)是晴天。雨也是如此;如果已经下过雨,很可能还会继续下雨。

但是天气会改变状态是有可能的(30%),所以我们也将其包含在我们的马尔可夫链模型中。

马尔可夫链是我们这个文本生成器的完美模型,因为我们的模型将仅使用前一个字符预测下一个字符。使用马尔可夫链的优点是,它是准确的,内存少(只存储1个以前的状态)并且执行速度快。

文本生成的实现

这里将通过6个步骤完成文本生成器:

  1. 生成查找表:创建表来记录词频
  2. 将频率转换为概率:将我们的发现转换为可用的形式
  3. 加载数据集:加载并利用一个训练集
  4. 构建马尔可夫链:使用概率为每个单词和字符创建链
  5. 对数据进行采样:创建一个函数对语料库的各个部分进行采样
  6. 生成文本:测试我们的模型

1、生成查找表

首先,我们将创建一个表,记录训练语料库中每个字符状态的出现情况。从训练语料库中保存最后的' K '字符和' K+1 '字符,并将它们保存在一个查找表中。

例如,想象我们的训练语料库包含,“the man was, they, then, the, the”。那么单词的出现次数为:

  • “the” — 3
  • “then” — 1
  • “they” — 1
  • “man” — 1

下面是查找表中的结果:

在上面的例子中,我们取K = 3,表示将一次考虑3个字符,并将下一个字符(K+1)作为输出字符。在上面的查找表中将单词(X)作为字符,将输出字符(Y)作为单个空格(" "),因为第一个the后面没有单词了。此外还计算了这个序列在数据集中出现的次数,在本例中为3次。

这样就生成了语料库中的每个单词的数据,也就是生成所有可能的X和Y对。

下面是我们如何在代码中生成查找表:

 def generateTable(data,k=4):
 
 T = {}
     for i in range(len(data)-k):
         X = data[i:i+k]
         Y = data[i+k]
         #print("X  %s and Y %s  "%(X,Y))
         if T.get(X) is None:
             T[X] = {}
             T[X][Y] = 1
         else:
             if T[X].get(Y) is None:
                 T[X][Y] = 1
             else:
                 T[X][Y] += 1
     return T
 T = generateTable("hello hello helli")
 print(T)
 
 #{'llo ': {'h': 2}, 'ello': {' ': 2}, 'o he': {'l': 2}, 'lo h': {'e': 2}, 'hell': {'i': 1, 'o': 2}, ' hel': {'l': 2}}

代码的简单解释:

在第3行,创建了一个字典,它将存储X及其对应的Y和频率值。第9行到第17行,检查X和Y的出现情况,如果查找字典中已经有X和Y对,那么只需将其增加1。

2、将频率转换为概率

一旦我们有了这个表和出现的次数,就可以得到在给定x出现之后出现Y的概率。公式是:

例如如果X = the, Y = n,我们的公式是这样的:

当X =the时Y = n的频率:2,表中总频率:8,因此:P = 2/8= 0.125= 12.5%

以下是我们如何应用这个公式将查找表转换为马尔科夫链可用的概率:

 def convertFreqIntoProb(T):     
     for kx in T.keys():
         s = float(sum(T[kx].values()))
         for k in T[kx].keys():
             T[kx][k] = T[kx][k]/s
 
     return T
 
 T = convertFreqIntoProb(T)
 print(T)
 #{'llo ': {'h': 1.0}, 'ello': {' ': 1.0}, 'o he': {'l': 1.0}, 'lo h': {'e': 1.0}, 'hell': {'i': 0.3333333333333333, 'o': 0.6666666666666666}, ' hel': {'l': 1.0}}

简单解释:

把一个特定键的频率值加起来,然后把这个键的每个频率值除以这个加起来的值,就得到了概率。

3、加载数据集

接下来将加载真正的训练语料库。可以使用任何想要的长文本(.txt)文档。

为了简单起见将使用一个政治演讲来提供足够的词汇来教授我们的模型。

 text_path = "train_corpus.txt"
 def load_text(filename):
     with open(filename,encoding='utf8') as f:
         return f.read().lower()
 
 text = load_text(text_path)
 print('Loaded the dataset.')

这个数据集可以为我们这个样例的项目提供足够的事件,从而做出合理准确的预测。与所有机器学习一样,更大的训练语料库将产生更准确的预测。

4、建立马尔可夫链

让我们构建马尔可夫链,并将概率与每个字符联系起来。这里将使用在第1步和第2步中创建的generateTable()和convertFreqIntoProb()函数来构建马尔可夫模型。

 def MarkovChain(text,k=4):
     T = generateTable(text,k)
     T = convertFreqIntoProb(T)
     return T
 
 model = MarkovChain(text)

第1行,创建了一个方法来生成马尔可夫模型。该方法接受文本语料库和K值,K值是告诉马尔可夫模型考虑K个字符并预测下一个字符的值。第2行,通过向方法generateTable()提供文本语料库和K来生成查找表,该方法是我们在上一节中创建的。第3行,使用convertFreqIntoProb()方法将频率转换为概率值,该方法也是我们在上一课中创建的。

5、文本采样

创建一个抽样函数,它使用未完成的单词(ctx)、第4步中的马尔可夫链模型(模型)和用于形成单词基的字符数量(k)。

我们将使用这个函数对传递的上下文进行采样,并返回下一个可能的字符,并判断它是正确的字符的概率。

 import numpy as np
 
 def sample_next(ctx,model,k):
 
     ctx = ctx[-k:]
     if model.get(ctx) is None:
         return " "
     possible_Chars = list(model[ctx].keys())
     possible_values = list(model[ctx].values())
 
     print(possible_Chars)
     print(possible_values)
 
     return np.random.choice(possible_Chars,p=possible_values)
 
 sample_next("commo",model,4)
 
 #['n']
 #[1.0]

代码解释:

函数sample_next接受三个参数:ctx、model和k的值。

ctx是用来生成一些新文本的文本。但是这里只有ctx中的最后K个字符会被模型用来预测序列中的下一个字符。例如,我们传递common,K = 4,模型用来生成下一个字符的文本是是ommo,因为马尔可夫模型只使用以前的历史。

在第 9 行和第 10 行,打印了可能的字符及其概率值,因为这些字符也存在于我们的模型中。我们得到下一个预测字符为n,其概率为1.0。因为 commo 这个词在生成下一个字符后更可能是更常见的

在第12行,我们根据上面讨论的概率值返回一个字符。

6、生成文本

最后结合上述所有函数来生成一些文本。

 def generateText(starting_sent,k=4,maxLen=1000):
 
 sentence = starting_sent
     ctx = starting_sent[-k:]
 
     for ix in range(maxLen):
         next_prediction = sample_next(ctx,model,k)
         sentence += next_prediction
         ctx = sentence[-k:]
     return sentence
 
 print("Function Created Successfully!")
 
 text = generateText("dear",k=4,maxLen=2000)
 print(text)

结果如下:

 dear country brought new consciousness. i heartily great service of their lives, our country, many of tricoloring a color flag on their lives independence today.my devoted to be oppression of independence.these day the obc common many country, millions of oppression of massacrifice of indian whom everest.
 my dear country is not in the sevents went was demanding and nights by plowing in the message of the country is crossed, oppressed, women, to overcrowding for years of the south, it is like the ashok chakra of constitutional states crossed, deprived, oppressions of freedom, i bow my heart to proud of our country.my dear country, millions under to be a hundred years of the south, it is going their heroes.

上面的函数接受三个参数:生成文本的起始词、K的值以及需要文本的最大字符长度。运行代码将得到一个以“dear”开头的2000个字符的文本。

虽然这段讲话可能没有太多意义,但这些词都是完整的,通常模仿了单词中熟悉的模式。

接下来要学什么

这是一个简单的文本生成项目。通过这个项目可以了解自然语言处理和马尔可夫链实际工作模式,可以在继续您的深度学习之旅时使用。

本文只是为了介绍马尔可夫链来进行的实验项目,因为它不会再实际应用中起到任何的作用,如果你想获得更好的文本生成效果,那么请学习GPT-3这样的工具,因为:别问,问就是GPT-3?

作者:Educative Team

本文转载于网络 如有侵权请联系删除

相关文章

  • 银行风控模型

    大家好,又见面了,我是你们的朋友全栈君。风控催生原因对于银行来说,现今互联网贷款和信用卡办理面临的主要难题是数据和风控。站在银行或金融机构角度,自然而然是想获得更多的信息和数据,但是在收集数据这方面又是比较无力的。加上当下的发展趋势,消费贷以及贷款审批速度都要求快。如何在快的的过程中对客户进行一个全面的审查,得出一个合理的结果呢?如果没有详细的数据对客户进行评估,这势必会提高放贷的风险。风控概述所谓风控,是指多银行贷款资金的风险把控,是对风险的一个评估。主要体现在两个方面:1、贷款前的风险评估,主要针对申请贷款或者信用卡的用户,银行风控中心会对你的个人情况和征信进行调查核实,从而分析是否可以将贷款发放给你,发放多少额度。2、放款后的风险监控,发放贷款以后银行也会定期的对贷款人的情况进行跟踪了解,能够及时的掌握资金的流向性,保证资金能够安全回收。另外在理财投资过程中也是会运用到风控体系,投资者可以向银行申请对自己所投资的理财产品进行风险评估,选择比较有保障的理财方式。整体思路在业务开展初期需要引入海量跨行业数据作为风控模型的基础,建立全面的风险管理体系。并在自有数据不足的情况下,建立反欺

  • 安卓测试常用的 ADB 命令

    一:工作环境:   adb的工作方式比较特殊采用监听SocketTCP5554等端口的方式让IDE和Qemu通讯,默认情况下adb会daemon相关的网络端口,所以当我们运行Eclipse时adb进程就会自动运行。  1.通过adb可以轻松的执行LinuxShell命令,如adbshelldir就是列举目录,在Linux中根目录为/而不是Windows上的C盘、D盘。  2.安装apk程序到模拟器则执行adbinstallandroid123.apk,这样名为android123的安装包就会安装到Android模拟器中,前提是android123.apk文件需要放到SDK/Tools目录下。  3.向emulator传送文件,使用adbpushandroid123.txt/tmp/android123.txt命令可以把SDK/Tools下的android123.txt文件传输到模拟器的/tmp/文件夹中,需要注意的是/tmp/文件夹中内容会在Android模拟器重新启动时清空。  4.从Android仿真器中回传文件到电脑 通过adbpull/tmp/android123.txtand

  • 高级Python工程师教你如何正确写代码

    我接手的第一样东西就是ReactUI。我们有一个主要组件,它容纳了其他所有组件。我喜欢在代码中加入一点幽默感,我想把它命名为GodComponent。在codereview的时候,我才明白为什么命名是一件很难的事情。计算机科学有两个难点:缓存失效,给变量命名,以及差一错误。我经手的每一段代码都带有隐喻意。GodComponent?那时用来盛放所有那些我不知道该放到哪里的的烂代码的。它包罗万象。如果我将一个变量命名为LayoutComponent,未来我会知道,它所做的只是规划布局,而不涉及任何状态。我发现的另一个好处是:如果它看起来太大了,就像包含大量业务逻辑的LayoutComponent一样,我知道是时候重构了,因为业务逻辑不应当属于那部分。而如果使用GodComponent这个名称,那对里面的业务逻辑就不会产生任何影响。命名你的集群?根据在它上面运行服务来命名是个好主意,可是你以后还可能会在上面运行其他东西。最终,我们是用团队名称来命名的。对于函数来说也是一样。doEverything()是一个可怕的名字,这会产生很多后果。如果这个函数可以完成所有操作,那么测试这个函数的特定部分

  • AWS Parameter Store经验总结

    ParameterStore用来存储配置的信息还是蛮方便的,记录一下这方面的经验。AWSCLIvalue值有httpurl时会尝试解析这个urlawsssmput-parameter--name"/my-service/qa/service_url"--typeString--overwrite--regionus-east-1--value"https://myservice/api/"复制这条命令执行的时候会去访问https://myservice/api/,会出现各种问题。项目上这个值是内网的地址,必须要通过代理才能访问,执行这条命令后就死在那里了。具体可以通过aws--debugssm这样去查看。 在github上面有人提到了同样的问题,据说这还是一个“特性”。解决方案是将这个关闭:awsconfiguresetcli_follow_urlparamfalse复制命令行小工具如果想要知道一个路径下面所有的值,在AWS的console界面里面非常的难找。要做数据迁移的时候非常的麻烦。在网上找到一个叫做aws-ssm-commander的小工

  • [Glide4源码解析系列] — 1.Glide初始化

    Glide一、前言在众多的图片加载框架中,Glide是Google推荐的,并在自家的项目中大量使用的一个非常强大的框架,专注于平滑滚动,并且还提供Gif,本地Vedio首帧的解码和显示。Glide提供了非常便捷的链式调用接口,以及丰富的拓展和自定义功能,开发者可以非常简单地对框架进行配置和图片再加工。如今Gilde已经更新到4.x,了解其源码对更好的使用Glide,以及学习相关的图片处理技术,学习更优雅的编码会有很大的帮助。不得不说,Glide整个框架的极其复杂的,特别是在对资源的转换和解码过程中,涉及了许多的嵌套循环,同时也使用了大量的工厂模式用于生产转换模块,编码模块,解码模块等,笔者在阅读过程中,多次迷失在茫茫的代码流中。为此,萌生了将对Glide的理解记录成文的想法,借以理清思路,也希望这一系列的文章可以帮助到无论是了解,还是准备阅读Glide源码的你,稍微理清一些思路。如有不对的地方,欢迎指正~那么接下来,我们就先看看Glide是如何进行框架初始化的。注意:本文源码版本为v4.6.1,不同版本可能存在一些差异! 二、Glide.with发生了什么?1.Glide单例的加载使用

  • 针对nginx,来具体聊聊正向代理与反向代理

    先来说说什么是代理服务器? 所谓代理服务器就是位于发起请求的客户端与原始服务器端之间的一台跳板服务器,正向代理可以隐藏客户端,反向代理可以隐藏原始服务器。 如果你对这句话还不是特别了解,那么接下来我们就详细聊聊正向代理和反向代理的区别。 正向代理 假如你常用的电脑想通过google搜索一个关键词“helloworld”,但是国内现在不允许访问google一下,所以你访问不了。 但,假如你现在有一台国外服务器可以访问google,于是出现了这种情况: 于是你想到,我的电脑直接远程控制这台服务器就能google啦,虽然有点麻烦。时间久了你就可能觉得每次远程时间挺累的事情,于是你又想,能不能我的电脑访问这台服务器,然后这台服务器去帮我请求google,然后把请求到的数据返回给我。设想是这样的: 这个过程其实就是正向代理!! 那么问题来了,怎么才能让我的这台服务器接受在我搜索helloworld的时候自动帮我去访问google呢?你想到nginx好像有正向代理的功能,于是按照了nginx,并配置相关信息: 其中:resolver配置DNS解析IP地址,比如GooglePublicDNS。(图例

  • python数据库-MySQL数据库的增删改查基本操作(49)

    一、数据库基础表table:数据是保存在表内,保存在一个表内的数据,应该具有相同的数据格式行:行用于记录数据记录:行内的数据列:列用于规定数据格式字段:数据的某个列主键:唯一地标识表中的某一条记录,不能空,不能重复二、数据库的数据类型1、数字类型整数:tinyint、smallint、mediumint、int、bigint 浮点数:float、double、real、decimal 日期和时间:date、time、datetime、timestamp、year2、字符串类型字符串:char、varchar 文本:tinytext、text、mediumtext、longtext3、二进制  (可用来存储图片、音乐等):tinyblob、blob、mediumblob、longblob4、列的约束:三、数据库连接  在关于数据库的第一篇文章中就给大家讲了使用Navicat连接数据库的方法,那么这里再给大家讲解一下使用命令连接数据库的方式。  一般在公司开发中,可能会将数据库统一搭建在一台服务器上,所有开发人员共用一个数据库,而不是在自己的电脑中配置一个数据库,远程连接命令mysql-h

  • 什么是ZooKeeper?

    来源:Java3y(ID:java3y)前言这篇文章来写写我学习ZooKeeper的笔记,如果有错的地方希望大家可以在评论区指出。一、什么是ZooKeeper从上面我们也可以发现,好像哪都有ZooKeeper的身影,那什么是ZooKeeper呢?我们先去官网看看介绍:官网对ZooKeeper的介绍官网还有另一段话:ZooKeeper:ADistributedCoordinationServiceforDistributedApplications相比于官网的介绍,我其实更喜欢Wiki中对ZooKeeper的介绍:wiki介绍ZooKeeper(留下不懂英语的泪水)我简单概括一下:ZooKeeper主要服务于分布式系统,可以用ZooKeeper来做:统一配置管理、统一命名服务、分布式锁、集群管理。使用分布式系统就无法避免对节点管理的问题(需要实时感知节点的状态、对节点进行统一管理等等),而由于这些问题处理起来可能相对麻烦和提高了系统的复杂性,ZooKeeper作为一个能够通用解决这些问题的中间件就应运而生了。二、为什么ZooKeeper能干这么多?从上面我们可以知道,可以用ZooKeep

  • 聊聊flink的AbstractTtlState

    序本文主要研究一下flink的AbstractTtlStateInternalKvStateflink-runtime_2.11-1.7.0-sources.jar!/org/apache/flink/runtime/state/internal/InternalKvState.java/** *The{@codeInternalKvState}istherootoftheinternalstatetypehierarchy,similartothe *{@linkState}beingtherootofthepublicAPIstatehierarchy. * *<p>Theinternalstateclassesgiveaccesstothenamespacegettersandsettersandaccessto *additionalfunctionality,likerawvalueaccessorstatemerging. * *<p>ThepublicAPIstatehierarchyisintendedtobeprogrammedagainstb

  • adb shell 如何选择特定的设备?

    开篇手机冲着电,开着安卓模拟器,想给模拟器发送命令,怎么办呢?怎么办呢?解决之法其实这个一查,stackoverflow或者百度谷歌一大把,比如这个“http://stackoverflow.com/questions/14654718/how-to-use-adb-shell-when-multiple-devices-are-connected-fails-with-error-mor”,不过呢,当然要配图才能更加清晰明了了。下面就看下配图版解答。进入正题:1.adbdevices显示都有哪些设备连接2.adb-semulator-5556shell{command}发送指定命令比如最近在折腾ReactNative,要显示开发者菜需要点击菜单键或者发送inputkeyevent82,那么就可以使用命令:adb-semulator-5556shellinputkeyevent82,如下图: 模拟器也会立刻给我们反应: 3.adb-semulator-5556shell进入shell命令行2中我们是每次发送命令都需要指定是哪个设备,这无疑是非常麻烦的。我们可以先通过adb-s{emu

  • 通用日志

    一、背景为软件开发提供一个现成的、定义良好的、可扩展的日志设施。所谓"现成的"意思为软件开发可以即刻使用,包括API文档、使用实例和库;"定义良好的"表示项目提供良好的使用接口和具有优秀的内部设计;可扩展的意味用户可以进一步扩展功能。关心软件日志的主要有三类用户:开发人员、系统管理人员和系统运行单位。三类用户各有各的日志需求:l开发人员在写代码的时候经常要输出程序的内部状态,目的可以是开发时的调试,或运行时的维护。l系统管理人员需要获取软件的状态数据以便进一步配置系统使其正常和高效运行。l系统运行单位需要软件保存操作日志以便例行检查或秋后算账。虽然三类用户各有各的需求,对于日志设施来说可以归结为以下功能特性:1.日志操作:日志功能是指基本的日志登记操作,是软件系统和日志设施之间的简单接口。软件系统一般只向这些功能传递应用日志信息。2.级别:级别是指软件系统可以分级别地进行日志登记操作。日志设施的级别特性表现为日志操作和设施配置两部分。日志操作的级别表现为软件系统可以指定某次日志登记的级别,设施配置的级别规定了有效的日志操作的最低级别。如果软件系统

  • 根据线性回归模型预测儿童身高

    ​本文已参与「新人创作礼」活动,一起开启掘金创作之路。 理论上,一个人的身高除了随年纪变大而增长之外,在一定程度上还受遗传和饮食习惯以及其他因素的影响,但是饮食等其他因素对身高的影响很难衡量。我们可以把问题简化一下,假定一个人的身高只受年龄、性别、父母身高、祖父母身高,外祖父母身高这几个因素的影响,并假定大致符合线性关系。importcopy importnumpyasnp fromsklearnimportlinear_model #儿童年龄,性别(0女1男),父亲身高,母亲身高,祖父身高,祖母身高,外祖父身高,外祖母身高 x=np.array([[1,0,180,165,175,165,170,165], [3,0,180,165,175,165,173,165], [4,0,180,165,175,165,170,165], [6,0,180,165,175,165,170,165], [8,1,180,165,175,167,170,165], [10,0,180,166,175,165,170,165], [11,0,180,165,175,165,170,165], [1

  • Python学习笔记 for windows 三

    多重继承继承是面向对象编程的一个重要的方式,因为通过继承,子类就可以扩展父类的功能。哺乳类:能跑的哺乳类,能飞的哺乳类;鸟类:能跑的鸟类,能飞的鸟类。classAnimal(object):pass复制classBird(Animal):pass复制classDog(Mammal):pass复制classRunnable(object):defrun(self):print('Running...')复制复制classDog(Mammal,Runnable):pass复制通过多重继承,一个子类就可以同时获得多个父类的所有功能。Mixin在设计类的继承关系时,通常,主线都是单一继承下来的,例如,Ostrich继承自Bird。但是,如果需要“混入”额外的功能,通过多重继承就可以实现,比如,让Ostrich除了继承自Bird外,再同时继承Runnable。这种设计通常称之为Mixin。为了更好地看出继承关系,我们把Runnable和Flyable改为RunnableMixin和FlyableMixin。类似的,你还可以定义出肉食动物CarnivorousMixin和植食动物Herbivore

  • 2015年6月11日晚_修习

    文辞巧者劳而智者忧,无能者无所求,饱食而遨游,泛若不系之舟。春风大雅能容物,秋水文章不染尘。大丈夫当立刀于世,有恩则报,有仇则雪,何必效那田间小儿情状,空谈那些稻香米熟之事。只是世上有那种小贼,可以面对着城门前五步如林枪戟,群骏环峙,众目逡巡,还能够这般施施然走上前来?不为良相,便为良医。爱上一个不该爱的人,把这刹那红颜尽付流水。忘却一个曾经深爱的人,叫那寂寞芳华都化作无缘。杀人不过头点地,得饶人处且饶人。西江月·题溧阳三塔寺张孝祥问讯湖边春色,重来又是三年。东风吹我过湖船,杨柳丝丝拂面。世路如今已惯,此心到处悠然。寒光亭下水连天,飞起沙鸥一片。题秋江独钓图王士祯一蓑一笠一扁舟,一丈丝纶一寸钩。一曲高歌一杯酒,一人独钓一江秋。登金陵凤凰台李白凤凰台上凤凰游,凤去台空江自流。吴宫花草埋幽径,晋代衣冠成古丘。三山半落青天外,二水中分白鹭洲。总为浮云能蔽日,长安不见使人愁。知味·西江月仙剑妙手烹饪百味,炊烟半掩孤星。人生何处不相逢,一饮一啄天定。世态浮云见惯,未解别样浓情,心波已乱意难平,清夜悠悠谁共。 

  • mysql-索引

    一、索引是什么? 索引是帮助MySQL高效获取数据的数据结构。 二、索引能干什么? 索引非常关键,尤其是当表中的数据量越来越大时,索引对于性能的影响愈发重要。索引能够轻易将查询性能提高好几个数量级,总的来说就是可以明显的提高查询效率。 三、索引的分类? 1、从存储结构上来划分:BTree索引(B-Tree或B+Tree索引),Hash索引,full-index全文索引,R-Tree索引。这里所描述的是索引存储时保存的形式, 2、从应用层次来分:普通索引,唯一索引,复合索引 3、根据中数据的物理顺序与键值的逻辑(索引)顺序关系:聚集索引,非聚集索引。 B树B树中,每个结点中关键字从小到大排列B树都取在内存中查询 B-Tree特性 关键字集合分布在整颗树中;任何一个关键字出现且只出现在一个结点中;搜索有可能在非叶子结点结束;其搜索性能等价于在关键字全集内做一次二分查找;自动层次控制; B-Tree搜索原理 B-树的搜索,从根结点开始,对结点内的关键字(有序)序列进行二分查找,如果命中则结束,否则进入查询关键字所属范围的儿子结点;重复,直到所对应的儿子指针为空,或已经是叶子结点;因此,B-T

  • 新春消消乐 题解

    给大家提前拜个早年! 第一档 测试贪心强不强的一档分,如果贪心策略很好的话,能拿到这一档的全部分数。 附上zyz的贪心代码\((40pts)\): #include<bits/stdc++.h> usingnamespacestd; stringstr; map<string,int>Ans; intcalc(strings) { //cout<<s<<'\n'; if(Ans[s])returnAns[s]; inttot[10],maxx=9,temp=0,last=-1; memset(tot,0,sizeoftot); for(inti=0;i<s.size();i++) tot[s[i]-'0']++; for(inti=0;i<10;i++) if(tot[i]>=tot[maxx])maxx=i; intnowmax; for(intnum=0;num<10;num++){ //if(tot[num]!=tot[maxx])continue; if(tot[num]==0)

  • HTML5中的Web Worker技术

      为了让后台程序更好的执行,在HTML5中设计了WebWorker技术。WebWorker的产生主要是考虑到在HTML4中JavaScript Web程序都是以单线程的方式执行的,一旦前面的脚本花费时间过长,后面的程序就会因长期得不到响应而使用户页面操作出现异常。   WebWorker实现的是线程技术,可以使运行在后台的JavaScript独立于其他脚本,从而不会影响页面的性能。   示例: 1<!DOCTYPEhtml> 2<htmllang="en"> 3<head> 4<metacharset="UTF-8"> 5<metaname="viewport"content="width=device-width,initial-scale=1.0"> 6<metahttp-equiv="X-UA-Compatible"content="ie=edge"> 7<title>Document</title> 8</head> 9<body> 10<

  • 【UOJ #46】 【清华集训2014】玄学

    题目描述 巨酱有n副耳机,他把它们摆成了一列,并且由1到n依次编号。每个耳机有一个玄学值,反映了各自的一些不可名状的独特性能。玄学值都是0到m-1间的整数。在外界的作用下(包括但不限于换线、上放、更换电源为核电、让kAc叔叔给它们讲故事),这些耳机的玄学值会发生改变。特别地,巨酱观察发现,每种作用o对应了两个整数ao与bo,在这种作用之后,玄学值原本为x的耳机,其玄学值恰会变成(aox+bo)modm。 巨酱对他手头耳机的表现并不满意,遗憾的是,最近他并不有钱,无法任性,不能赶紧买买买以满足自己。手头紧张的他准备拟定一个相对经济的方案,通过各种作用来改善他手头玩具的性能。具体地说,为了尽快完成方案的制订,巨酱希望自己能高效地完成以下工作: 巨酱想到了一种操作,能让耳机的玄学值由x变为(ax+b)modm,并且他计划对编号为i到j的耳机执行这种操作。巨酱想知道如果将(并且仅将)自己的第i个到第j个计划按顺序付诸行动,编号为k的耳机的玄学值将会变成多少。出于著名算法竞赛选手的矜持,巨酱表示自己才不需要你的帮助。但是如果巨酱真的厌倦了自己的玩具,它们就会被50包邮出给主席。为了不让后者白白捡

  • C++ 子类构造函数初始化列表与基类关系

    抽象基类的派生子类构造函数按照初始化列表的写法怎么也写不对,查资料后记录 要点如下 公有类型派生类不能访问基类私有成员 --但我这里基类没有private成员 为什么要调用父类的构造函数? 构造函数用来初始化类的对象,与父类的其它成员不同,它不能被子类继承(子类可以继承父类所有的成员变量和成员方法,但不继承父类的构造方法)。因此,在创建子类对象时,为了初始化从父类继承来的数据成员,系统需要调用其父类的构造方法。* 派生类构造函数 在创建派生类对象时,先调用基类的构造函数,然后调用派生类的构造函数;撤销对象时,析构函数被调用的顺序则相反。 若派生类中包含对象成员,则派生类的构造函数初始化成员列表中既要列出基类的构造函数也要列出对象的构造函数。派生类定义对象时,先调用基类的构造函数,再调用对象的构造函数,最后调用派生类的构造函数。 #pragmaonce #include<iostream> #include<string> usingnamespacestd; //职工抽象基类 classWorker { public: Worker(){

  • C 单链表

    C单链表(SinglyLinkedList) /* *singly_linked_list.c *单向链表 *sll=singly_linked_list **/ #include<stdio.h> #include<stdlib.h> #include<stdbool.h> /* *节点结构head->|value|next|->... **/ typedefstructsll{ intvalue; structsll*next; }sll; voidinit_sll(sll**head); voidadd_sll_node(sll**head,intvalue); voidadd_sll_nodes(sll**head,intvalues[],intlen); booldel_sll_node(sll**head,intindex); sll*get_sll_node(sll*head,intindex); sll*locate_sll_node(sll*head,intvalue); boolinsert_sll_node(

  • Delphi CreateProcess

    DelphiCreateProcessWIN32API函数CreateProcess用来创建一个新的进程和它的主线程,这个新进程运行指定的可执行文件   2010-12-2717:00:17|  分类: Delphi |  标签: |字号大中小 订阅 CreateProcess百科名片 WIN32API函数CreateProcess用来创建一个新的进程和它的主线程,这个新进程运行指定的可执行文件。 目录 函数原型参数返回值举例说明 C代码 C++代码函数原型参数返回值举例说明 C代码 C++代码展开编辑本段函数原型  BOOLCreateProcess   (   LPCTSTRlpApplicationName,   LPTSTRlpCommandLine,   LPSECURITY_ATTRIBUTESlpProcessAttributes。   LPSECURITY_ATTRIBUTESl

相关推荐

推荐阅读