C++编程提升之路第二课——数学

一:前言

众所周知,数学在我们编程当中是非常重要的。一些题目,你用纯暴力肯定会超时,而经过数学优化后复杂度就会降低很多。

二:欧几里得算法

1:介绍

  • 其实这个算法就是 g c d ( a , b ) = g c d ( b , a   m o d   b ) gcd(a,b)=gcd(b,a~mod~b) gcd(a,b)=gcd(b,a mod b) 但是要证明它并不是很容易。

  • 我们可以先证明: g c d ( a , b ) = g c d ( b , a − b ) gcd(a,b)=gcd(b,a-b) gcd(a,b)=gcd(b,ab)

    • 我们设 d = g c d ( a , b ) d=gcd(a,b) d=gcd(a,b) ,则 a = d ⋅ a 1 a=d\cdot a1 a=da1 , b = d ⋅ b 1 b=d\cdot b1 b=db1 g c d ( a 1 , b 1 ) = 1 gcd(a1,b1)=1 gcd(a1,b1)=1

    • a − b = d ⋅ e s a 1 − d ⋅ b 1 = d ⋅ ( a 1 − b 1 ) a-b=d \cdot es a1-d \cdot b1=d \cdot (a1-b1) ab=desa1db1=d(a1b1)

    • 那么 a − b a-b ab b b b 都有一个公因子 d d d,接下来只需证明:

    • g c d ( b 1 , a 1 − b 1 ) = 1 gcd(b1,a1-b1)=1 gcd(b1,a1b1)=1

    • 我们采用反证法

    • b 1 = β ⋅ λ b1=\beta \cdot \lambda b1=βλ, a 1 − b 1 = α ⋅ λ ( λ > 1 ) a1-b1=\alpha \cdot \lambda(\lambda>1) a1b1=αλ(λ>1)

    • a 1 = a 1 − b 1 + b 1 = λ ⋅ ( α + β ) a1=a1-b1+b1=\lambda \cdot (\alpha + \beta) a1=a1b1+b1=λ(α+β)

    • 因为之前我们已经定义 g c d ( a 1 , b 1 ) = 1 gcd(a1,b1)=1 gcd(a1,b1)=1 b 1 = λ ⋅ β b1=\lambda \cdot \beta b1=λβ

    • 那么 λ \lambda λ只能等于1

    • 与命题不符,得证

  • ∵ g c d ( a , b ) = g c d ( b , a − b ) \because gcd(a,b)=gcd(b,a-b) gcd(a,b)=gcd(b,ab)

  • ∴ g c d ( a , b ) = g c d ( b , a − b ) = g c d ( b , a − 2 b ) = g c d ( b , a − 3 b ) . . . \therefore gcd(a,b)=gcd(b,a-b)=gcd(b,a-2b)=gcd(b,a-3b)... gcd(a,b)=gcd(b,ab)=gcd(b,a2b)=gcd(b,a3b)...

  • ∴ g c d ( a , b ) = g c d ( b , a   m o d   b ) \therefore gcd(a,b)=gcd(b,a~mod~b) gcd(a,b)=gcd(b,a mod b)

  • 得证!

  • 根据此定理,我们可以快速求出两个数的 g c d gcd gcd

2:code

  • 代码:
#include<bits/stdc++.h>
using namespace std;
inline int gcd(int n,int m){
	if(b==0)return a;
	return gcd(b,a%b);
}
int main(){
	int n,m;
	cin>>n>>m;
	cout<<gcd(n,m);
	return 0;
}

三:扩展欧几里得算法

1:介绍

  • 它就是求 a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b)
    • 显然,当 b = 0 b=0 b=0 时,则原方程变为 a x = a ax=a ax=a,解为 { x = 1 y = 0 \begin{cases} x=1\\ y=0\\ \end{cases} {x=1y=0
    • b ≠ 0 b\ne0 b=0,且有 x 1 , y 1 x_1,y_1 x1,y1满足 a   m o d   b ⋅ x 1 + b ⋅ y 1 = g c d ( b , a   m o d   b ) a~mod~b \cdot x_1+b \cdot y1=gcd(b,a~mod~b) a mod bx1+by1=gcd(b,a mod b),则有解 { x = x 1 y = y 1 − x 1 ⋅ f l o o r ( a / b ) \begin{cases} x=x_1\\y=y_1-x_1 \cdot floor(a/b)\\\end{cases} {x=x1y=y1x1floor(a/b)
    • 下面为证明过程
      • ∵ ( a   m o d   b ) ⋅ x 1 + b ⋅ y 1 = g c d ( b , a   m o d   b ) \because(a~mod~b)\cdot x_1+b \cdot y_1=gcd(b,a~mod~b) (a mod b)x1+by1=gcd(b,a mod b)
      • ∴ ( a − f l o o r ( a / b ) ⋅ b ) ⋅ x 1 + b ⋅ y 1 = g c d ( a , b ) \therefore(a-floor(a/b)\cdot b) \cdot x_1+b\cdot y_1=gcd(a,b) (afloor(a/b)b)x1+by1=gcd(a,b)
      • ∴ a ⋅ x 1 + b ⋅ ( y 1 − x 1 ⋅ ( f l o o r ( a / b ) ) = g c d ( a , b ) \therefore a\cdot x_1+b\cdot (y_1-x_1\cdot (floor(a/b))=gcd(a,b) ax1+b(y1x1(floor(a/b))=gcd(a,b)
      • 证毕
    • 根据此结论,我们可以一直递归,直至 b = 0 b=0 b=0

2:code

  • 代码:
#include<bits/stdc++.h>
using namespace std;
void ex_gcd(int a,int b,int &x,int &y){//求a*x+b*y=gcd(a,b)的整数解 
	if(!b){
		x=1;
		y=0;
		return;
	}
	ex_gcd(b,a%b,y,x);
	y-=(a/b)*x;
}
int main(){
	int a,b,x,y;
	cin>>a>>b;
	ex_gcd(a,b,x,y);
	cout<<x<<' '<<y;
	return 0;
}

3:拓展1

  • 题目:解方程 a x + b y = c ax+by=c ax+by=c
    • 思路:我们设 d = g c d ( a , b ) d=gcd(a,b) d=gcd(a,b) ,再把等式两边同时乘上 d c \frac{d}{c} cd
    • 则原方程化为 a ⋅ d c ⋅ x + b ⋅ d c ⋅ y = g c d ( a , b ) a\cdot \frac{d}{c} \cdot x+b\cdot\frac{d}{c}\cdot y=gcd(a,b) acdx+bcdy=gcd(a,b)
    • 求解一个 a ⋅ x ′ + b ⋅ y ′ = g c d ( a , b ) a\cdot x'+b\cdot y'=gcd(a,b) ax+by=gcd(a,b)
    • 则方程的解为 { x = x ′ ⋅ d c y = y ′ ⋅ d c \begin{cases} x=x'\cdot\frac{d}{c}\\ y=y'\cdot\frac{d}{c}\\ \end{cases} {x=xcdy=ycd
    • c ∤ d c\nmid d cd,则原方程无解

4:拓展2

  • 题目:解方程 a ⋅ x ≡ b ( m o d p ) a \cdot x \equiv b \pmod p axb(modp)
    • 思路:此题非常简单,将它化为拓展1
    • 原方程化为 a x + p y = b ax+py=b ax+py=b 再用拓展1解即可
    • b = 1 b=1 b=1 ,则此题化为了求解 a a a m o d   p mod~p mod p 意义下的逆元。

四:逆元的求法

  • 逆元的定义为若 a ⋅ x ≡ b ( m o d p ) a \cdot x \equiv b \pmod p axb(modp)
  • 求解方式有一下几种:

1:费马小定理(p为质数)

  • 费马小定理: a p − 1 ≡ 1 ( m o d p ) a^{p-1} \equiv 1 \pmod p ap11(modp),证明此处省略
  • a ⋅ a p − 2 ≡ 1 ( m o d p ) a\cdot a^{p-2} \equiv 1 \pmod p aap21(modp)
  • ∴ a \therefore a a m o d   p mod~p mod p意义下的逆元为 a p − 2 a^{p-2} ap2
  • 只需使用一个快速幂就好了
  • 代码:
#include<bits/stdc++.h>
using namespace std;
int power(int a,int b,int p){
	int ans=1;
	while(b){
		if(b&1)ans=ans*a%p;
		a=a*a%p;b>>=1;
	}
	return ans;
}
int inv(int x,int p){
	return power(x,p-2,p);
}
int main(){
	int x,p;
	cin>>x>>p;
	cout<<inv(x,p);
	return 0;
}

2:线性求逆元(p为质数)

  • 当我们要求 1 1 1 n n n 中所有的数的逆元
  • 我们用一个 i n v [ i ] inv[i] inv[i] 来存 i i i 的逆元
  • 设我们要求的是 i n v [ i ] inv[i] inv[i] ,且 p = k ⋅ i + r ( r < i ) p=k\cdot i+r(r<i) p=ki+r(r<i)
  • 又因为 p p p 为质数,则 0 < r < i 0<r<i 0<r<i
  • k = ⌊ x ⌋ , r = p   m o d   i , k × i + r ≡ 0 ( m o d p ) k=\lfloor x \rfloor,r=p~mod~i,k\times i+r \equiv 0\pmod p k=x,r=p mod i,k×i+r0(modp)
  • 将等式两边同时乘以 i , r i,r i,r 的逆元
  • k ⋅ i n v [ r ] + i n v [ i ] ≡ 0 ( m o d p ) ⇒ i n v [ i ] ≡ − k ⋅ i n v [ r ] ( m o d p ) d ⇒ i n v [ i ] ≡ ⌊ p i ⌋ ⋅ i n v [ p   m o d   i ] ( m o d p ) k\cdot inv[r]+inv[i] \equiv 0\pmod p\Rightarrow inv[i]\equiv -k\cdot inv[r] \pmod pd\Rightarrow inv[i]\equiv \lfloor \frac{p}{i} \rfloor \cdot inv[p~ mod~i] \pmod p kinv[r]+inv[i]0(modp)inv[i]kinv[r](modp)dinv[i]ipinv[p mod i](modp)
  • ∴ i n v [ i ] = ( p − ⌊ p i ⌋ ⋅ i n v [ p   m o d   i ] ) \therefore inv[i]=(p- \lfloor \frac{p}{i} \rfloor \cdot inv[p~ mod~i] ) inv[i]=(pipinv[p mod i])
  • 根据此递推式,即可写出代码
#include<bits/stdc++.h>
using namespace std;
const int N=3e6+7;
int n,p;
long long inv[N];
int main(){
	cin>>n>>p;
	inv[1]=1;
	for(int i=2;i<=n;i++)
	inv[i]=(p-p/i)*inv[p%i]%p;
	for(int i=1;i<=n;i++){
		cout<<inv[i]<<"\n";
	}
	return 0;
}

3:扩展欧几里得求逆元

  • 根据我们之前学的扩展欧几里得拓展2的例题:
  • a ⋅ x ≡ b ( m o d p ) a \cdot x \equiv b \pmod p axb(modp)
  • 将b换为1即可
#include<bits/stdc++.h>
using namespace std;
void ex_gcd(int a,int b,int &x,int &y){//求a*x+b*y=gcd(a,b)的整数解 
	if(!b){
		x=1;
		y=0;
		return;
	}
	ex_gcd(b,a%b,y,x);
	y-=(a/b)*x;
}
int get_inv(int a,int p){
	int x,y;
	ex_gcd(a,p,x,y);
	x=(x%p+p)%p;//求最小的逆元
	return x; 
} 
int main(){
	int a,p;
	cin>>a>>p;
	cout<<get_inv(a,p);;
	return 0;
}

5:结语

想必通过今天作者对大家的总结,大家的数学水平都应该有一定的提升了吧,写code的能力估计也强了好几倍,希望在这段时间了,我们一起努力,一起进步!有什么错误还请各位大佬指出。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
第1章 界面外观   实例1 带图标的菜单   实例2 显示倾斜文字   实例3 文字的颜色渐变   实例4 设置并叠加透明图片   实例5 颜色渐变进度条   实例6 透明窗体  第2章 界面与图像控制   实例7 调色程序   实例8 颜色下拉框   实例9 模拟拷贝进程   实例10 通用对话框   实例11 窗体分割   实例12 实现QQ程序的抽屉效果   实例13 以动画方式弹出/关闭窗口   实例14 半透明窗体   实例15 获得指定点颜色   实例16 判知图片的大小   实例17 图片的伸缩显示   实例18 游览大图   实例19 放大局部图形   实例20 屏幕抓图   实例21 裁剪位图   实例22 填充区域图像   实例23 列表项的提示条   实例24 浮动的鼠标提示   实例25 控制工具栏的按钮组   实例26 工具栏上设置下拉按钮   实例27 使窗体保持在最前   实例28 模仿Windows任务栏   实例29 定义光标热区   实例30 拖放选中对象  第3章 多媒体控制   实例31 调节系统音量   实例32 控制混音效果   实例33 播放WAV文件   实例34 再现Windows的CD播放器   实例35 小解霸VCD典型控制   实例36 播放rm文件  第4章 时间控制   实例37 文字逐个出现模仿打字   实例38 嵌入式电子钟   实例39 程序中嵌入日历   实例40 毫秒级的控制   实例41 读写系统时间   实例42 同步网络时间  第5章 操作系统与硬件   实例43 编写屏保程序   实例44 屏蔽系统热键和隐藏任务栏   实例45 动态调整屏幕分辨率   实例46 获取系统硬件信息   实例47 编辑注册表信息   实例48 重启动和关闭计算机   实例49 获取Windows版本号和运行模式   实例50 枚举可用字体  第6章 程序控制   实例51 向导程序   实例52 系统托盘程序   实例53 隐藏程序不被关闭程序发现   实例54 枚举系统正在运行的程序   实例55 启动并控制其他Exe程序   实例56 禁止运行程序多个实例   实例57 禁止窗体右上角各按钮   实例58 多线程方式同时进行多项任务   实例59 线程优先级示例——赛马   实例60 利用剪贴板实现Exe程序间的数据交换   实例61 通过内存映射实现Exe程序间的数据交换   实例62 通过消息机制实现Exe程序间的数据交换  第7章 磁盘文件   实例63 获取驱动器序列号   实例64 获取磁盘空间数据   实例65 判别并定位到光驱(软驱)   实例66 递归法遍历磁盘目录   实例67 获得文件属性   实例68 删除不为空的目录   实例69 快速检索指定文件   实例70 拷贝、删除和移动文件   实例71 读写INI文件   实例72 读写大块资料(二进制)文件   实例73 文件变更通知  第8章 数据库   实例74 格式化数字   实例75 中文大写数字   实例76 存取图像字段   实例77 ADO控制Access数据库   实例78 SQL语句中设置时段检索条件   实例79 SQL语句中设置字符串检索条件   实例80 SQL语句中设置多个字符串检索条件   实例81 SQL语句嵌套   实例82 代码控制链接ODBC  第9章 网络与通信   实例83 获取网卡地址   实例84 获得主机名和IP地址   实例85 端口扫描   实例86 判断网址是否有效   实例87 枚举局域网内计算机   实例88 连续批量Ping测试   实例89 设置IE的标题   实例90 收发送电子邮件   实例91 FTP上传下载   实例92 网络聊天:WINSOCK-TCP   实例93 广播信息:WINSOCK-UDP   实例94 电话拨号上网  第10章 数学算法   实例95 进制转换   实例96 随机选号   实例97 统计中英文字符数  第11章 鼠标和键盘   实例98 鼠标位置追踪   实例99 代码控制光标   实例100 模拟鼠标的单双击   实例101 模拟键盘输入   实例102 限定鼠标区域   实例103 截获鼠标移开事件   实例104 截获键盘信息  第12章 程序发布   实例105 产生程序序列号   实例106 建立一个快捷方式   实例107 设置程序为自动被执行   实例108 注册与卸载OCX   实例109 限定程序的使用时限   实例110 在IE工具栏中加入快捷图标
目录 第1章 matlab概述. 1.1 matlab的发展历程 1.2 matlab产品组成及语言特点 1.2.1 matlab的主要产品构成 1.2.2 matlab语言的特点 1.3 matlab 7.0的新功能和新产品 1.3.1 matlab 7.0的新功能 1.3.2 matlab升级及新增的模块 1.4 小结 第2章 matlab程序设计及代码优化 2.1 matlab的表达式和变量 2.1.1 表达式 2.1.2 变量 2.2 细胞数组与结构数组 2.2.1 细胞数组 2.2.2 结构数组 2.3 类与对象 2.4 流程控制 2.4.1 for循环结构 2.4.2 while循环结构 .2.4.3 if-else-end分支结构 2.4.4 switch-case结构 2.4.5 try-catch结构 2.5 m文件编程 2.6 m文件编程规范 2.7 m文件评述器 2.8 提高m文件执行效率的技巧 2.8.1 矢量化操作 2.8.2 给数组预定义维 2.8.3 下标或者索引操作 2.8.4 尽量多使用函数文件而少使用非脚本文件 2.8.5 将循环体中的内容转换为c-mex 2.8.6 内存优化 2.9 小结 第3章 matlab混合编程简介 3.1 进行混合编程的出发点 3.2 matlab应用程序接口简介 3.3 几种常见的混合编程方法简介 3.3.1 使用matlab自带的matlab compiler 3.3.2 利用matlab引擎 3.3.3 利用activex控件 3.3.4 利用mat文件 3.3.5 c-mex 3.3.6 利用mideva/matcom 3.3.7 利用matrix[lib]实现混合编程 3.3.8 利用matlab add-in 3.3.9 matlab com builder 3.3.10 matlab和excel混合编程 3.4 小结 第4章 c-mex编程 4.1 c-mex简介 4.2 mex文件系统的配置 4.3 mex文件的结构和运行 4.3.1 mex文件结构 4.3.2 mex函数的执行流程 4.3.3 mex文件的结构和使用 4.3.4 mex文件与独立应用程序的区别 4.4 c语言mex函数 4.5 c-mex混合编程 4.6 visual c++中mex文件的建立和调试 4.6.1 visual c++中mex程序的建立和环境设置 4.6.2 mex程序的调试 4.6.3 mex独立应用程序的发布 4.7 mex编程实例 4.8 小结 第5章 通过matlab引擎实现混合编程 5.1 matlab引擎简介 5.2 matlab引擎库函数 5.3 visual c++调用matlab引擎时的环境设置 5.4 matlab引擎类的封装 5.4.1 cmatlabeng类的定义和实现代码 5.4.2 cmatlabeng说明 5.4.3 cmatlabeng说明和使用方法 5.5 应用实例 5.6 小结 第6章 mat文件实现数据共享 6.1 mat文件简介 6.2 操作mat文件 6.2.1 mat文件格式 6.2.2 操作mat文件的matlab api 6.3 visual c++调用mat时的环境设置 6.4 实例 6.5 小结 第7章 利用mideva实现混合编程 7.1 mideva简介 7.2 mideva的安装 7.3 mideva环境下m文件到dll/exe文件的转换 7.4 visual c++环境下使用mideva混合编程 7.4.1 混合编程环境的设置 7.4.2 通过外壳函数调用 7.5 matrix[lib] 7.6 混合编程实例 7.7 小结 第8章 利用matrix[lib]实现混合编程 8.1 matrix[lib]简介 8.2 matrix[lib]与visual c++混合编程 8.2.1 matrix[lib]的安装 8.2.2 visual c++环境配置 8.2.3 初始化库 8.3 matrix[lib]函数使用参考 8.3.1 矩阵操作 8.3.2 库常量 8.3.3 访问库函数 8.3.4 矩阵i/o 8.3.5 图形函数 8.4 混合编程实例 8.5 matlab数学库 8.5.1 简介 8.5.2 visual c++工程中调用matlab数学函数库的环境设置 8.6 小结.. 第9章 通过matlab add-in实现混合编程 9.1 matlab add-in简介 9.2 matlab add-in安装和在visual c++中的环境设置 9.3 通过matlab add-in生成独立应用程序 9.4 matlab add-in实例 9.5 小结 第10章 matlab和delphi混合编程 10.
第1章 Visual C++与数字图像处理 1 1.1 数字图像处理概述 2 1.1.1 图像与数字图像 2 1.1.2 数字图像处理研究的内容 4 1.1.3 数字图像处理的应用 6 1.2 Visual C++概述 8 1.2.1 C++语言简介 8 1.2.2 Visual C++简介 16 1.2.3 Visual C++ 2005 集成开发环境 19 1.3 在Visual C++中处理数字图像 22 1.3.1 位图和调色板 22 1.3.2 图形设备接口 23 1.3.3 OpenCV 26 1.4 本章小结 26 第2章 Visual C++ 2005基础知识 27 2.1 利用向导生成应用程序 28 2.1.1 创建新项目 28 2.1.2 编译并运行工程 35 2.2 添加资源 36 2.2.1 新建资源 36 2.2.2 导入资源 38 2.3 MFC编程基础 38 2.3.1 MFC应用程序框架 39 2.3.2 Windows消息和事件驱动 40 2.3.3 常用消息 41 2.3.4 MFC的消息映射 42 2.4 消息与事件响应 44 2.4.1 添加类 44 2.4.2 添加类成员 45 2.4.3 添加消息响应 46 2.4.4 添加事件 47 2.4.5 添加函数重写 48 2.4.6 手动添加消息响应 50 2.5 对话框的使用 51 2.5.1 创建并编辑对话框资源 51 2.5.2 模式对话框和无模式对话框 55 2.5.3 消息对话框 57 2.5.4 共用对话框 59 2.6 常用控件的使用 64 2.6.1 按钮类控件 64 2.6.2 文本框 67 2.6.3 列表框 70 2.6.4 组合框 74 2.6.5 静态类控件 76 2.7 菜单栏和工具栏 77 2.7.1 菜单栏的使用 77 2.7.2 工具栏的使用 83 2.8 本章实例:简单的画图程序 87 2.8.1 实例预览 88 2.8.2 概要设计 88 2.8.3 完成实例编码 91 2.9 本章小结 98 第3章 认识色彩空间 99 3.1 颜色的基本知识 100 3.1.1 颜色的定义 100 3.1.2 颜色的属性 102 3.2 常用色彩空间简介 103 3.2.1 RGB颜色空间 103 3.2.2 CMY/CMYK颜色空间 105 3.2.3 HSV/HSB(HSI/HCI/HSL) 颜色空间 106 3.2.4 CIE系列颜色空间 109 3.2.5 YUV/YCbCr颜色空间 111 3.3 色彩空间的转换方法 112 3.3.1 RGB转换到HSV的方法 113 3.3.2 RGB转换到HSI的方法 114 3.3.3 RGB转换到YUV的方法 115 3.3.4 RGB转换到YCbCr的方法 116 3.4 本章实例:Photoshop 色彩编辑器 118 3.4.1 需求分析 118 3.4.2 概要设计 119 3.4.3 完成实例编码 121 3.5 本章小结 130 第4章 图像文件格式 131 4.1 图像文件概述 132 4.1.1 图像文件 132 4.1.2 图像文件的一般结构 132 4.1.3 图像文件的常用参数 133 4.2 BMP文件格式 134 4.2.1 文件结构 135 4.2.2 文件头和信息头 135 4.2.3 主要参数 136 4.3 GIF文件格式 136 4.3.1 GIF格式简介 137 4.3.2 GIF文件结构 137 4.3.3 GIF文件块的结构 138 4.4 PNG文件格式 142 4.4.1 PNG格式简介 142 4.4.2 PNG文件结构 143 4.4.3 PNG中的关键数据块 144 4.5 图像的压缩编码 146 4.5.1 Huffman编码 147 4.5.2 LZW编码 148 4.5.3 行程编码 151 4.5.4 离散余弦变换 151 4.6 JPEG文件格式 153 4.6.1 JPEG文件概述 153 4.6.2 JPEG编码/解码的理论基础 153 4.6.3 JPEG文件的格式 160 4.7 本章实例:JPEG解码程序 163 4.7.1 概要设计 163 4.7.2 完成实例编码 169 4.8 本章小结 188 第5章 使用DIB处理数字图像 189 5.1 设备相关位图和设备 无关位图 190 5.1.1 设备相关位图(DDB) 190 5.1.2 设备无关位图(DIB) 190 5.2 CBitmap类 190 5.2.1 创建DDB 191 5.2.2 CBitmap中的成员函数 193 5.2.3 应用DDB显示图像 193 5.2.4 应用DDB显示大图像 195 5.3 进一步了解DIB 203 5.3.1 DIB的结构 203 5.3.2 DIB信息段 203 5.3.3 位图数据 205 5.3.4 与DIB有关的函数 206 5.4 本章实例:DIB类的封装 208 5.4.1 设计 208 5.4.2 构造函数 210 5.4.3 DIB位图的显示 214 5.4.4 BMP文件的存储 215 5.5 本章小结 216 第6章 使用GDI+处理数字图像 217 6.1 GDI+简介 218 6.1.1 GDI+概述 218 6.1.2 GDI+的结构 218 6.2 在Visual C++中应用GDI+ 219 6.2.1 GDI+ 在Visual C++ 2005 中的配置方法 219 6.2.2 在Visual 6.0中使用GDI+ 221 6.3 GDI+基础 222 6.3.1 Graphics类 222 6.3.2 GDI+的基本数据类型 225 6.3.3 GDI+中的颜色 226 6.4 GDI+处理图像的基本方法 228 6.4.1 GDI+的图像类 228 6.4.2 创建图像对象 229 6.4.3 图像的显示和缩放 232 6.4.4 图像的基本处理方法 237 6.5 处理图像的色彩 244 6.5.1 ColorMatrix结构体 244 6.5.2 改变图像的透明度 245 6.5.3 将图像转换为灰度图 249 6.5.4 改变图像的亮度 251 6.5.5 改变图像的对比度 253 6.6 本章实例:播放GIF动画 255 6.6.1 播放原理分析 255 6.6.2 处理过程 256 6.6.3 具体实现 257 6.7 本章小结 260 第7章 使用OpenCV处理 数字图像 261 7.1 OpenCV简介 262 7.1.1 OpenCV概述 262 7.1.2 OpenCV的特点 263 7.1.3 OpenCV的命名规则 263 7.1.4 OpenCV的应用举例 264 7.2 OpenCV的安装与配置 266 7.2.1 OpenCV 在Visual C++ 6.0 下的安装与配置 266 7.2.2 OpenCV 在Visual C++ 2005 下的安装与配置 268 7.3 OpenCV的结构 271 7.3.1 OpenCV的体系结构 271 7.3.2 OpenCV的函数结构 271 7.3.3 OpenCV的功能结构 273 7.3.4 OpenCV的数据结构 274 7.4 本章实例:利用OpenCV 显示图像 275 7.4.1 图像文件的载入与显示 275 7.4.2 图像文件的创建、 保存和复制 277 7.5 本章小结 282 第8章 常见图像显示特效 283 8.1 显示特效概述 284 8.1.1 显示特效基础 284 8.1.2 显示特效过程 286 8.1.3 显示特效类 287 8.2 扫描显示特效 289 8.2.1 特效预览 289 8.2.2 基本原理和实现方法 289 8.2.3 编程实现 290 8.3 移动显示特效 292 8.3.1 特效预览 292 8.3.2 基本原理和实现方法 292 8.3.3 编程实现 293 8.4 百叶窗显示特效 295 8.4.1 特效预览 295 8.4.2 基本原理和实现方法 295 8.4.3 编程实现 297 8.5 栅条显示特效 298 8.5.1 特效预览 298 8.5.2 基本原理和实现方法 299 8.5.3 编程实现 300 8.6 马赛克显示特效 301 8.6.1 特效预览 301 8.6.2 基本原理和实现方法 302 8.6.3 编程实现 303 8.7 雨滴显示特效 304 8.7.1 特效预览 304 8.7.2 基本原理和实现方法 304 8.7.3 编程实现 305 8.8 本章实例:类似ACDSee 的图像浏览工具 306 8.8.1 实例预览 306 8.8.2 概要设计 307 8.8.3 完成实例编码 311 8.9 本章小结 324 第9章 图像的点运算 325 9.1 灰度直方图 326 9.1.1 灰度直方图 326 9.1.2 基本原理 328 9.1.3 编程实现 328 9.2 灰度线性变换 338 9.2.1 基本原理 338 9.2.2 编程实现 341 9.3 灰度非线性变换 344 9.3.1 灰度对数变换 344 9.3.2 灰度幂次变换 350 9.3.3 灰度指数变换 353 9.4 灰度阈值变换 354 9.4.1 基本原理 355 9.4.2 编程实现 355 9.5 灰度拉伸 357 9.5.1 基本原理 358 9.5.2 编程实现 360 9.6 灰度均衡 364 9.6.1 基本原理 364 9.6.2 编程实现 365 9.7 本章小结 366 第10章 对图像进行几何变换 367 10.1 图像几何变换的基本理论 368 10.1.1 图像几何变换概述 368 10.1.2 图像几何变换的数学描述 370 10.2 图像的平移变换 371 10.2.1 效果预览 371 10.2.2 基本原理 371 10.2.3 编程实现 373 10.3 图像的镜像变换 377 10.3.1 效果预览 377 10.3.2 基本原理 378 10.3.3 编程实现 379 10.4 图像的转置 383 10.4.1 效果预览 383 10.4.2 基本原理 384 10.4.3 编程实现 385 10.5 图像的缩放 386 10.5.1 效果预览 387 10.5.2 基本原理 387 10.5.3 插值算法介绍 388 10.5.4 编程实现 392 10.6 图像的旋转 398 10.6.1 效果预览 398 10.6.2 基本原理 398 10.6.3 编程实现 403 10.7 使用GDI+实现图像的 几何变换 409 10.7.1 GDI+的变换操作 409 10.7.2 平移 410 10.7.3 缩放 412 10.7.4 旋转 413 10.7.5 变换的组合 417 10.7.6 利用矩阵进行其他 几何变化 419 10.8 本章小结 422 第11章 图像的增强处理 423 11.1 图像的简单平滑 424 11.1.1 邻域处理的基本概念 424 11.1.2 图像的简单平滑原理 427 11.1.3 图像简单平滑的算法实现 427 11.2 图像的高斯平滑 431 11.2.1 平滑线性滤波器 432 11.2.2 高斯平滑的原理 432 11.2.3 高斯平滑的算法实现 433 11.3 图像的中值滤波 436 11.3.1 统计排序滤波器 437 11.3.2 图像中值滤波的原理 437 11.3.3 图像中值滤波的算法实现 439 11.4 应用OpenCV对图像 进行平滑处理 445 11.4.1 函数描述 445 11.4.2 概要设计 446 11.4.3 编码实现 446 11.5 拉普拉斯边缘增强 452 11.5.1 图像的锐化 452 11.5.2 图像拉普拉斯锐化的原理 452 11.5.3 图像拉普拉斯锐化的 算法实现 453 11.6 Sobel边缘细化 457 11.6.1 Sobel边缘细化的原理 457 11.6.2 Sobel边缘细化的 编程实现 459 11.7 本章小节 464 第12章 常见滤镜效果 465 12.1 图像的反色效果 466 12.1.1 底片效果 467 12.1.2 实现方法及原理 467 12.1.3 编程实现 467 12.2 图像的雕刻效果 469 12.2.1 雕刻效果 469 12.2.2 实现方法及原理 469 12.2.3 编程实现 470 12.3 图像的黑白效果 472 12.3.1 黑白效果 472 12.3.2 实现方法及原理 473 12.3.3 编程实现 473 12.4 图像的雾化效果 475 12.4.1 雾化效果 475 12.4.2 图像点阵的随机化处理 476 12.4.3 编程实现 476 12.5 图像的马赛克效果 483 12.5.1 马赛克效果 483 12.5.2 实现方法及原理 483 12.5.3 编程实现 484 12.6 图像的素描效果 487 12.6.1 素描效果 487 12.6.2 实现方法及原理 487 12.6.3 编程实现 487 12.7 本章小结 490 第13章 边缘检测和轮廓跟踪 491 13.1 边缘检测 492 13.1.1 边缘检测的基本概念 492 13.1.2 常规边缘检测 493 13.1.3 带方向的边缘检测 498 13.1.4 拉普拉斯算子 503 13.2 Hough变换 509 13.2.1 Hough变换的原理 509 13.2.2 编程实现 515 13.3 种子算法 520 13.3.1 算法介绍 520 13.3.2 编程实现 523 13.4 轮廓跟踪 526 13.4.1 区域表示方法 526 13.4.2 单区域跟踪 536 13.4.3 多区域跟踪 539 13.5 本章实例:应用OpenCV 进行边缘检测 541 13.5.1 Canny准则 541 13.5.2 Canny算法 542 13.5.3 在OpenCV中使用Canny 算法 543 13.6 本章小结 548 第14章 图像的形态处理 549 14.1 数学形态 550 14.2 一些必要的概念和 符号约定 550 14.3 图像的腐蚀 554 14.3.1 腐蚀原理 554 14.3.2 编程实现 557 14.4 图像的膨胀 562 14.4.1 膨胀原理 562 14.4.2 编程实现 565 14.5 腐蚀和膨胀的性质及应用 568 14.5.1 腐蚀和膨胀的代数性质 568 14.5.2 腐蚀和膨胀的应用 571 14.6 开运算和闭运算 577 14.6.1 开运算 578 14.6.2 闭运算 579 14.6.3 编程实现 580 14.6.4 开运算和闭运算的 代数性质 582 14.7 图像形态的其他运算 584 14.7.1 击中/不击中运算 584 14.7.2 细化处理 588 14.8 本章实例:应用OpenCV 进行形态处理 592 14.8.1 函数描述 592 14.8.2 概要设计 592 14.8.3 编码实现 593 14.9 本章小结 598 第15章 图像分割与目标识别 599 15.1 图像的分割 601 15.1.1 基于幅度的图像分割 601 15.1.2 基于区域的图像分割 606 15.1.3 基于形态分水岭的 图像分割 611 15.2 图像的匹配 614 15.2.1 基本概念 614 15.2.2 模板匹配算法 615 15.2.3 序贯相似性检测算法 616 15.2.4 幅度排序算法 618 15.3 模式的识别 620 15.3.1 基本概念 620 15.3.2 统计模式识别 621 15.3.3 其他模式识别方法简介 627 15.4 本章实例:静态人脸 检测程序 628 15.4.1 人脸检测概述 628 15.4.2 算法分析 629 15.4.3 应用OpenCV进行 人脸检测 633 15.5 本章小结 640
### 回答1: 本章主要针对初者,简要介绍了c/c++的基本语法和常见的编译错误。首先,介绍了程序的基本结构和常用的数据类型。c语言的基本语句包括赋值语句、条件语句和循环语句等,这些语句都可以组成程序的逻辑结构。接下来,介绍了函数的定义和调用,以及参数传递的方式。对于c++,还介绍了一些面向对象的概念,例如类、对象、成员函数等。同时,也提到了头文件和命名空间的使用方法。 在编程过程中,常常会出现各种编译错误,例如语法错误、类型不匹配、语义错误等,需要会如何查看和解决这些错误。此外,还介绍了调试工具和各种常用的运算符和表达式,这些都是初者必须掌握的基础知识。 总的来说,本章是关于c/c++快速入门的一篇简介性文章。虽然只是涉及到了基础的语法和知识点,但对于初者而言是一个很好的起点。在习过程中需要不断实践,积累经验,并不断深入了解更高级的编程技术和工具。 ### 回答2: C/C++是一种广泛使用的编程语言,它具有高效、灵活、可移植等特点,在各个领域得到广泛应用。C语言是C++语言的基础,在C++之前,需要先掌握C语言的基础知识。 本文介绍的是C/C++教程中的第二章——快速入门C/C++。在这一章节中,我们将介绍C语言的基本语法、变量、运算符和流程控制语句等基础知识。以下是C语言的一些基本知识点。 C语言的基本语法: C语言程序由多个函数组成,其中一个函数必须命名为main(),程序从该函数开始执行。C程序中的语句以分号结束,注释使用“//”表示单行注释,“/* */”表示多行注释。 变量和数据类型: C语言中变量的定义格式为“数据类型 变量名”;数据类型包括基本类型和用户自定义类型。C语言中的基本类型有int类型、char类型、float类型和double类型等。其中,int类型表示整型,char类型表示字符型,float类型和double类型表示浮点型。 运算符: C语言中的运算符包括算术运算符、关系运算符、逻辑运算符等。例如,“+”表示加法运算符,“>=”表示大于等于运算符,“&&”表示逻辑与运算符。 流程控制语句: C语言中的流程控制语句包括if语句、switch语句、while语句、do-while语句和for语句等。这些语句可以根据条件执行相应的语句块。 总之,本章节的快速入门C/C++,具有基本语法、变量、运算符和流程控制语句等基础知识。初者可以通过这些基础知识,轻松入门C/C++,为后续习打下基础。同时,要注意编写代码的规范和逻辑性,才能更好的理解和使用C/C++语言。 ### 回答3: C语言是一门广泛使用的编程语言,具有高效、灵活、稳定等特点,被广泛应用于嵌入式系统、操作系统、驱动程序、多媒体应用等领域。习C语言是程序员的必备技能之一。 第二章的快速入门C/C++教程,主要介绍了C/C++语言的基础知识,重点是程序的结构和输入输出。其中程序结构包括函数、语句、变量、表达式等,而输入输出则包括scanf、printf、getchar和putchar等函数。 # 程序结构 程序结构是指程序的基本构成单元,包括函数、语句、变量、表达式等。C语言中的程序结构主要包含以下几个方面。 ## 函数 C语言中,函数是程序的基本组成单元。一个C程序可以由一个或多个函数组成,每个函数可以完成一个任务。函数的格式如下: ```c 返回类型 函数名(参数1, 参数2, ...){ // 函数体 return 返回值; } ``` 其中,返回类型指函数执行后的返回值类型;函数名是由程序员定义的,用于调用函数时识别函数;参数列表是函数的输入参数,可以有多个参数,每个参数由类型和变量名组成;函数体是函数要执行的代码块;return语句可以返回函数的执行结果。 ## 语句 语句是完成特定功能的一组指令。C语言中的语句包括赋值语句、条件语句、循环语句等。C语言中通常使用花括号来表示语句块。例如,下面是一个if语句的例子。 ```c if(条件){ // if语句块 }else{ // else语句块 } ``` 如果条件为真,则执行if语句块中的代码;否则执行else语句块中的代码。 ## 变量 变量是用于存储数据的一种容器。在C语言中,一个变量包括变量名、类型和值。变量名由程序员定义,用于识别变量;类型指变量的数据类型,如整型、字符型、实型等;值是存储在变量中的数据。变量的定义格式如下。 ```c 数据类型 变量名 = 值; ``` 例如,下面是一个整型变量的定义。 ```c int num = 10; ``` ## 表达式 表达式是由变量、运算符和常量组成的一个具有返回值的语句。C语言中的运算符分为算术运算符、关系运算符、逻辑运算符等,例如加号、减号、乘号、除号等。下面是一个简单的表达式。 ```c a = 5 + 6 * 3 / 2 - 1; ``` 这个表达式将计算5加6乘3除以2减1的值,并将结果赋给a变量。 # 输入输出 输入输出是程序中非常重要的部分,可以让程序与用户进行交互。C语言中有多种输入输出函数,其中一些最常用的是scanf、printf、getchar和putchar函数。 ## scanf函数 scanf函数用于从标准输入读取格式化数据,并将读取的数据存储到变量中。它的格式如下。 ```c scanf("格式控制字符串", 变量列表); ``` 其中,格式控制字符串指示scanf函数需要读取的数据类型和格式,变量列表指向要读取的变量。下面是一个scanf函数的例子。 ```c int num; scanf("%d", &num); ``` 这个代码段将从标准输入读取一个整数,并将其存储到num变量中。 ## printf函数 printf函数用于将格式化数据输出到标准输出。它的格式如下。 ```c printf("格式控制字符串", 参数列表); ``` 其中,格式控制字符串指示printf函数需要输出的数据类型和格式,参数列表包含要输出的变量和常量。下面是一个printf函数的例子。 ```c int num = 5; printf("num的值是%d\n", num); ``` 这个代码段将输出“num的值是5”。 ## getchar和putchar函数 getchar函数用于从标准输入读取一个字符,putchar函数用于将一个字符输出到标准输出。它们的用法非常简单,例如下面的代码将读取一个字符并将其转换成大写字母后输出。 ```c char c = getchar(); putchar(toupper(c)); ``` 以上就是第二章中的快速入门C/C++教程的主要内容,包括程序结构和输入输出方面的基础知识。熟练掌握这些内容,对于习C语言来说是非常重要的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值