彩色图像:RGB图像。灰度图像:0-255像素值。二值图像:0和1,用于掩膜图像。
索引图像:在灰度图像中,自定义调色板,自定义输出256种颜色值。
HSI、HSV、RGB、CMY、CMYK、HSL、HSB、Ycc、XYZ、Lab、YUV色彩空间(颜色模型)
RGB颜色空间是算法处理中应用最多的颜色空间。
HSI颜色空间,色调(Hue)、色饱和度(Saturation或Chroma)和亮度(Intensity或Brightness)
YUV,分为三个分量,“Y”表示明亮度(Luminance或Luma),也就是灰度值;而“U”和“V” 表示的则是色度(Chrominance或Chroma),作用是描述影像色彩及饱和度,用于指定像素的颜色。YUV 4:4:4采样,每一个Y对应一组UV分量。YUV 4:2:2采样,每两个Y共用一组UV分量。 YUV 4:2:0采样,每四个Y共用一组UV分量。 紧缩格式(packed formats)平面格式(planar formats)。YYYYYYYYUVUV YYYYYYYYUUVV
像素数为图像实际组成的像素的个数,像素是没有固定宽度和高度的,是一个感光单元。
分辨率的单位为 像素/英寸(1英寸(inch)=2.54厘米(cm)),这里指的不是面积,而是对角线的长度,即dpi、ppi。分辨率也称之为点密度,分辨率越高,看的越细腻。
PAL制式是——25fps,NTSC是——30fps。
使用一个三角函数(如正弦函数)与一个高斯函数叠加我们就得到了一个Gabor滤波器。Gabor滤波器可以抽取空间局部频度特征,是一种有效的纹理检测工具。
附:图像的空域是指二维坐标系上的操作,频域指的是图像经过傅里叶变换后的频谱。在频率域中,高频分量表示图像中灰度变换比较快的那些地方,比如物体的边缘就是灰度的突然变化,所以物体边缘就是高频分量。而物体内部比较平坦的区域,灰度基本没有变化,对应的就是低频分量。比如低通滤波只让低频分量通过,往往就是使图像模糊,因为边缘信息被去除了。高频对应图像细节,低频对应图像大致轮廓。
参考:中值滤波与椒盐噪声
椒盐噪声:也称为脉冲噪声:
在图像中,它是一种随机出现的白点或者黑点,可能是亮的区域有黑色像素或是在暗的区域有白色像素(或是两者皆有)。
滤除椒盐噪声比较有效的方法是对信号进行中值滤波处理。
matlab中连通区域标记函数bwlabel中的算法,一次遍历图像,并记下每一行(或列)中连续的团(run)和标记的等价对,然后通过等价对对原来的图像进行重新标记。
vector< vector >
中,以下为每一行的操作。 vector< pair >
用于存放所有的等价对。 代码见github
开源库cvBlob中使用的标记算法,它通过定位连通区域的内外轮廓来标记整个图像,这个算法的核心是轮廓的搜索算法
TODO:轮廓跟踪算法
MMX(Multi Media eXtension,多媒体扩展指令集)是一些整数并行运算指令。
SSE(Streaming SIMD Extensions,单指令多数据流扩展)是一系列浮点并行运算指令。
SIMD,单指令多数据流,是指用一条指令执行多个计算,比如图像像素一般是BYTE占8位,而计算机中总线是64位,所以理论上可以同时进行8个像素的运算。
单指令多数据流SIMD、对称多处理机SMP、大规模并行处理机MPP、工作站机群COW、分布共享存储DSM多处理机。
SIFT/SURF为了实现不同图像中相同场景的匹配,主要包括三个步骤:
1. 尺度空间的建立;
2. 特征点的提取;
3. 利用特征点周围邻域的信息生成特征描述子;
4. 特征点匹配。
之所以采用尺度空间,是为了应对尺度不变性。
SIFT
3*3
邻域内的8个点做比较,在同一组内的尺度空间上,中心点和上下相邻的两层图像的2*9
个点作比较,如此可以保证检测到的关键点在尺度空间和二维图像空间上都是局部极值点2*2
块,每块的所有像素点的荼毒做高斯加权,每块最终取8个方向,即可以生成2*2*8
维度的向量,以这2*2*8
维向量作为中心关键点的数学描述。线性判别分析(LDA), 主成分分析(PCA)
参考、 参考
LDA和PCA最终的表现都是解一个矩阵特征值的问题,分类的目标是,使得类别内的点距离越近越好(集中),类别间的点越远越好。
LDA的全称是Linear Discriminant Analysis(线性判别分析),是一种supervised learning。
LDA的原理是,将带上标签的数据(点),通过投影的方法,投影到维度更低的空间中,使得投影后的点,会形成按类别区分,一簇一簇的情况,相同类别的点,将会在投影后的空间中更接近。要说明白LDA,首先得弄明白线性分类器(Linear Classifier):因为LDA是一种线性分类器。对于K-分类的一个分类问题,会有K个线性函数 y = wx+b.
当满足条件:对于所有的j,都有Yk > Yj,的时候,我们就说x属于类别k。对于每一个分类,都有一个公式去算一个分值,在所有的公式得到的分值中,找一个最大的,就是所属的分类了。
y = wx+b实际上就是一种投影,是将一个高维的点投影到一条高维的直线上,LDA最求的目标是,给出一个标注了类别的数据集,投影到了一条直线之后,能够使得点尽量的按类别区分开
主成分分析(PCA)与LDA有着非常近似的意思,LDA的输入数据是带标签的,而PCA的输入数据是不带标签的,所以PCA是一种unsupervised learning。
PCA更像是一个预处理的方法,它可以将原本的数据降低维度,而使得降低了维度的数据之间的方差最大
它的目标是通过某种线性投影,将高维的数据映射到低维的空间中表示,并期望在所投影的维度上数据的方差最大,以此使用较少的数据维度,同时保留住较多的原数据点的特性。
通俗的理解,如果把所有的点都映射到一起,那么几乎所有的信息(如点和点之间的距离关系)都丢失了,而如果映射后方差尽可能的大,那么数据点则会分散开来,以此来保留更多的信息。可以证明,PCA是丢失原始数据信息最少的一种线性降维方式。(实际上就是最接近原始数据,但是PCA并不试图去探索数据内在结构)
Linear Discriminant Analysis (也有叫做Fisher Linear Discriminant)是一种有监督的(supervised)线性降维算法。与PCA保持数据信息不同,LDA是为了使得降维后的数据点尽可能地容易被区分!
如下图所示,请以准确快速实现配准为目标,设计算法,让两图中对应的特征点(至少一部分特征点)配准(即精准地地找出对应点之间对应的坐标关系值)。
参考
之前是用角点检测,后来采用SIFT算子,Sift算法的实质是在不同的尺度空间上查找关键点(特征点),计算关键点的大小、方向、尺度信息,利用这些信息组成关键点对特征点进行描述的问题。
对于一般应用图像中,景物可能存在任意特征(如折线,弧形、亮度极值、色调等),请设计合适的算法,找到图像中可以作为明显特征点的灰度的极值点所在的邻域。以准确快速实现极值点邻域筛选为目标,设计算法。用流程图表达)。
也使用SIFT特征
线性分类器:Logistic回归 y=sigmoid(wx+b)
传统方式:特征描述和检测
KNN,K最近邻,判断图像与各个类别的距离
SVM,选定特征, SVM算法输出一个最优化的分隔超平面(分类面)。本科课题:SIFT、k-means、Bag of Words、SVM。映射函数可能为多项式。
BPNN,全连接网络,计算量巨大
CNN,卷积神经网络
迁移学习,利用别人训练好的参数,自定义网络
LR的优化函数为似然函数,经典线性回归的优化函数为最小二乘。
LR将预测范围缩小到了[0,1],而经典线性回归的预测范围为整个实数。
相同:都是分类模型。都处理二分类。都可以添加正则项。
区别:LR是参数模型,SVM是非参数模型;LR采用logistical loss,SVM采用hinge loss;SVM之所以称之为支持向量,是因为SVM只考虑了与分类最相关的少数点来学习分类器。
K值较小意味着模型会越复杂,容易发生过拟合。K值过大会使模型过于简单,使得预测发生错误。实际使用中K一般取较小的数字。
参考http://blog.csdn.net/v_july_v/ … 24837
是一个二分分类器,找寻数据之间间隔最大的线性分类器。其学习策略是使分隔间隔最大化。对于线性可分的数据,SVM构造一个分隔面。对于线性不可分的数据,SVM采用核函数将低维空间的问题映射到了高维空间,从而线性可分。常用核函数有多项式核函数、高斯核函数、线性核函数。为了应对维度爆炸的情形,核函数事先在低维空间上进行计算,再将分类的实际效果展现在高维上。
SVM的损失函数叫做Hinge(hɪndʒ) Loss,形式为max(0,1-y*a),y为真实值+-1,a为预测值,介于-1到1之间。
BP(back propagation)神经网络,输入X,通过隐藏节点的非线性变换后,输出信号Y,通过误差分析,来调整隐藏节点的W和b。
AdaBoost是一个广泛使用的BOOSTING算法,其中训练集上依次训练弱分类器,每次下一个弱分类器是在训练样本的不同权重集合上训练。权重是由每个样本分类的难度确定的。分类的难度是通过分类器的输出估计的。
参考资料
//TODO 详细学习
K均值聚类(K-meansClustering)
将输入数据分到K个类中。K均值是通过循环更新类中心的初始估计值来实现的。优势是实现起来很简单,是并行化的。主要缺陷是,类的数目需要提前确定。
主要分三步:
1. 随机选取k个聚类质心点(cluster centroids)
2. 对于每一个样例i,计算其应该属于的类
3. 对于每一个类j,重新计算该类的质心
1. 重复下面过程直到收敛
层次聚类
层次聚类(或者叫做凝聚聚类)是另一个简单但是强大的聚类算法。其思想是基于成对距离建立一棵相似度树。该算法首先分组成为两个最近的对象(基于特征向量之间的距离),并且在一棵有着两个对象作为孩子的树中创建一个平均结点。然后在余下的结点中找到一个最近的pair,并且也包含任何平均节点,等等。在每一个结点,两个孩子之间的距离也会被存储。簇然后可以通过遍历这棵树并在距离比某个阈值小以至于决定聚类的大小的结点处停止来被提取出来。
层次聚类有几个优势。比如,树结构可以被用来可视化关系,并且显示簇是如何关联起来的。一个好的特征向量将得到树中好的分离。另一个优势是树可以在不同的簇阈值中被重用,而不需要重新计算树。缺点是需要选择一个阈值如果实际的簇需要的话。
谱聚类
对于n个元素的相似度矩阵(或者叫affinity matrix, 有时也叫距离矩阵)是一个有着成对相似度分数的n*n矩阵。谱聚类的这个名称是从相似度矩阵构造的矩阵的谱的使用得来。这个矩阵的特征向量被用来降维,然后再聚类。
谱聚类方法的其中一个优势是唯一的输入就是这个矩阵,并且可以被你可以想到的任何相似度度量构造出来。像K均值和层次聚类这样的方法计算特征向量的平均值,这个限制了特征(或者是描述符)对向量(为了能够计算平均值)。有了谱方法,不再需要任何类型的特征向量,只有“距离”或者“相似度”。
Mean Shift 聚类算法
简单的说,mean shift就是沿着密度上升的方向寻找同属一个簇的数据点。
欧式距离为最常见的2点之间的距离,为2点之间的直线距离。
曼哈顿距离又称为L1距离或者城市区块距离,是两个点的1范数距离。
Graph cuts是一种十分有用和流行的能量优化算法,在计算机视觉领域普遍应用于前背景分割(Image segmentation)、立体视觉(stereo vision)、抠图(Image matting)等。
利用图,将目标和背景进行分割。
已知两幅拼接好的图像,两幅图像在几何关系配准之后,但两图之间存在明显灰度差别跳变,请设计一个算法对图像进行处理,让两幅图之间的灰度看不出跳变,形成自然过渡。(可以不考虑两图之间的黑图部分)。
影像融合是指高分辨率灰度图像和低分辨率彩色图像融合得到具有高分辨率的彩色图像。该算法称之为图像镶嵌。简单的做法可以是寻找两幅影像的镶嵌线,镶嵌线是指两幅影像公共区域区别最小的一条线,可以利用相关系数法判断得到,然后根据镶嵌线上两幅影像的灰度差异对右影像进行反差调整,最后拼接。
Bagging方法是ensemble methods中获得用于训练base estimator的数据的重要一环。 正如其名,Bagging方法就是将所有training data放进一个黑色的bag中,黑色意味着我们看不到里面的数据的详细情况,只知道里面有我们的数据集。然后从这个bag中随机抽一部分数据出来用于训练一个base estimator。抽到的数据用完之后我们有两种选择,放回或不放回。
我们可以看到从根节点开始往下会有分支,最终会走向叶子节点,得到分类结果。每一个非叶子节点都是一个特征,上图中共有三维特征。但是决策树的一个劣势就是容易过拟合,下面我们要结合上文提到的bagging技术来中和一下。
bagging + decision trees,我们得到了随机森林。将决策树作为base estimator,然后采用bagging技术训练一大堆小决策树,最后将这些小决策树组合起来,这样就得到了一片森林(随机森林)。
(X[1],Y[1])….(X[n],Y[n])是数据集,我们要训练T棵决策树g[1]….g[t]…g[T]。 每次从数据中有放回地随机抽取size-N’的子数据集D[t]用于训练第t棵决策树g[t]。
随机森林的随机性体现在每颗树的训练样本是随机的,树中每个节点的分裂属性集合也是随机选择确定的。有了这2个随机的保证,随机森林就不会产生过拟合的现象了。
高斯混合模型(Gaussian Mixture Model, GMM)将一个事物分解为若干的基于高斯概率密度函数(正态分布曲线)形成的模型。
高斯混合模型(GMM,Gaussian mixture model)是建模最为成功的方法之一,同时GMM可以用在监控视频索引与检索。
用于动目标检测中的背景建模。
目前最广泛被使用的分类器有人工神经网络、支持向量机、最近邻居法、高斯混合模型、朴素贝叶斯方法、决策树和径向基函数分类。
无监督学习里典型的例子就是聚类了。聚类的目的在于把相似的东西聚在一起,而我们并不关心这一类是什么。因此,一个聚类算法通常只需要知道如何计算相似度就可以开始工作了。
减小模型复杂度、加大数据、batch normalization、dropout、正则化、early stopping。
常见的判别模型有:K近邻、SVM、决策树、感知机、线性判别分析(LDA)、线性回归、传统的神经网络、逻辑斯蒂回归、boosting、条件随机场。通过决策函数来进行判别。
常见的生成模型有:朴素贝叶斯、隐马尔可夫模型、高斯混合模型、文档主题生成模型(LDA)、限制玻尔兹曼机。通过联合概率密度分布函数来进行预测。
归一化加快了梯度下降求解最优解的速度;归一化还可能会提高精度。
标准化是依照特征矩阵的列处理数据,其通过求z-score的方法,将样本的特征值转换到同一量纲下。归一化是依照特征矩阵的行处理数据,其目的在于样本向量在点乘运算或其他核函数计算相似性时,拥有统一的标准,也就是说都转化为“单位向量”。
对于深度网络而言,归一化的目的是方便比较,可以加快网络的收敛速度;标准化是将数据利用z-score(均值、方差)的方法转化为符合特定分布的数据,方便进行下一步处理,不为比较。
熵是指样本的随机程度。样本越无序,熵越大, 信息越多。
图像检测和分割,增强学习,生成对抗网络,预测学习
Stochastic Gradient Descent 随机梯度下降。GD即Full-Batch,SGD即为Mini-Batch。随机性表现在训练数据的shuffle。
Rectified Linear Unit, ReLU
若使用线性激活函数,则无论神经网络有多少层,输出都是输入的线性组合。
好的激活函数有以下特点:
深度网络的链式连乘法则,使得反向传播时到达前几层时,权值更新值非常小或非常大。
可以通过ReLU解决一部分。
先是混淆矩阵,这是基础。
包含四部分的信息:
1. True negative(TN),称为真阴率,表明实际是负样本预测成负样本的样本数
2. False positive(FP),称为假阳率,表明实际是负样本预测成正样本的样本数
3. False negative(FN),称为假阴率,表明实际是正样本预测成负样本的样本数
4. True positive(TP),称为真阳率,表明实际是正样本预测成正样本的样本数
前面有真的表示预测正确。
ROC曲线
二分类标签的输出概率需要定义一个阈值p,p值的选取反映了分类器的分类性能。ROC曲线的横轴为FP(将真实负样本预测为了正样本,越低越好),纵轴为TP(将真实正样本预测为正样本,越高越好)
则,若ROC曲线处于对角线之下,则分类性能差于随机分类器。希望该曲线向左上角凸。
AUC指标
AUC(Area under the ROC curve),适用于二元分类问题,AUC实际上就是ROC曲线下的面积。AUC直观地反映了ROC曲线表达的分类能力。
求解步骤:
AUC含义:从所有真实的正样本中取一个数据,判断这个样本是正样本的概率是p1,从所有真实的负样本中取一个数据,判断这个样本是正样本的概率是p2。对于分类器来说p1越大越好,p2越小越好。则p1大于p2的概率称之为AUC。
mAP
计算步骤,参考:
AP(average precision),
相关和卷积的机理相似,但卷积滤波器首先要旋转180度。
因为在图像的每个位置都要计算一遍卷积核,所以图像像素数为M,卷积核大小为N,则卷积的时间复杂度为O(M*N)。
CNN的四个特点:局部连接、权值共享、池化操作、多层次结构。
局部连接使网络可以提取数据的局部特征;权值共享降低了网络的训练难度,一个Filter只提取一个特征;池化操作与多层次结构一起,实现了数据的降维,将低层次的局部特征组合成为较高层次的特征,从而对整个图片进行表示。
人脸在不同的区域存在不同的特征(眼睛/鼻子/嘴的分布位置相对固定),当不存在全局的局部特征分布时,Local-Conv更适合特征的提取。
LSTM可以防止梯度消失或者爆炸
简称GAN。该网络包含2个部分,一个称之为生成器generator,主要作用是生成图片,并且尽量使得其看上去是来自于训练样本的。另一方是discriminator,其目标是判断输入图片是否属于真实训练样本。
TensorFlow分为二部分,一部分是构造部分,用来构造网络;一部分是执行部分,用来执行网络中的计算。
我们需要把服装与背景、人物、建筑等等元素区别开来,确定是否有衣服以及衣服在什么位置。接下来需要对衣服进行分析,提取出服装的属性、特征等等。最后再根据这些特征,在庞大的数据库里搜索同款或者类似的服装图片。
方差判断,梯度变化。
场景文字检测与识别,先用CNN等对文字进行定位,然后再使用LSTM、OCR进行文字识别。
首先检测轮廓,然后对轮廓进行分析(角点)。
如果图像污损严重,如何识别?
人脸识别、识别各类东西、检索各类图像。
全概率公式
对任一事件A,若有互不相容的事件 Bi(i=1,2,...,n) B i ( i = 1 , 2 , . . . , n ) ,满足 P(Bi)>0,∑ni=1P(Bi)=1(i=1,2,...,n) P ( B i ) > 0 , ∑ i = 1 n P ( B i ) = 1 ( i = 1 , 2 , . . . , n ) 且 ∑ni=1Bi⊃A ∑ i = 1 n B i ⊃ A ,则事件A的概率可用下式计算:
此概率称之为全概率公式。
Bayes公式
利用乘法公式与全概率公式可导出Bayes公式
对任一事件A,若有互不相容的事件 Bi(i=1,2,…,n) B i ( i = 1 , 2 , … , n ) ,满足 P(Bi)>0,∑ni=1P(Bi)=1(i=1,2,...,n) P ( B i ) > 0 , ∑ i = 1 n P ( B i ) = 1 ( i = 1 , 2 , . . . , n ) 且 ∑ni=1Bi⊃A ∑ i = 1 n B i ⊃ A ,(跟上个公式条件相同)则
最小二乘法通常用于 曲线拟合 (least squares fitting) 。
推导过程
核心思想是最小化损失函数:距离差值的平方( (di−R)2 ( d i − R ) 2 ),若想公式可导,则可以计算平方差的平方 (di2−R2)2 ( d i 2 − R 2 ) 2
C,C++中内存分配方式可以分为三种:
一个C、C++程序编译时内存分为5大存储区:堆区、栈区、全局区、文字常量区和程序代码区。
递归写法
非递归写法
设置队列
键字值不同的元素可能会映象到哈希表的同一地址上就会发生哈希冲突。解决办法:
具有二叉查找树的所有特征。二叉查找树查找的效率最坏为O(n),红黑树通过颜色着色的方法将最坏降低到平均水平。
是红黑树的这5条性质,使一棵n个结点的红黑树始终保持了logn的高度,从而也就解释了上面所说的“红黑树的查找、插入、删除的时间复杂度最坏为O(log n)”
#include
#include
using namespace std;
#define BIT3 (0x1<<3)
void set_bit3(unsigned &a)
{
a |= BIT3;
}
void clear_bits(unsigned &a)
{
a &= ~BIT3;
}
int main()
{
unsigned a = UINT_MAX;
clear_bits(a);
cout << (bitset<32>)a << endl;
set_bit3(a);
cout << (bitset<32>)a << endl;
return 0;
}
解法一、分治法
因为矩阵的行和列都是递增的,所以整个矩阵的对角线上的数字也是递增的,故我们可以在对角线上进行二分查找,如果要找的数是6介于对角线上相邻的两个数4、10,可以排除掉左上和右下的两个矩形,而在左下和右上的两个矩形继续递归查找
解法二、定位法
首先直接定位到最右上角的元素,比要找的数大就往左走,比要找数的小就往下走,直到找到要找的数字为止,走不动,说明这个数不存在。这个方法的时间复杂度O(m+n)。代码如下:
#include
#include
using namespace std;
bool YoungMatrix(vector< vector<int> > mat, int target){
int y = 0, x = mat[y].size() - 1;
int var = mat[y][x];
while (true) {
if (var == target){
printf("Mat[%d][%d]=%d\n", y, x, target);
return true;
}
else if (var < target && y < mat.size() - 1){
var = mat[++y][x];
}
else if (var > target && x > 0){
var = mat[y][--x];
}
else{
return false;
}
}
}
int main(){
vector<vector<int> > matrix(20);
for (int i = 0; i < 20; i++){
for (int j = 0; j < 20; j++) {
matrix[i].push_back(i+j);
cout << matrix[i][j] << " ";
}
cout << endl;
}
cout << YoungMatrix(matrix, 38) << endl;
return 0;
}
就是当1~n,2^i
从左上角到右下角总共要走2n步,其中横向要走n步,所以总共就是 Cn2n C 2 n n 次。
已知一棵二叉树前序遍历和中序遍历分别为ABDEGCFH和DBGEACHF,则该二叉树的后序遍历为多少?
#include
#include
using namespace std;
string Subsequent(string pre, string mid) {
if (pre.size() != mid.size() || pre.empty()) return "";
char root = pre[0];
int rootIndex = mid.find(root);
string leftPre = pre.substr(1, rootIndex);
string leftMid = mid.substr(0, rootIndex);
string rightPre = pre.substr(rootIndex + 1);
string rightMid = mid.substr(rootIndex + 1);
string res;
res += Subsequent(leftPre, leftMid);
res += Subsequent(rightPre, rightMid);
res += root;
return res;
}
int main(){
string pre = "ABDEGCFH";
string mid = "DBGEACHF";
cout << Subsequent(pre, mid) << endl;
return 0;
}
代码见github
动态规划推导式
代码见github
与上文区别是不等时的处理方式,和最后是整个矩阵中寻找最大值。
代码见github
直方图
#include
#include
#include
using namespace std;
vector<int> LongestShunZi(vector<int> input) {
// 统计直方图
vector<int> hist;
hist.resize(15);
for (int i = 0; i < input.size(); i++)
if (input[i] > 0 && input[i] < 15)
hist[input[i]] ++;
hist[14] = hist[1];
//最大牌数
int maxCount = 0;
for (int i = 1; i < 15; i++)
if (hist[i] > maxCount)
maxCount = hist[i];
//求结果
int resLen = 0;
int resCount = 0;
int resEnd = 0;
for (int i = 1; i <= maxCount; i++)
{
int len = 0;
int longestLen = 0;
int longestEnd = 1;
for (int j = 1; j < 15; j++) {
if (hist[j] >= i) {
len++;
if (len > longestLen) {
longestLen = len;
longestEnd = j;
}
}
else {
len = 0;
}
}
if (longestLen == 14 && 2 * i > hist[1]) longestLen--;
if (longestLen * i > resLen * resCount) {
resLen = longestLen;
resCount = i;
resEnd = longestEnd;
}
}
vector<int> res;
for (int i = resEnd - resLen + 1; i <= resEnd; i++)
for (int j = 0; j < resCount; j++)
res.push_back(i);
return res;
}
int main() {
int arr[] = { 1, 5, 2, 3, 4, 4, 5, 9, 6, 7, 2, 3, 3, 4 };
vector<int> v(arr, arr+sizeof(arr)/sizeof(int));
vector<int> res = LongestShunZi(v);
for (int i = 0; i < res.size(); i++) cout << res[i] << " ";
cout << endl;
return 0;
}
对一批编号为1-100,全部开关朝上(开)的亮灯进行如下操作:凡是编号为1的倍数的灯反方向拨一次开关;凡是编号为2的倍数的灯反方向又拨一次开关;编号为3的倍数的灯反方向又拨一次开关……凡是编号为100的倍数的灯反方向拨一次开关。编写程序,模拟此过程,最后打印出所熄灭灯的编号。
#include
using namespace std;
int main() {
bool arr[101];
memset(arr, 0, 101);
for (int i = 2; i <= 100; i++) {
for (int j = 1; j <= 100; j++) {
if (j % i == 0) {
arr[j] = !arr[j];
}
}
}
for (int i = 1; i <= 100; i++) {
if (!arr[i])
cout << i << endl;
}
return 0;
}
1
4
9
16
25
36
49
64
81
100
一个数的约数个数为奇数。所有的数都包含1和自己,平方数的约数肯定是奇数个。
unsigned int convect(char* pstr)
实现个函数 unsigned int convect(char* pstr)
。其中pstr
是十六进制数的字符串。函数convect
将pstr
转换成数字返回(比如:字符串’1A’,将返回数值26.注意,pstr[0]
是’1’)。pstr
中只有数字字符0到9、A到F。不得借助其它的系统函数调用。
#include
using namespace std;
unsigned int convect(char* pstr) {
char *p = pstr;
unsigned long long res = 1;
unsigned long long maxInt = (res << 32) - 1;
res = 0;
while (*p != '\0') {
if (*p >= '0' && *p <= '9') {
res = res * 16 + *p - '0';
}
else if (*p >= 'A' && *p <= 'F') {
res = res * 16 + *p - 'A' + 10;
}
else return 0;
p++;
}
if (res > maxInt) return 0;
return res;
}
int main() {
cout << convect((char*)"1A") << endl;
cout << convect((char*)"FFFFFFFF") << endl;
cout << convect((char*)"FFFFFFFFF") << endl;
return 0;
}
unsigned int counter(char* pstr)
实现一个函数unsigned int counter(char* pstr)
。函数将打印出匹配的括号对。比如:字符串”a(bc(d)ef(12)g)”就存在3对匹配的括号对,分别是:
1. 位置4上的(与位置6上的)匹配。打印4 6即可。
1. 位置9上的(与位置12上的)匹配。打印9 12即可。
1. 位置1上的(与位置14上的)匹配。打印1 14即可。
明确这个模块的功能,明确其输入以及输出。
尽量去除与其他模块的耦合关系,确保独立性。
我会首先编写输入和输出的接口函数,然后由粗到精,逐步实现细节算法。
同时还需要编写模块的测试代码,保证交付的可靠性。
imread(), imwrite(), imshow()
Matlab引擎方式(Matlab后台程序为服务器,VC前端为客户端,C/S结构)、Matlab编译器(将Matlab源代码编译为C++可以调用的库文件)及COM组件(Matlab生成COM组件,VC调用)
.*
和 *
的区别?.*
表示矩阵元素分别相乘,要求两个矩阵具有相同的shape。*
表示矩阵相乘。
有四人装药丸的罐子,每个药丸都有一定的重量,被污染的药丸是没被污染的重量+1.只称量一次,如何判断哪个罐子的药被污染了?
答:在四个罐子里面分别取1、2、3、4颗药丸,然后进行称量。如果称量结果比实际(污染前)重了n,就是第n罐被污染了。 (因为每加一颗被污染的药丸就增加1所以增加n就是增加n颗就是在第n个罐子里拿的)
一群人开舞会,每人头上都戴着一顶帽子。帽子只有黑白两种,黑的至少有一顶。每个人都能看到其他人帽子的颜色,却看不到自己的。主持人先让大家看看别人头上戴的是什么帽子,然后关灯,如果有人认为自己戴的是黑帽子,就打自己一个耳光。第一次关灯,没有声音。于是再开灯,大家再看一遍,关灯时仍然鸦雀无声。一直到第三次关灯,才有劈劈啪啪打耳光的声音响起。问有多少人戴着黑帽子?
解:假如只有一个人戴黑帽子,那他看到所有人都戴白帽,在第一次关灯时就应自打耳光,所以应该不止一个人戴黑帽子;如果有两顶黑帽子,第一次两人都只看到对方头上的黑帽子,不敢确定自己的颜色,但到第二次关灯,这两人应该明白,如果自己戴着白帽,那对方早在上一次就应打耳光了,因此自己戴的也是黑帽子,于是也会有耳光声响起;可事实是第三次才响起了耳光声,说明全场不止两顶黑帽,依此类推,应该是关了几次灯,有几顶黑帽。
让工人为你工作7天,给工人的回报是一根金条。金条平分成相连的7段,你必须在每天结束时给他们一段金条,如果只许你两次把金条弄断,你如何给你的工人付费?
答:分成1、2、4段。利用1,2,4可以组合成1,2,3,4,5,6,7
下面玩一个拆字游戏,所有字母的顺序都被打乱。你要判断这个字是什么。假设这个被拆开的字由5个字母组成:
1. 共有多少种可能的组合方式?
2. 如果我们知道是哪5个字母,那会怎么样?
3. 找出一种解决这个问题的方法。
个人解答:
1. A55=5∗4∗3∗2∗1=120 A 5 5 = 5 ∗ 4 ∗ 3 ∗ 2 ∗ 1 = 120
1. 会依靠英文字母的规则等大致弄几种可能性出来。
1. 将弄出来的可能性的单词进行查找。
解:很大程度上取决于下水道的形状,一般为了使得各个方向的管子都可以接入到下水道中,所以下水道设计成了圆柱形,所以盖子相应的也是圆形。且圆形比较省材料,便于运输。
首先在纸上画出了CNTOWER的草图,然后快速估算支架和各柱的高度,以及球的半径,算出各部分体积,然后和各部分密度运算,最后相加得出一个结果。