数据结构与算法之迭代算法

数据结构与算法之迭代算法

迭代算法的基本概念

定义:

迭代法(Iteration)也称为“碾转法”,是一种不断用变量的旧值递推出新值的解决问题的一种方法。迭代算法一般用于数值计算。迭代法应该是早已熟悉的算法策略。

设计要点

利用迭代算法策略求解问题,设计工作主要3步:
1)确定迭代模型
根据问题的描述,分析得出前一个(或几个)值与其下一个值的迭代关系数学模型。当然这样的迭代关系,最终会迭代出解的目标。
2)建立迭代关系
递推数学模型一般是带下标的字母,算法设计中要将其转化为“循环不变式”----迭代关系式,迭代关系式就是一个直接或间接地不断由旧值推出新值的表达式,存储新值的变量称为迭代变量。
迭代关系式的建立是迭代算法设计的主要工作。
3)对迭代过程进行控制
确定在什么时候结束迭代过程,是设计迭代算法时必须考虑的问题。
迭代过程的控制通常可分为两种情况:一种是一致或可以计算处理所迭代次数,这时可以构建一个固定次数的循环来实现对迭代过程的控制。另一种是所须的迭代次数无法确定,需要分析出迭代构成的结束条件,甚至于要考虑有肯得不到目标解(迭代不收敛)的情况,避免出现迭代过程死循环。

实例

计算

题目:
求1+11+111+1111+…+11….11(n个1)的和除以7的余数是多少?
分析:
最后的余数可以看成是每个加数与7的余数之和再除以7的余数。
11…11(n个1)的余数等于(11…10)除以7的余数加1。
用变量s累加记录各个式子余数的和。
用变量k,记录当次循环除以7的余数,也是下次循环的基础。
代码:

#include <cstdio.h>
using namespace std;
int main(){
 int s=0,k=0,n;
 scanf(%d”,&n);
 for(int i=1;i<=n;i++)
 {
   k=k*10+1;
   k=k%7;
   s=s+k;
 }
 printf(“所得余数为%d\n”,s%7);
 return 0}

求方程

题目:
用二分法求解一元非线性方程f(x)=x3+2x2-8=0在【0,2】的近似根r,精确到0.0001 。
分析:
可以用数学方法证明在0到2之间是单调递增的。又x=0时,f(x)=-8;x=2时,f(x)=4,因此曲线f(x)在【0,2】间必与x轴有交点,则交点即是该问题的解。该问题的解可能是个无理数,无法通过计算机得到精确的解,我们只可能得到近似解,根据题意精确到0.0001,即是利用迭代法求得某个x0,使得|f(x0)|<0.0001,我们可认为x0就是该问题的解。
迭代思路:
用x1和x2取区域【0,2】两个端点,计算其中间点x=(x1+x2)/2的值,计算f(x)=xxx+2xx-8的值。
若f(x)=0,则x是我们的解。
若f(x)>0,表明问题的解在【x1,x】之间,应用迭代思想,让x2=x,构成新的x1和x2区间,执行1)的操作,直到abs(f)>=0.0001时结束。
若f(x)<0,表明问题的解在【x,x2】之间,应用迭代思想,让x1=x,构成新的x1和x2区间,执行1)的操作,直到abs(f)>=0.0001时结束。
代码:

#include <cstdio.h>
#include <math.h>
using namespace std;
int main()
{ 
  double x,x1=0,x2=2, f;
   do{
 x=(x1+x2)/2;
 f=x*x*x+2*x*x-8;
 if(f==0)	
	    	break;
	 if(f>0.0)	 
    x2=x;
 else
     x1=x;
	}while( abs(f)>=0.0001);
   printf(%f  \n”,x); 
   return 0;
}

比例简化

问题:
在社交媒体上,经常会看到针对某一个观点同意与否的民意调查以及结果。例如,对某 一观点表示支持的有 1498 人,反对的有 902 人,那么赞同与反对的比例可以简单的记为 1498:902。
不过,如果把调查结果就以这种方式呈现出来,大多数人肯定不会满意。因为这个比例 的数值太大,难以一眼看出它们的关系。对于上面这个例子,如果把比例记为 5:3,虽然与 真实结果有一定的误差,但依然能够较为准确地反映调查结果,同时也显得比较直观。
现给出支持人数 A,反对人数 B,以及一个上限 L,请你将 A 比 B 化简为 A’比 B’,要 求在 A’和 B’均不大于 L 且 A’和 B’互质(两个整数的最大公约数是 1)的前 下,A’/B’ ≥ A/B 且 A’/B’ - A/B 的值尽可能小。
【输入】
输入文件名为 ratio.in。

输入共一行,包含三个整数 A,B,L,每两个整数之间用一个空格隔开,分别表示支持 人数、反对人数以及上限。
【输出】
输出文件名为 ratio.out。

输出共一行,包含两个整数 A’,B’,中间用一个空格隔开,表示化简后的比例。
【输入输出样例】
ratio.in ratio.out
1498 902 10 53
分析:
对于 100%的数据,1 ≤ A ≤ 1,000,000,1 ≤ B ≤ 1,000,000,1 ≤ L ≤ 100, A/B ≤ L。
代码:

#include<bits/stdc++.h>
using namespace std;
int main()
{
	double a,b,l,x,y;
	cin>>a>>b>>l;
	double m=1e9,tmp,k=a/b;
	for(double i=1;i<=l;i++)
	{
		for(double j=1;j<=l;j++)
		{
			tmp=i/j-k;//记录差值 
			if(tmp<m&&tmp>=0)//记录最小的差值 
			{
				x=i;
				y=j;
				m=tmp;
			}
		}
	}
	cout<<x<<" "<<y<<endl;
	return 0;
}
  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值