Terrorshadow


  • 首页

  • 归档

  • 分类

  • 标签

  • 关于

  • 搜索

知识图谱

发表于 2020-06-13

知识图谱


什么是知识图谱


为提高搜索效率,优化搜索质量,2012年,Google首先提出知识图谱这以概念,以知识图谱为底层技术支持的搜索引擎,用户不再需要通过不停的点击链接来获取自己想要的信息,实现智能搜索。


知识图谱定义


知识图谱,是结构化的语义知识库,用于以符号形式描述物理世界中的概念及其相互关系,其基本组成单位是“实体-关系-实体”三元素,以及实体及其相互属性-值对,实体间通过关系相互联结,构成网络的知识结构。
这个定义的含义:

  • 知识图谱本身是一个具有属性的实体通过关系链接而成的网状知识库.从图的角度来看,知识图谱在本质上是一种概念网络,其中的节点表示物理世界的实体(或概念),而实体间的各种语义关系则构成网络中的边.由此,知识图谱是对物理世界的 一种符号表达。
  • 知识图谱的研究价值在于,它是构建在当前Web基础之上的一层覆盖网络(overlay network),借助知识图谱,能够在Web网页之上建立概念间的链接关系,从而以最小的代价将互联网中积累的信息组织起来,成为可以被利用的知识.
  • 知识图谱的应用价值在于,它能够改变现有的信息检索方式,一方面通过推理实现概念检索(相对于现有的字符串模糊匹配方式而言);另一方面以图形化方式向用户展示经过分类整理的结构化知识,从而使人们从人工过滤网页寻找答案的模式中 解脱出来。

知识图谱的架构


1. 知识图谱逻辑架构

数据层

在知识图谱数据层,知识以事务(fact)为单位存储在图数据库,如果以“实体-关系-实体”或者“实体-属性-性质”三元组作为事务的基本表达方式,存储在图数据库中的所有数据将构成庞大的实体关系网络,形成知识的“图谱”。

模式层

模式层是知识图谱的核心,在模式层存储的是经过提炼的知识,通常采用本体库来管理知识图谱的模式曾,借助本体库对公理、规则和约束条件的支持能力来规范实体、关系以及实体的类型和属性等对象之间的联系,本体在知识图谱中的地位相当于知识库的模具,拥有本体库的冗余知识很少。
知识图谱的一般构建结构,知识图谱构建过程从原始数据出发,采用一系列自动或者半自动技术手段,从原始数据中提取出知识,并将其存储到知识库的数据层和模式层的过程。这是一个迭代的过程,根据知识获取的逻辑,每一轮迭代包含三个阶段:信息抽取、知识融合以及知识加工。
知识图谱构建

2. 知识图谱构建

自顶向下构建

所谓自顶向下构建是指借助本体和模式信息,加入到知识库中。

自底向上

所谓自底向上构建,则是借助一定的技术手段,从公开采集的数据中提取出资源模式,选择其中置信度较高的新模式,经过人工审核后,加入知识库中。

3. 知识图谱构建过程

信息抽取

信息抽取是一种自动化地从半结构化和无结构数据中抽取实体、关系以及实体属性等结构化信息的技术。涉及的关键技术包括:实体抽取、关系抽取和属性抽取。

1.实体抽取

指从文本数据集中自动识别出命名实体,实体抽取质量(准确率、召回率)对整个知识获取效率影响极大,是信息抽取最为基础和关键的部分。

2.关系抽取

文本语料经过实体抽取,得到的是一系列离散的命名实体,为了得到语义信息,还需要从相关语料中提取出实体之间的关联关系,通过关系将实体联系起来,形成网状的知识结构。
早期相关研究主要通过人工构造语法和语义规则,这种方法有两个不足:

  • 要求制定规则的人对特定领域有深入理解和认知
  • 制定工作量大,并且难以扩展到其他领域

随后出现了一系列关于实体关系的模型研究:

  • 机器学习方法(统计学)
  • 基于特征向量或核函数的有监督学习方法(缺点需要进行大量的人工标注来确保算法有效性)
  • 半监督、无监督学习方法
3.属性抽取

属性抽取的目标是从不同信息源中采集特定实体的属性信息,例如针对某个公共人物,可以从网络公开信息中得到其昵称、生日、国籍、教育背景等信息。属性抽取技术从多种数据来源中汇集这些信息,实现对实体属性的完整勾画。

知识融合(knowledge fusion)

目的:将知识抽取中包含的冗余和错误信息进行清理和整合
主要包含两个内容:实体链接和知识合并。

1.实体链接

是指对从文本中抽取得到的实体对象,将其链接到知识库中对应的正确实体对象的操作。基本思想是根据给定的实体 指称项 ,从知识库中选取一组候选实体对象,然后通过相似度计算将 指称项 链接到正确的实体对象。
实体链接的基本思想是首先根据给定的实体指称项,从知识库中选出一组候选实体对象,然后通过相似度计算将指称项链接到正确的实体对象。
实体链接的一般流程:

  1. 从文本中通过实体抽取得到实体指称项
  2. 进行实体峭岐和共指消解,判断知识库中的同名实体与之是否代表不同的含义以及知识库中是否存在其他命名实体与之表示相同的含义;
  3. 在确认知识库中对应的正确实体对象后,将该实体指称项链接到知识库中对应实体。

关于消除歧义的补充:

  1. 实体消歧
    消除同名实体产生的歧义问题。例如“李娜”这个名词可能指代中国顶级网球运动员,也可能指代现在在某高校就读的研究生。通过实体消岐结合当前语义环境来分辨实体的具体指代是什么。(聚类)
  2. 共指消解
    解决多个指称项对应于同一实体对象的问题。例如“母亲”和“妈妈”在汉语中是对同一个实体的不同称谓,它们的意思是相同的。
2.知识合并

指将两个内容相近的知识库进行融合,形成一个更大的知识库。

  1. 合并外部知识库
    主要处理两方面的问题:
  • 数据层融合:包括实体的指称、属性、关系以及所属类别等
    其主要研究问题是如何避免实例以及关系冲突等问题(冗余问题)
  • 模式层融合:将新得到的本体融入到已有的本体库中。
  1. 合并关系数据库
    对两个关系型数据库求左合并,右合并,笛卡尔积等操作。(关于这个我可能解释的比较狭义但是好像就是这样的)

知识推理

是指从知识库中已有的实体关系数据触发,经过计算机推理,建立实体的新关联,从而拓展和丰富知识网络。例如(曹操,父子,曹丕),(曹丕,兄弟,曹植),可以推导出(曹操,父子,曹植)。


知识图谱相关PAAS服务


百度AI开放平台

  • 实体标注

输入:
待标注的文本字符串(utf8编码,最多64个汉字)

1
2
// 输入示例
curl -X POST 'https://aip.baidubce.com/rpc/2.0/kg/v1/cognitive/entity_annotation?access_token=【用户access_token】' -H 'content-type: application/json' -d '{"data": "刘德华的老婆"}'

输出:(示例)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// 输出示例
{
"log_id": 6367018173853945311,
"entity_annotation": [
{
"status": "LINKED",
"confidence": "0.991616",
"concept": {
"level1": "人物",
"level2": "文化人物,娱乐人物"
},
"_bdbkKgId": "114923",
"mention": "刘德华",
"_bdbkUrl": "http://baike.baidu.com/item/%E5%88%98%E5%BE%B7%E5%8D%8E/114923",
"offset": "0",
"desc": "中国香港男演员、歌手、词作人"
},
{
"status": "LINKED",
"confidence": "0.817889",
"concept": {
"level1": "语言文化",
"level2": "文字词汇"
},
"_bdbkKgId": "827",
"mention": "老婆",
"_bdbkUrl": "http://baike.baidu.com/item/%E8%80%81%E5%A9%86/827",
"offset": "4",
"desc": "汉语词语"
}
]
}

  • 知识问答

知识图谱的应用领域


智能问答

降低了人机交互门槛,用户可以通过关键词向网页发送请求得到他们想要的答案。

智能推荐

例如Facebook的Graph Search,用户查询产品信息时仅需输入关键词,以知识图谱为基础的智能推荐就会向用户输出产品相关信息。

金融领域

金融领域是知识图谱最早、最广泛的应用领域之一,目前最常用的主要是风险控制和智能投顾两方面。
例如金融知识图谱,对数据进行智能分析,当用户进行投资理财时,可以根据提取出来的信息,结合用户实际需求,为用户智能推荐理财产品。


数据获取来源

  • 爬虫
  • 数据库获取

数据预处理

  • 数据清洗
  • 知识抽取

导入数据到知识图谱

  • 数据筛选(决定哪些数据需要到知识图谱系统,性能,业务要求)
  • 知识图谱设计(类似数据库设计)
  • 批量导入(初次导入基础数据)
  • 增量导入

本体论


本体论(Ontology),是探究世界的本原或基质的哲学理论。“本体论”一词是由17世纪的德国经院学者P·戈科列尼乌斯首先使用的。
传统上的本体含义,是一个哲学的分支,即形而上学,本体论一般包含了有关所有的实体的存在或者一些可能会存在的问题,以及实体之间如何被归类研究对立的问题,如何在层次的体系结构中,根据相互作用和差异上进行分类的问题。本体论还有个通俗易懂的定义是,它是对事物“存在”性的定性检验。

关于本体论的例子:

基因本体论(gene ontology)

基因本体(Gene Ontology,GO)是一个在生物信息学领域中广泛使用的本体,它涵盖生物学的三个方面:细胞组分、分子功能、生物过程。

基因本体论

基因本体是一个有向无环图(DAG)型的本体。目前,GO中使用了is_a和part_of和regulates三种关系。

基因本体论的关系示例

本体论与知识图谱的区别

例如要对档案领域的知识库分类,这个分类本身就是本体。比如档案数据分为毕业生类和学校文件类,毕业生类又分为本科生类、研究生类;关于每个分类下又有不同的数据信息,每种信息对应着不同的实体,每个实体有其不同的属性值,可以将其抽象成为一个三元组,例如(毕业生A,毕业年份,2017),这个三元组就是知识图谱中的基本结构了。
由于知识图谱这个概念是由Google提出,而知识库的概念没有明确的提出,可以将其理解为是知识数据库,即所有数据的集合体,包含知识和本体,例如Wiki百科就可以理解为一个半结构化的知识库。(我的理解是知识库是广义的知识图谱,知识图谱最终构建的逻辑结构为一个图)
还有一个浅而易懂的例子,对于概念型的三元组(老虎,科,猫科),如果将猫科定义为一个本体,则这个三元组就反映了本体与实体之间的关系。

参考:
(1)知识图谱基础知识
(2)田莉霞.知识图谱研究综述[J].软件,2020,04:67-71.
(3)段宏. 知识图谱构建技术综述[J]. 计算机研究与发展(03).
(4)百度AI开放平台
(5)百度百科-本体论
(6)Paulheim H , Cimiano P . Knowledge graph refinement: A survey of approaches and evaluation methods[J]. Semantic Web, 2016, 8(3):489-508.

R语言

发表于 2019-11-25

我这块主要是为java服务的

创建向量

1
2
v1 <-c(1502,5215,5235,6242) 
print(v1)

输出:

1
[1] 1502 5215 5235 6242


定义函数

1
2
3
4
Rtest<-function(v2,i){

print(v2[i])
return(v2[i]+55)

函数调用:

1
Rtest(c(1,63,523,524),3)

输出:

1
2
[1] 523
[1] 578


R语言$的含义

网上东西挺多的(反正没一个能讲明白的),这玩意说白了就是一个dataframe中取某一个向量。

R语言

发表于 2019-11-25

我这块主要是为java服务的

创建向量

1
2
v1 <-c(1502,5215,5235,6242) 
print(v1)

输出:

1
[1] 1502 5215 5235 6242


定义函数

1
2
3
4
Rtest<-function(v2,i){

print(v2[i])
return(v2[i]+55)

函数调用:

1
Rtest(c(1,63,523,524),3)

输出:

1
2
[1] 523
[1] 578


R语言$的含义

网上东西挺多的(反正没一个能讲明白的),这玩意说白了就是一个dataframe中取某一个向量。

Jpcap

发表于 2019-11-22

Java利用Jpcap抓包


NetworkInterfaceAddress[]

类型-参数名 参数解释
String-datalink_description 数据链路层的描述。描述所在的局域网是什么网。例如,以太网(Ethernet)、无线LAN网(wireless LAN)、令牌环网(token ring)等等。
String-datalink_name 该网络设备所对应数据链路层的名称。具体来说,例如Ethernet10M、100M、1000M等等。
String-decription 网卡信息
boolean_Loopback 是否是loopback设备
Byte[]-mac_address 网卡的MAC地址
String-Name 网卡设备名称

JpcapCaptor

类型-参数名 参数解释
int-dropped_packets 被抛弃包数目
int-ID 未知

JpcapCaptor方法

返回值类型 方法名-说明
static NetworkInterface[] getDeviceList()
返回一个网络设备列表。
static JpcapCaptor openDevice(NetworkInterface interface, intsnaplen, booleanpromisc, intto_ms)

创建一个与指定设备的连接并返回该连接。注意,以上两个方法都是静态方法。
Interface:要打开连接的设备的实例;
Snaplen:这个是比较容易搞混的一个参数。其实这个参数不是限制只能捕捉多少数据包,而是限制每一次收到一个数据包,只提取该数据包中前多少字节;
Promisc:设置是否混杂模式。处于混杂模式将接收所有数据包,若之后又调用了包过滤函数setFilter()将不起任何作用;
To_ms:这个参数主要用于processPacket()方法,指定超时的时间;
void Close()
关闭openDevice()的连接
JpcapSender getJpcapSenderInstance()
该返回一个JpcapSender实例,JpcapSender类是专门用于控制设备的发送数据包的功能的类。
Packet getPacket()
捕捉并返回一个数据包。这是JpcapCaptor实例中四种捕捉包的方法之一。
int loopPacket(int count,PacketReceiver handler)
捕捉指定数目的数据包,并交由实现了PacketReceiver接口的类的实例处理,并返回捕捉到的数据包数目。如果count参数设为-1,那么无限循环地捕捉数据。
这个方法不受超时的影响。还记得openDivice()中的to_ms参数么?那个参数对这个方法没有影响,如果没有捕捉到指定数目数据包,那么这个方法将一直阻塞等待。
PacketReceiver中只有一个抽象方法void receive(Packet p)。
int processPacket(intcount, PacketReceiver handler)
跟loopPacket()功能一样,唯一的区别是这个方法受超时的影响,超过指定时间自动返回捕捉到数据包的数目。
int dispatchPacket(intcount, PacketReceiverhandler)
跟processPacket()功能一样,区别是这个方法可以处于“non-blocking”模式工作,在这种模式下dispatchPacket()可能立即返回,即使没有捕捉到任何数据包。
void setFilter(java.lang.Stringcondition, booleanoptimize)
.condition:设定要提取的包的关键字。

Optimize:这个参数在说明文档以及源代码中都没有说明,只是说这个参数如果为真,那么过滤器将处于优化模式。
void setNonBlockingMode(booleannonblocking)
如果值为“true”,那么设定为“non-blocking”模式。
void breakLoop()
当调用processPacket()和loopPacket()后,再调用这个方法可以强制让processPacket()和loopPacket()停止。

IPPacket

类型-参数名 参数解释
boolean-d_flag V4
IPAddress-dst_ip 目的IP地址
int-flow_label 流标签
short-hop_limit 生存时间
int-ident 分组标识(v4)
short-length 数据包长度
boolean-more_frag MF标志位(v4)
more fragment标识还有分片
byte-priority 优先权
short-protocol 协议(v4、v6)
IPAddress-src_ip 返回源IP地址
String-data 报文内容

TCPPacket

TCPPacket是IPPacket的子包

类型-参数名 参数解释
boolean-ack ACK标识
boolean-fin FIN标识
byte[]-option TCP选项
boolean-psh PSH标志
long-sequence 序号
int-src_port 源端口
int-dst_port 目的端口
boolean-syn SYN标志
boolean-urg URG标志

R语言-Java语言沟通

发表于 2019-09-24

R-Java语言

####直接在RGui输入

1
install.packages("包的名字",lib="下载的路径")

输入

1
2
library(Rserve)
Rserve()

运行你的Rserve,然后才可以在Java中调用R语言程序
(我也不知道写这个干啥用,反正调试了半天真的是让人头大)

JAVADOC注释

发表于 2019-09-22

javadoc注释


eclipse

在写完的接口前面,输入/** 再按个回车,就自动生成嘞

超几何分布随机序列生成

发表于 2019-09-22
题目:超几何分布

实验目的

生成一系列的超几何分布的数

实验步骤

1.使用马特赛特旋转算法生成随机数
2.使用生成的随机数模拟多次不放回抽奖的行为,将结果记录
3.输出超几何分布随机数的结果

代码解释

AI测试

发表于 2019-08-15

AI测试


什么是AI测试

人工智能(AI)是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学(定义)。人工智能利用机器学习技术,通过对现有的经过处理(筛选、消噪、过滤等)的数据,不断进行矫正(设置阀值等方法)机器模型的输出,此过程称为训练,期望通过训练可以得到在未来新数据上有良好表现的模型,从而投入生产。

AI测试内容

1. 模型评估测试

模型评估主要是测试 模型对未知新数据的预测能力,即泛化能力。
泛化能力越强,模型的预测能力表现越好。而衡量模型泛化能力的评价指标,就是性能度量(performance measure)。性能度量一般有错误率、准确率、精确率、召回率等。

参数以及说明:

Accuracy(准确率)
Precision(精确率)
Recall(召回率)
F1值
P-R(Precision-recall )曲线
ROC曲线
AUC值
Kappa系数
OOB误差

对于二值分类器,或者说分类算法,如分类猫和狗,分类性别男和女。
TP、FP、TN、FN,即:
True Positive, False Positive, True Negative, False Negative

预测值与真实值相同,记为T(True)
预测值与真实值相反,记为F(False)
预测值为正例,记为P(Positive)
预测值为反例,记为N(Negative)

TP:预测类别是正例,真实类别是正例
FP:预测类别是正例,真实类别是反例
TN:预测类别是反例,真实类别是反例
FN:预测类别是反例,真实类别是正例
分类混淆矩阵

例子
用例说明

AUC&ROC曲线

受试者操作特征曲线(ROC),这一点网上已经说烂不再赘述,用来衡量二分类问题中的模型性能。

SKLEARN接口文档代码示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import numpy as np
import matplotlib.pyplot as plt
from itertools import cycle

from sklearn import svm, datasets
from sklearn.metrics import roc_curve, auc
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import label_binarize
from sklearn.multiclass import OneVsRestClassifier
from scipy import interp

# Import some data to play with
iris = datasets.load_iris()
X = iris.data
y = iris.target

# Binarize the output
y = label_binarize(y, classes=[0, 1, 2])
n_classes = y.shape[1]

# Add noisy features to make the problem harder
random_state = np.random.RandomState(0)
n_samples, n_features = X.shape
X = np.c_[X, random_state.randn(n_samples, 200 * n_features)]

# shuffle and split training and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.5,
random_state=0)

# Learn to predict each class against the other
classifier = OneVsRestClassifier(svm.SVC(kernel='linear', probability=True,
random_state=random_state))
y_score = classifier.fit(X_train, y_train).decision_function(X_test)

# Compute ROC curve and ROC area for each class
fpr = dict()
tpr = dict()
roc_auc = dict()
for i in range(n_classes):
fpr[i], tpr[i], _ = roc_curve(y_test[:, i], y_score[:, i])
roc_auc[i] = auc(fpr[i], tpr[i])

# Compute micro-average ROC curve and ROC area
fpr["micro"], tpr["micro"], _ = roc_curve(y_test.ravel(), y_score.ravel())
roc_auc["micro"] = auc(fpr["micro"], tpr["micro"])

ROC曲线示例图

P-R曲线

P-R曲线用来衡量分类器性能的优劣,横轴为recall ,纵轴为precision。
P-R 曲线越靠近右上角性能越好。
如果有多个分类器,则可以画出P-R曲线,若一个分类器A的P-R曲线把另外一个分类器B覆盖,则在一方面可以说明 A的分类器性能比B分类器好。
有交叉时,用平衡点(BEP)来衡量。平衡点即precision 等于 recall 时的值。那么可以认为A优于B。
画出P-R曲线:
算法对样本进行分类时,通常都会有个阈值,或者超参数,需要调。
不同的阈值时,就可以得出不同的精确率和召回率,从而画出P-R曲线图。

OOB误差

随机森林算法模型误差评价
OOB

2. 稳定性测试

稳定性/鲁棒性主要是测试算法多次运行的稳定性;以及算法在输入值发现较小变化时的输出变化。
如果算法在输入值发生微小变化时就产生了巨大的输出变化,就可以说这个算法是不稳定的。

3. 系统测试

将整个基于算法模型的代码作为一个整体,通过与系统的需求定义作比较,发现软件与系统定义不符合或与之矛盾的地方。
系统测试主要包括以下三个方面:

  1. 项目的整体业务流程
  2. 真实用户的使用场景
  3. 数据的流动与正确

4. 接口测试

接口测试是测试系统组件间接口的一种测试。接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。测试的重点是要检查数据的交换,传递和控制管理过程,以及系统间的相互逻辑依赖关系等。

5. 文档测试

文档测试是检验用户文档的完整性、正确性、一致性、易理解性、易浏览性。
在项目的整个生命周期中,会得到很多文档,在各个阶段中都以文档作为前段工作成果的体现和后阶段工作的依据。为避免在测试的过程中发现的缺陷是由于对文档的理解不准确,理解差异或是文档变更等原因引起的,文档测试也需要有足够的重视。

6. 性能测试

7. 白盒测试


AI测试流程

AI测试分为五个步骤,测试需求分析、测试环境准备、测试数据准备与验证、AI测试执行与分析、模型上线与监控。

AI测试需求分析

AI测试需求分析与软件开发的需求分析要求基本一致,需要明确测试对象、测试范围、测试的方法和工具、测试的准则等。AI测试需求分析需要通过开发、测试、运营共同参与讨论,确定AI系统测试通过的准则。由于AI开发具有一定的不确定性,还需要根据实际情况去定义可允许的风险,风险可根据技术的限制和社会共识来确定。

测试环境准备

AI的算法,比如推荐系统、搜索引擎、图像分类、自然语言处理都依赖于大数据基础架构,因此AI算法模型的测试环境准备,通常需要考虑数据量、计算量、测试时间等因素。此外,AI测试需要高效的持续测试,所以AI测试尤其需要测试环境快速部署的能力。

测试数据准备与验证

AI测试与机器学习一样,需要一定量测试数据去进行模型的评估与测试。测试的数据集要根据真实环境下用户产生的数据情况去划分,可以遵守如下原则:
  1. 测试数据与训练数据的比例要合适
  2. 测试数据与训练数据需要独立同分布
  3. 测试数据与训练数据正负样本的比例也需要尽量保持一致
  4. 对于有监督的模型,测试数据的标签需要保证正确

AI系统测试与分析

模型离线评估主要是评测AI模型对未知新数据的预测能力,即泛化能力。泛化能力越强,模型的预测能力越好。可靠性测试,包括了鲁棒性、可用性、容错性、易恢复性等指标。对于无人驾驶、人脸识别等安全攸关的AI系统,需尽可能采用异常数据来进行测试,如对抗样本、易出错的样本等;对于推荐系统和搜索引擎等智能程序则需要测试反作弊能力。

AI模型上线与监控

AI模型上线后,根据实际业务每隔几天或几星期,对模型各类指标进行评估。指标应设置对应阀值,当低于阀值时应触发报警。如果模型随着数据的演化而性能下降,说明模型在新数据下性能不佳,就需要利用新数据重新训练模型。此外,在一些场景中,我们还需要对用户输入数据进行监控。

测试结果

通过测试文档以及各种测试的资料,可以整合成一个整个文档。通过文档说明可以更正所有测试的内容。
fenleijuzhen


参考博客
人工智能测试方法–释梦石

【AI测试】也许这有你想知道的人工智能 (AI) 测试–凌晨点点

AI测试的思考与探索–陈敏刚

未命名

发表于 2019-03-12
1
2
3
4
5
6
7
public class Test {
public static void main(String[] args) {
char c = '4';
int t = c - '0';
System.out.println("char转换为数字: " + t);
}
}

邮票

发表于 2019-02-27

某人有8 角的邮票5 张,1 元的邮票4 张,1 元8 角的邮票6 张,用这些邮票中的一张或若干张可以得到多少中不同的邮资?

枚举了,反正容量也不大……再排序,之前因为数组容量问题,数组一共是756=210,导致两次测试没通过,剩下就是排序,去重(最简单的冒泡排序居然不会写了,果然过完年就咸鱼了)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class Main2{
public static void main(String args[]){
int a;
int m[]=new int[210];
int c=0;
int num=0;
for(int i=0;i<=5;i++){
for(int j=0;j<=4;j++){
for(int k=0;k<=6;k++){
m[c++]=8*i+10*j+18*k;
// System.out.println(m[c-1]);
num++;
}
}
}
//System.out.println(num);
int n=209;
for(int i=n;i>0;i--) {
for(int j=1;j<i;j++) {
if(m[j]<m[i]) {
int temp=m[j];
m[j]=m[i];
m[i]=temp;
}else if(m[i]==m[j]) {
m[j]=m[(n--)];
}
}
}
System.out.println(n);
}
}

在别人的博客偷来一份C++版的,参考一下吧,他还用到了容器
邮票,c++版

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>
using namespace std;
void sort(float a[],int n)
{
float temp;
for(int i=0;i<n;++i)
for(int j=i;j<n;++j)
{
if(a[i]>=a[j])
{
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
}
int main()
{
int sum=0;
float s[1000];
float s1[1000];
for(int i=0;i<=5;++i)
{
for(int j=0;j<=4;++j)
{
for(int k=0;k<=6;++k)
{
s[sum++]=0.8*i+j+1.8*k;
}
}
}
for(int p=0;p<sum;++p)
cout<<s[p]<<" ";
cout<<endl<<"总数:"<<sum<<endl;
sort(s,sum);
for(int b=0;b<sum;++b)
cout<<s[b]<<" ";//
cout<<endl<<"排好序:"<<sum<<endl;
cout<<endl;

//去除0
int u=0;
for(int d=0;d<sum;++d)
{
if(s[d]!=s[d+1]&&s[d]!=0)
s1[u++]=s[d];
}
for(int m=0;m<u;++m)
cout<<m<<" "<<s1[m]<<endl;
cout<<endl<<"去除0:"<<u<<endl;
return 0;
}

容器版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <set>
using namespace std;
int main()
{
set<float> fset;//double不精确
int i,j,k,count;
for(i=0;i<=5;++i)
for(j=0;j<=4;++j)
for(k=0;k<=6;++k)
fset.insert(0.8*i+1*j+1.8*k);
cout<<"总数:"<<fset.size()<<endl;
set<float>::iterator it;
cout<<"去除重复和0:"<<endl;
for(count=1,it=fset.begin();it!=fset.end();++it,++count)
cout<<count<<" "<<*it<<endl;
return 0;
}

居然发现我的代码还比这个短一些,不过这是人家两年前的博客,两年前的我……

12…4

Mark Zhang

33 日志
© 2020 Mark Zhang
由 Hexo 强力驱动
|
主题 — NexT.Pisces v5.1.4