初阶C-1107

这次的初阶都是跟C语言中的递归有关的。可以说递归是一个不好理解的,比较抽象的东西。

递归(Recursion),指在函数的定义中使用函数自身的方法,即程序的自身调用。

递归就是方法里调用自身。

但是递归的缺陷也是非常大的。在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等,所以一般不提倡用递归算法设计程序。

1.递归和非递归分别实现求第n个斐波那契数。

//利用了递归
int Fibonacci(int n){
	if (n == 1 || n == 2){
		return 1;
	}
	return Fibonacci(n - 1) + Fibonacci(n - 2);
}
//不使用递归
void Fib(int n){
	int j = 1, k = 1, sum = 0;
	if (n == 1 || n == 2){
		return 1;
	}
	if (n % 2 == 0){
		for (int i = 1; i < n / 2; i++){
			j += k;
			k += j;
		}
		printf("%d", k);
	}
	else if(n % 2 == 1){
		for (int i = 1; i <= n / 2; i++){
			j += k;
			k += j;
		}
		printf("%d", j);
	}
}

2.编写一个函数实现n^k,使用递归实现.

//n^k  如果调用递归,我们先拆分这个算式
//			n^k=1,k=0;n^k=n*n^(k-1),k>0
double index(double n,double k){
	if (k == 0){
		return 1;
	}
	return n*index(n, k - 1);
}

3.写一个递归函数DigitSum(n),输入一个非负整数,返回组成它的数字之和,例如,调用DigitSum(1729),则应该返回1+7+2+9,它的和是19.

int DigitSum(int n){
	int m = 0;
	int sum = 0;
	if (n != 0){
		m = n % 10;
		n = n / 10;
		sum = m + DigitSum(n);
	}
	return sum;
}

4.递归和非递归分别实现strlen.

int Strlen(const char*str){
	if ('\0' == *str){
		return 0;
	}
	return 1+Strlen(str + 1);//这里的+1可以理解成每次进行拆分去算
    					   //比如“abcd” 先为“a”+“bcd”,第二次在为“b”+“cd”,以此类推
}

int Strlen2(char str[]){
	int size = 0;
	while (str[size] != '\0'){
		size++;
	}
	return size;
}

5.递归和非递归分别实现求n的阶乘 .

void Fac(int n){
	int j = 1;
	if (n == 1){
		return 1;
	}
	for (int i = 1; i <= n; i++){
		j *= i;
	}
	printf("%d", j);
}

int Fac1(int a){
	if (a == 1){
		return 1;
	}
	return a*Fac1(a-1);
}

6.递归方式实现打印一个整数的每一位.

int PrintfNum(int n){
	if (n > 9){
		printf("%d",PrintfNum(n / 10);
	}
	printf("%d", n % 10);
    
    //逆序实现,非递归
	//while (n){
	//	m = n % 10;
	//	n = n / 10;
	//	printf("%d", m);
	//}
	
}

本次就结束了,还有一个利用递归进行逆序的题,我觉得这道题很不好理解。我将专门写一篇关于这道题目的文章。

递归的思想是很重要的。我们可以想象成电影《盗梦空间》,一层接着一层的梦境,就好比我们的递归不断的往下进行,只有上一层完成后,才可到下一层。多加练习,多思考,一定会掌握的。

### 光流法C++源代码解析与应用 #### 光流法原理 光流法是一种在计算机视觉领域中用于追踪视频序列中运动物体的方法。它基于亮度不变性假设,即场景中的点在时间上保持相同的灰度值,从而通过分析连续帧之间的像素变化来估计运动方向和速度。在数学上,光流场可以表示为像素位置和时间的一阶导数,即Ex、Ey(空间梯度)和Et(时间梯度),它们共同构成光流方程的基础。 #### C++实现细节 在给定的C++源代码片段中,`calculate`函数负责计算光流场。该函数接收一个图像缓冲区`buf`作为输入,并初始化了几个关键变量:`Ex`、`Ey`和`Et`分别代表沿x轴、y轴和时间轴的像素强度变化;`gray1`和`gray2`用于存储当前帧和前一帧的平均灰度值;`u`则表示计算出的光流矢量大小。 #### 图像处理流程 1. **初始化和预处理**:`memset`函数被用来清零`opticalflow`数组,它将保存计算出的光流数据。同时,`output`数组被填充为白色,这通常用于可视化结果。 2. **灰度计算**:对每一像素点进行处理,计算其灰度值。这里采用的是RGB通道平均值的计算方法,将每个像素的R、G、B值相加后除以3,得到一个近似灰度值。此步骤确保了计算过程的鲁棒性和效率。 3. **光流向量计算**:通过比较当前帧和前一帧的灰度值,计算出每个像素点的Ex、Ey和Et值。这里值得注意的是,光流向量的大小`u`是通过`Et`除以`sqrt(Ex^2 + Ey^2)`得到的,再乘以10进行量化处理,以减少计算复杂度。 4. **结果存储与阈值处理**:计算出的光流值被存储在`opticalflow`数组中。如果`u`的绝对值超过10,则认为该点存在显著运动,因此在`output`数组中将对应位置标记为黑色,形成运动区域的可视化效果。 5. **状态更新**:通过`memcpy`函数将当前帧复制到`prevframe`中,为下一次迭代做准备。 #### 扩展应用:Lukas-Kanade算法 除了上述基础的光流计算外,代码还提到了Lukas-Kanade算法的应用。这是一种更高级的光流计算方法,能够提供更精确的运动估计。在`ImgOpticalFlow`函数中,通过调用`cvCalcOpticalFlowLK`函数实现了这一算法,该函数接受前一帧和当前帧的灰度图,以及窗口大小等参数,返回像素级别的光流场信息。 在实际应用中,光流法常用于目标跟踪、运动检测、视频压缩等领域。通过深入理解和优化光流算法,可以进一步提升视频分析的准确性和实时性能。 光流法及其C++实现是计算机视觉领域的一个重要组成部分,通过对连续帧间像素变化的精细分析,能够有效捕捉和理解动态场景中的运动信息
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值