通过递归解决多重循环问题
- 格式:pdf
- 大小:126.64 KB
- 文档页数:3
多重子集的概念多重子集是集合中的元素的组合,其中一个元素可以出现多次,也可以不出现。
换言之,多重子集是原集合中的一个或多个元素的选择组合。
以下是对多重子集的详细解释:1. 多重子集的定义:多重子集是指从一个集合中选择出来的组合,其中一个元素可以出现多次,也可以不出现。
例如,给定集合{1, 2, 3},它的多重子集可以有{1, 1, 2},{1, 2, 2, 2}等。
2. 多重子集的性质:(1) 多重子集可以为空集。
例如,给定集合{1, 2, 3},它的多重子集中可以包含空集{}。
(2) 多重子集的大小可以小于等于原集合的大小。
例如,给定集合{1, 2, 3},它的多重子集可以是{}、{1}、{1, 2}、{1, 1, 3}等。
(3) 多重子集中的元素顺序不重要。
例如,{1, 2, 3}和{2, 1, 3}表示相同的多重子集。
(4) 给定集合的所有子集都是它的多重子集。
例如,给定集合{1, 2, 3},它的子集有{1}、{2}、{3}、{1, 2}、{2, 3}等,这些都是它的多重子集。
3. 多重子集的生成方法:(1) 二进制法:对于一个n个元素的集合,可以用一个长度为n的二进制数表示多重子集。
二进制数的第i位为1表示选择集合中的第i个元素,为0则表示不选择。
例如,对于集合{1, 2, 3},二进制数"101"可以表示多重子集{1, 3}。
(2) 递归法:可以通过递归的方式生成多重子集。
对于一个n个元素的集合,它的多重子集可以通过以下递归步骤生成:从左到右依次考虑每个元素,对于每个元素,可以选择它出现0次、1次、2次......n次,然后分别对剩下的元素继续递归。
通过递归的方式,可以生成所有的多重子集。
(3) 迭代法:可以使用迭代的方式生成多重子集。
对于一个n个元素的集合,可以使用循环遍历所有的可能情况,判断每个元素是否选择。
例如,对于集合{1, 2, 3},可以用三个嵌套的循环遍历所有的情况,并根据每个元素的选择情况生成多重子集。
背包问题全类型背包问题给定⼀组物品,每种物品都有⾃⼰的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最⾼。
背包问题⼤体都可以⽤上述⽅式进⾏描述,但在具体的问题上有了不同的限制条件,于是便有了各种类型的背包问题。
背包问题可基本分为0-1背包问题、部分背包问题、多重背包问题、完全背包问题四⼤类。
接下从四种问题的解决的核⼼算法可以把部分背包问题单独化为⼀类,其核⼼算法为贪⼼。
其余的三种背包问题都可以⽤动态规划解决。
造成部分背包问题与其他的背包问题最⼤不同的原因是其限定条件的不同,部分1. 部分背包问题限定条件:每件物品可以只选取⼀部分完整问题描述:有 n 件物品,第i件物品重 w[i],价值为 v[i],且每件物品可以进⾏分割,分割后的价值按取⾛重量占该物品总重量的⽐值计算。
在不超过最⼤承载量 C 的范围内,问最⼤可以取⾛的价值为多少?( 其中 i ∈ {1,2,3,···,n} )算法:贪⼼分析:根据本题的特殊性,我们可以任意地对某⼀部品进⾏分割,所以我们优先选择性价⽐⾼的物品,即单位重量下物品的价值。
解题代码//C++#include<cstdio>#include<algorithm>#include<iostream>using namespace std;struct bag { int w,v; //w表⽰重量 v表⽰价值 double p; //⽤来储存v/w 性价⽐}a[10005];bool cmp(bag x,bag y) { return x.p > y.p; //性价⽐⾼的物品排在前⾯}int main() {剩余 } } printf('%.2f\n', ans); //输出答案 return 0;}注意计算时注意数据类型在计算“性价⽐”的时候要注意,在C/C++等⼀部分语⾔中存在以下机制 int/int = int ,这样是⽆法计算出⼩数的,需要将其中任意⼀项浮点化即可。
多重网格算法综述邹静文 102071406摘要 本文总结了多重网格算法的基础理论,剖析了多重网格方法的一种并行模式以及总结了已取得的成果和待扩充的领域。
对多重网格方法的基本思想有一个较详细的概述,比较分析了单一网格和多重网格的计算结果,并对多重网格的并行模式进行了探索和分析。
关键词 多重网格算法,套迭代,粗网格校正,并行模式,交错多重网格,区域分解一、引言多重网格法(Multiple Grid Method),简称M —G 方法是近年来求解偏微分方程边值问题的快速方法之一,本文参考前人的文献资料,并结合所学知识,总结多重网格法的基础理论,包括多重网格的应用原则、具体实现步骤以及计算结果的分析和比较。
其计算结果表明:多重网格方法具有收敛速度快的优点,当多重网格方法所用层数越多,收效速度就越快;而且撞制粗、细网格层之间自适应转换的撞制参数在选取上有很大的灵活性;可以看出随着剖分的加密,单一网格方法达到收敛所需的迭代次数显著增加,而多重网格方法所需迭代次数基本上不随网格的疏密和层数而变化,这表明多重网格方法具有与网格参数无关的收敛性。
二、多重网格方法的基础理论多重网格方法的最初被提出是由于在网格方程迭代求解时,误差的各个Fourier 分量的衰减程度不同。
认识到高频振荡误差是局部行为,来源于附近几个网格点之间的相互藕合,与边界或距离较远的网格点信息无关;而低频光滑误差是全局行为,主要来源于边界信息。
传统的点或块松弛都是局部性较强的方法,因此它们能迅速抹平局部性的高频振荡误差,但对全局性的低频光滑误差却衰减缓慢。
实际上,经过初始几次迭代后,误差将呈现光滑性。
所以,习惯上称能迅速抹平高频振荡误差,使误差趋于光滑的松驰方法为有效光滑方法,并用松驰因子来刻画它们的光滑效应。
2.1多重网格方法思想的引入考虑在简单区域Ω上泊松方程的第一类边值问题(狄立克雷边值问题):(,)(,),(,)(,)0,(,)u x y f x y x y u x y x y -∆=∈Ω⎧⎨=∈∂Ω⎩这里Ω是一个单位正方形,∂Ω是这个正方形的边界如下图所示:在以步长为h 的网格上hΩ离散后,得到一个线性系统h h h L u f =,其中h L 是一个稀疏矩阵。
【算法】常见算法分类和思想我们在实际应⽤中,对⼀个问题会有不同的解题思路,⽐如我们在读书时候,往往对⼀道数学题⽬会有多种解题⽅法,可能有些⽅法⽐较简单,有些⽅法⽐较复杂,步骤较多。
所以找到⼀个合适的⽅法可以更快更好的去解决问题。
在程序应⽤中,我们也会有不同的算法去解决问题。
算法分类分为:1.基础算法:包括字符串,数组,正则表达式,排序,递归等。
2.数据结构:堆,栈,队列,链表,矩阵,⼆叉树等。
3.⾼级算法:贪⼼算法,动态规划等。
根据问题的不同,⼀般可以有以下算法思想去解决问题: 递推算法: 递推法,就是从已知的结果和条件出发,利⽤特定关系分解中间步骤得出推论,逐步推导⽽得到结果。
递推算法分为顺推和逆推两种。
递推与递归的⽐较 相对于递归算法,递推算法免除了数据进出栈的过程,也就是说不需要函数不断的向边界值靠拢,⽽直接从边界出发,直到求出函数值。
分治算法: 分治,顾名思义,分⽽治之,分治算法是⼀种化繁为简的算法思想,往往应⽤于计算步骤⽐较复杂的问题,通过将问题简化⽽逐步得到结果。
常⽤场景就是求出最轻、最重问题(在⼀堆形状相同的物品中找出最重或最轻的那⼀个,⼆分查找,快速排序和归并排序,分治算法也是许多⾼效算法的基础,⽐如快速傅⽴叶变换算法和 Karatsuba 乘法算法。
概率算法: 概率算法是在程序执⾏过程中利⽤概率统计的思路随机地选择下⼀个计算步骤,在很多情况下,算法在执⾏过程中⾯临选择时,随机性选择⽐最优选择省时,因此概率算法可以在很⼤程度上降低算法的复杂度。
概率算法⼤致分类如下: 1.贝叶斯分类算法。
2.蒙特卡罗(Monte Carlo)算法。
3.拉斯维加斯(Las Vegas)算法。
4.舍伍德(Sherwood)算法。
5.随机数算法。
6.近似算法。
7.机器学习算法中的的⼀些概率⽅法。
递归算法: 递归算法是指⼀种通过重复将问题分解为同类的⼦问题⽽解决问题的⽅法。
具体来说就是就是⼀个函数或者类⽅法直接或间接调⽤⾃⾝的⼀种⽅法。
fird函数fird函数是一个在计算机编程中非常有用的函数。
它是一个递归函数,能够从一个整数列表中找到第一个重复的元素并返回。
在理解fird函数之前,让我们先来了解一下递归函数的概念。
递归函数是指一个函数可以调用自身来解决更小的子问题。
在编写递归函数时,我们需要定义一个递归基(base case),它是递归函数停止递归的条件,以避免无限递归。
编写fird函数的关键是如何在整数列表中找到第一个重复的元素。
可以通过两种方法来实现。
方法一是使用两个嵌套的循环。
外层循环遍历整个列表,内层循环从外层循环的当前元素开始遍历列表的其余部分。
在内层循环中,我们可以使用一个条件语句来检查是否存在两个相同的元素。
如果找到了重复的元素,我们就可以返回该元素并结束函数。
方法二是使用一个哈希表(hash table)来存储已经遍历过的元素。
我们可以遍历整个列表,并将每个元素添加到哈希表中。
在添加之前,我们可以使用一个条件语句来检查该元素是否已经存在于哈希表中。
如果存在,说明我们找到了重复的元素,就可以返回该元素并结束函数。
无论使用哪种方法,fird函数的时间复杂度都是O(n^2),其中n是列表的长度。
这是因为方法一的内层循环需要遍历列表的其余部分,时间复杂度是O(n),而方法二需要将每个元素添加到哈希表中,时间复杂度是O(n)。
当列表很大时,fird函数的性能可能不够理想。
为了提高性能,我们可以使用一种更高效的数据结构来存储已经遍历过的元素,例如哈希集合(hash set)。
使用哈希集合可以将元素的查找时间从O(n)降低为O(1),从而将fird函数的时间复杂度降低到O(n)。
除了时间复杂度,我们还需要考虑空间复杂度。
方法一不需要额外的存储空间,所以它的空间复杂度是O(1)。
而方法二需要使用一个哈希表来存储已经遍历过的元素,所以它的空间复杂度是O(n)。
总结来说,fird函数是一个递归函数,能够从一个整数列表中找到第一个重复的元素并返回。
第5章循环结构(一)本章学习的目的和要求(二)本章学习的重点(三)复习题1.1单选题1.以下说法正确的是( )。
A.不能使用do-while语句构成的循环B.do-while语句构成的循环必须用break语句才能退出C.do-while语句构成的循环,当while语句中的表达式值为假时结束循环D.do-while语句构成的循环,当while语句中的表达式值为真时结束循环C语言支持的循环语句有:()A for循环B while循环C do while循环D以上都是1.2多选题1.3判断题1.continue语句用于循环语句内部中。
当遇到continue语句之后,循环体中continue语句后面的语句将被跳过,计算机将接着开始执行下一次循环。
()2.for(表达式1;表达式2;表达式3){},其中表达式1只执行一次。
3.若int i=0,k=8;while(i=8) i=k--;则while循环体的执行次数为0.4.多重循环是指循环语句的循环体中,又嵌套了另一个或多个循环语句,多个内层循环可以相互交叉嵌套。
5.在复合语句中定义的变量可在该复合语句所在的函数的其它地方使用。
6.在函数体内定义的变量称全局变量,可以被程序中的所有函数引用。
7.continue语句用在循环体中,可使整个循环不结束。
8.continue语句可以用于switch结构中。
9.break语句只能用于循环语句中。
10.do......while循环语句至少要执行一次循环体。
11.语句while(!E);中的条件!E等价于E==0。
12.语句for(;;){循环体}和while(1){循环体}是等价的。
13.在C语言中,for语句既可以用于计数类型循环又可以用于条件类型循环。
14.在while循环中允许使用嵌套循环,但只能是嵌套while循环。
15.在实际编程中,do-while循环完全可以用for循环替换。
16.continue语句只能用于三个循环语句中。
迭代幂次函数一、简介迭代幂次函数是一种基于递归的数学函数,其核心思想是将一个复杂的问题分解成多个简单的子问题,并通过递归调用来解决这些子问题。
在计算机科学中,迭代幂次函数常用于算法设计和数据分析等领域,具有广泛的应用价值。
二、定义迭代幂次函数可以表示为:f(x) = x^a,其中a为正整数。
该函数接受一个实数x作为输入,并返回x的a次方。
在计算过程中,该函数通过不断递归调用自身来实现幂运算。
三、递归实现以下是一个基于递归实现的迭代幂次函数:```pythondef power(x, a):if a == 0:return 1elif a % 2 == 0:return power(x*x, a/2)else:return x * power(x*x, (a-1)/2)```该函数接受两个参数:x和a。
如果a等于0,则返回1;否则,如果a为偶数,则将x平方并将a除以2,继续递归调用power();如果a 为奇数,则先将x平方并将(a-1)除以2,然后再乘以x并继续递归调用power()。
这样不断递归调用,直到a等于0时返回1,完成幂运算。
四、迭代实现以下是一个基于迭代实现的迭代幂次函数:```pythondef power(x, a):result = 1while a > 0:if a % 2 == 1:result *= xx *= xa //= 2return result```该函数通过一个while循环来实现幂运算。
首先将result初始化为1,然后不断循环直到a等于0。
在每次循环中,如果a为奇数,则将result乘以x;无论a是否为奇数,都将x平方并将a除以2。
这样不断迭代计算,直到a等于0时返回result,完成幂运算。
五、性能比较基于递归的实现方法通常比基于迭代的实现方法更简洁易懂,并且具有更好的可读性和可维护性。
但是,在某些情况下,递归实现可能会导致栈溢出或者效率低下的问题。
递归是一种强大的编程技术,它允许函数在其定义中调用自身。
然而,递归并不是解决所有问题的最佳方法。
有时,使用迭代(即循环)或其他算法可能会更有效,更简洁,甚至更快。
下面是一些可以替代递归的算法和方法。
1. 迭代
迭代是递归的一种常见替代方法。
在许多情况下,递归函数可以通过使用循环(如for 循环或while循环)来重写。
迭代通常比递归更容易理解和调试,并且对于某些问题,迭代可能比递归更有效。
2. 动态规划
动态规划是一种用于解决递归问题的强大技术。
它通过将问题的解决方案存储在一个表(或其他数据结构)中,避免了递归中的重复计算。
这种方法通常比递归更快,因为它避免了不必要的重复计算。
3. 尾递归优化
尾递归是一种特殊的递归形式,其中递归调用是函数体中的最后一个操作。
一些编程语言(如Haskell)对尾递归进行了优化,使其具有与迭代相同的效率。
然而,并非所有编程语言都支持这种优化,因此尾递归可能并不总是最佳选择。
4. 栈模拟
对于某些递归问题,可以通过使用栈来模拟递归调用栈。
这种方法允许我们以迭代的方式模拟递归过程,从而避免了递归的深度限制。
5. 非递归数据结构
某些数据结构(如栈、队列、树等)可以以非递归方式实现。
使用这些数据结构可以避免需要递归的算法。
总的来说,选择递归还是其他算法取决于具体的问题和上下文。
在某些情况下,递归可能是最简洁和最直接的方法。
然而,在其他情况下,使用迭代、动态规划或其他技术可能会更有效、更简洁或更快。
因此,了解多种解决问题的方法是非常重要的。
递推法和递归法的区别递推法和递归法是程序设计中常用的两种方法,它们都可以用来解决类似于数据处理、计算等问题。
虽然两种方法都可以实现同样的功能,但是它们的实现方式和运行机制却存在很大的不同。
本文将详细探讨递推法和递归法的区别。
一、概念解释递推法(Recursion)是指利用已知条件和递推关系式依次推导出未知结果的过程。
递推法可以理解为“顺着问题的发展过程,从已知的问题处理到未知的结果”。
它可以用于简化问题,使问题的计算过程不用涉及很多变量。
而递归法(Iteration)是指一个函数在定义中调用自己的过程。
递归函数会将问题拆分为一个个子问题,并且通过不断调用自身的方式来解决这些子问题。
递归法可以用于处理数据结构、树形结构等具有递归特性的问题。
二、实现方式递推法通常通过循环来实现,它可以用循环变量来记录已知条件和当前状态。
在每次循环中,根据递推关系式计算出下一次循环的结果。
因此,递推法的运行机制主要是循环和计算,递推法的实现方式更为直接和简单。
递归法则主要是通过函数的调用来实现。
递归函数会将问题拆分成一个个子问题,并通过调用自身的方式来解决这些子问题。
当问题被拆分至最小单元时,函数会返回结果,然后将所有的子问题的结果组合成一个完整的结果。
因此,递归法的实现基于函数的调用和返回,它更加灵活和方便。
三、运行机制递推法的运行机制主要是循环和计算,它可以通过循环变量来记录已知条件和当前状态,然后根据递推关系式计算出未知结果。
因此,递推法的效率通常比递归法更高。
而递归法则主要是基于函数的调用和返回来运行的。
递归函数会将问题拆分成一个个子问题,并通过调用自身的方式来解决这些子问题。
当问题被拆分至最小单元时,函数会返回结果,然后将所有的子问题的结果组合成一个完整的结果。
由于递归法需要使用函数的调用和返回,因此它的效率较低,而且递归深度过深容易导致栈溢出。
四、应用场景递推法适合于序列、条件递推等问题,因为在这些问题中,我们可以通过已知条件、递推关系式和循环变量来计算出未知结果。
递归求阶乘的时间复杂度递归求阶乘是一种常见的数学运算方法,可以用来计算一个非负整数的阶乘。
在计算机科学中,递归是一种解决问题的算法思想,它通过将问题分解为相同类型的更小的子问题来解决。
阶乘是一个典型的递归问题,可以使用递归算法来求解。
在开始讨论递归求阶乘的时间复杂度前,先来了解一下什么是时间复杂度。
时间复杂度是一种用来度量算法运行时间性能的方法。
它表示算法的运行时间与输入规模之间的关系。
通常用大O符号来表示时间复杂度。
在计算机科学中,时间复杂度分为几种常见的复杂度级别,如O(1)、O(log n)、O(n)、O(n log n)和O(n^2)等。
递归求阶乘的算法可以通过以下方式实现:```pythondef factorial(n):if n == 0:return 1else:return n * factorial(n-1)```在这段代码中,我们定义了一个递归函数factorial,它接受一个非负整数n作为参数,并返回n的阶乘。
函数的基本情况是当n为0时,返回1;否则,递归调用函数自身,并将n乘以factorial(n-1)的结果返回。
现在,我们来分析一下递归求阶乘的时间复杂度。
在每一次递归调用中,函数都会将问题规模减小1,并再次调用自身。
因此,递归调用的次数取决于输入的规模n。
具体地说,当输入的n为正整数时,递归调用的次数为n-1次。
这是因为在每一次递归调用中,函数都会将n减去1,并再次调用自身,直到n为0才停止递归。
综上所述,递归求阶乘的时间复杂度可以表示为O(n-1),即O(n)。
这意味着,递归求阶乘的时间复杂度与输入规模n成正比。
随着n的增大,递归调用的次数也会相应增加,导致算法的运行时间增加。
需要注意的是,在实际应用中,递归求阶乘的算法可能遇到递归深度限制的问题。
当递归深度超过系统或编程语言设定的最大限制时,程序将抛出递归堆栈溢出的异常。
为了避免递归深度限制的问题,我们可以使用循环来实现求阶乘的算法。
2016年11月
第35卷第11期
洛阳师范学院学报
Journ ̄of Luoyang Norm ̄Unive ̄ity
NOV.,2016
Vo1.35 No.11
通过递归解决多重循环问题
刘华煜
(洛阳师范学院数学科学学院,河南洛阳471934)
摘要:在计算机编程中,多重循环不仅繁琐而且易出错,用递归模拟多重循环则会避免这些问题,本文对此
做了研究.
关键词:多重循环;递归;钩子函数
中图分类号:TP311 文献标识码:A 文章编号:1009—4970(2016)ll一0014—03
1穷举法与多重循环
穷举法也称为枚举法.穷举法是编程中常用的
方法,穷举法的基本思想是根据题目的部分条件确
定答案的大致范围,并在此范围内对所有可能的情 况逐一验证,直到全部情况验证完毕.若某个情况 验证符合题目的全部条件,则为本问题的一个解; 若全部情况验证后都不符合题目的全部条件,则本 题无解. 穷举法中经常会用到多重循环,如: (1)求所有的水仙花数(水仙花数是指一个三 位数,其各位数字立方和等于该数本身). 其程序是一个三重循环: for(i=1;i<=9;i++)//百位数 for(j=0;j<:9;j++)//十位数 for(k=0;k<=9;k++)//个位数 (2)求所有这样的四位数:此数用abed来表 示,abed=(ab) +(ed)2. 其程序是一个四重循环: for(i=1;i<=9;i++) //千位数 f0r(j=0;j<=9;j++)//百位数 for(k=0;k<=9;k++)//十位数 for(ITI:0;rn<=9;m++) //个位数 穷举过程中经常会碰到很多独立的条件:条件 1有m中可能,条件2有n中可能,条件3有P种 可能……,有多少个条件,就有几重循环.无论是 写这样的程序还是读这样的程序都会很累,还容易 隐藏各种错误. 2 递归 程序调用自身的编程技巧称为递归.递归做为
一
种算法在程序设计语言中被广泛应用.一个过程
或函数在其定义或说明中有直接或间接调用自身的
一
种方法,它通常把一个大型复杂的问题层层转化
为一个与原问题相似的规模较小的问题来求解,递
归策略只需少量的程序就可描述出解题过程所需要
的多次重复计算,大大地减少了程序的代码量.递
归的能力在于用有限的语句来定义对象的无限集
合.一般来说,递归需要有边界条件、递归前进段
和递归返回段.当边界条件不满足时,递归前进;
当边界条件满足时,递归返回.
3用递归来解决多重循环
以下为叙述方便,把最外层循环称为第1层循
环,次外层循环称为第2层循环,…….
对第1层循环而言,循环体是第2一n层循环,
即第1层循环的循环体也是一个多重循环,只不过
是层数少了1,同样,对第2层循环而言,循环体是
第3一n层循环,即第2层循环的循环体也是一个
多重循环,层数再少1,……,以此类推.
多重循环的每一层循环的循环体都是一个层数
少1的多重循环,符合递归“把一个大型复杂的问
题层层转化为一个与原问题相似的规模较小的问
题”的特点.
收稿日期:2015—12—06
作者简介:刘华煜(1976一),男,黑龙江大庆人,硕士,讲师.研究方向:计算机应用
・
l4・
洛阳师范学院学报2016年第11期
所以可以用递归来实现多重循环.’ l
4代码
4.1简单的四重循环
下面的代码实现的是每一重循环都是从0到2
的四重循环:
int i[4];
void loop(int n){
int m=n一1,j;
if(n==0){for(J=3;j>=0;j一一)
pfintf(”%d”,i[j]);pfinff(””);return;}
for(i[m]=0;i[m]<=2;i[m]++)
loop(n一1);
}
int main(void){loop(4);}
程序的输出是:
0000 0001 0002 0010 001 1 0012 0020 0021 0022
O100 0l01…2222
每一组四位数的含义:
以0121为例,0是第四层循环变量此时的值,
1是第三层循环变量此时的值,2是第二层循环变
量此时的值,1是第一层循环变量此时的值.
代码中的i[4]存储的是每层循环变量此时的
值.
1oop循环中的if(n:=0)后的代码是最内层循
环的循环体.
for(i[m]=0;i[m]<=2;i[m]++)loop(n一1);
对每次本层循环都递归调用一下loop函数,以
执行下一层循环.
4.2不同循环次数
每层循环的循环次数经常是各不相同的.为了
处理这个问题,需要一个新的数组:
int maxi[4]={2,3,4,3};
其中2代表第四层循环从0到2,3代表第三层循
环从0到3,4代表第二层循环从0到4,3代表第
一
层循环从0到3.
for(i[m]=0;i[m]<=2;i[m]++)loop(n一1);
也需要修改成:
for(i[m]=0;i[m]<=maxi[m];i[m]++) loop(n一1); 4.3初值不为0 循环变量的初值经常不是0,并且每层循环的 初值也不一定相同.解决这个问题的方法是再设一 个数组mini,表达每层循环的初值,并将 for(i[m]:0;i[m]<=maxi[In];i[m]++) 修改成 for(i[m]=mini[m];i[m]<=maxi[m]; i[m]++) 4.4钩子函数 如果把最内层的循环体作为钩子函数提取出 来,loop函数就可以作为一个通用函数存在了.其 代码如下: int i[4]; int m ̄i[4]={2,3,4,3}; int mini[4]={0,0,0,1}; void loop(int n,void( hook)(void data), void’lc h0okdata){ int m:n一1: if(n==0){hook(hookdata);return;} for(i[m]=mini[m 3;i Em]<=maxi[m]; i[in]++) loop(n一1,hook,hookdata); } void P(void data){ int j; for(j=3;j>=0;j一一)pfintf(”%d”,i[j]); pfinff(””); retum; } int main(void){loop(4,P,NULL);} 其中P是钩子函数,代表最内层循环的循环体. 5 用递归解决abcd=(ab) +(cd) 问题 其代码如下: int i[4],maxi[4]={9,9,9,9}, mini[4]={0,0,0,1}; void loop(int n,void(:lc hook)(void data), void{hookdata){略} void p(void data){ int al:(i[0]+i[1] 10) (i[0]+i[1]¥ 10)+(i[2]+i[3] 10) (i[2]+i[3] 10);
int a2=i[3]¥1000+i[2]:}=100+i[1]¥10
+i[0];
if(al==a2)pfintf(”%d%d%d%d”,i[3],
i[2],i[1],i[0]);
.
15・
洛阳师范学院学报2016年第11期
return;
}
int main(void){loop(4,P,NULL);}
结果是:1233 8833
6 结论
用递归来解决多重循环问题,避免了其烦琐和
易出错的缺点.
参考文献
[1]Ivor Horton.C语言入门经典[M].北京:清华大学出版
社,2013.10.
[2]Robe ̄Sedgewick.算法分析导论[M].北京:机械工业
出版社,2006.4.
[3]Kyle Loudon.算法精解:c语言描述[M].北京:机械工
业出版社,2012.9.
[责任编辑胡廷锋]
Solving Multiple Loop Problems by Recursion
LIU Hua—yu
(College of Mathematics and Science,Luoyang Normal University,Luoyang 471934,China)
Abstract:Multiple loop are not only tedious but also prone to error,using recursion to simulate multiple loop
can avoid these problems.
Key words:multiple loop;recursion;hook function
・
l6・