复合结构程序设计(14)

完成运算符表达式、流程控制、格式化输入输出后,复合结构程序设计将是第一次利用C/C++去解决实际问题。所谓复合结构程序设计即顺序、分支和循环三大结构相互嵌套配合使用来完成对实际问题的求解,这也是程序员锻炼思维逻辑、掌握计算机解决问题的入口。

循环结构的嵌套

循环里嵌入循环,一般情况下二重、三重循环比较多,再多层的循环嵌套情况比较少见。要注意的是循环嵌套循环次数是乘法计算,而不是加法。比如:两重循环,外循环10次,内循环100次,那么总共执行1000次循环(10行100列),这也是为什么多重循环需要尽量避免的原因。

两重循环经典的题目应该是矩阵输出(上三角、下三角、九九乘法表等)

#include <iostream>
#include <stdio.h>
using namespace std;

int main()
{
	int i,j;
	for(i=1;i<=9;i++)
	{
		for(j=1;j<=i;j++)
		{
            //C语言用printf   
            //printf("%d*%d=%d ",i,j,i*j);
			cout<<i<<"*"<<j<<"="<<i*j<<"  ";
		}
        //printf("\n");
		cout<<endl;
	}
	return 0;
}

注意点:

1、内循环j的终止条件是  j<=i,是因为九九乘法表是上三角,把i看成行,j就是列,第1行j<=1输出1个,第9行 j<=9 输出9个,注意理解这种控制的方法;

2、j 循环后的cout<<endl;是用于换行,第一行输出完毕,换行后再输出第二行等等;

3、每个 i * j 的输出后面带有空格,用来分开后的分割。

 循环嵌分支

应该说循环嵌分支的统计类型题是复合结构程序设计的起始点,典型的题目是统计某范围内符合特点的数据的个数或者和,比如统计【1,1000】满足3的倍数或者7的倍数的和:

#include <iostream>
#include <stdio.h>
using namespace std;

int main()
{
	int i,sum=0;//统计、累加,要注意清0
	for(i=1;i<=1000;i++)
	{
		if(i%3==0 || i % 7 ==0) sum += i;
	}
	cout<<sum<<endl;
	//printf("%d\n",sum);
	return 0;
}

1、统计和累加要注意清0,累乘则是清1;

2、for循环计数循环,一般包含从什么到什么的意义,要掌握好程序的大结构;

3、sum += i;复合赋值运算,用于累加,对计算机而言一般都是简单粗暴:遍历整个范围,满足条件的处理,不满足的忽略(穷举法)

4、i从1 开始还是从 3开始并不重要,在算法上这个称为问题的规模N,一重循环的计算称为算法复杂度N,两重循环(外循环规模N,内循环规模N)复杂度是N*N,想象一下N非常大!那么如果能够把两重循环的问题变成一重循环来解决,效率将得到非常大的提升!

5、复杂度是N的阶乘、N的N次方等等,称为"NP"问题(Non-deterministic Polynomial),解决NP问题是公认的世界级难题。

隐藏条件的循环嵌分支:求水仙花数,水仙花数是这样的三位数:它的百位立方+十位立方+个位立方正好等于它自己。比如:153 = 1 + 125 + 27 

#include <iostream>
#include <stdio.h>
using namespace std;

int main()
{
	int i,a,b,c;
	for(i=100;i<1000;i++)
	{
		a = i / 100;
		b = i /10 % 10;
		c = i % 10;
		if(a*a*a+b*b*b+c*c*c==i)
			cout<<i<<endl;
		   //printf("%d\n",i);
	}
	return 0;
}

1、隐含条件“三位数”,从100到999,马上可以确定程序的大结构应该是for计数循环;

2、思路也清晰,针对100到999,每个数判断是否为水仙花数,是则输出;

3、根据水仙花数的定义,每次循环都需要取出i的百位十位个位,联系整除与取余运算即可以解决这个问题;

4、要根据三大结构的特点把对应的功能写在正确的位置,比如取数字的三位操作,要写在循环体内:每个 i 都得取出三位进行判断(不多不少,循环),而输出应该放在循环体的分支下:可能有多个输出(多个肯定是循环,分支和顺序最多一次),不是每个i都是(加上分支条件);

还有方法来解这个问题

#include <iostream>
#include <stdio.h>
using namespace std;

int main()
{
	int a,b,c;
	for(a=1;a<=9;a++)
	{
		for(b=0;b<=9;b++)
		{
			for(c=0;c<=9;c++)
			{
				if(a*a*a+b*b*b+c*c*c == a*100+b*10+c)
					cout<<a*100+b*10+c<<endl;
				   //printf("%d\n",a*100+b*10+c);
			}
		}
	}
	return 0;
}

1、三位数是百位从1到9、 十位从0到9 、 个位从0到9 的数字组合起来的,这样三重循环同样可以遍历所有的三位数,注意百位从1开始;

2、组合成三位数:a*100+b*10+c  (乘位权值)

3、解决问题的方法不会只有一种,程序员应该养成尝试多种方法解决问题的习惯;三重循环与一重循环的复杂度一样(900 = 9 * 10 * 10),但是推荐第一种,因为代码行少点!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

易老师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值