第十一讲 do while

      今天的内容主要是说昨天留给大家思考的问题,这个问题说难不难,就是有些麻烦,相信有同学已经得出答案了,不管如何,还是以前那句话,我们从头理一理吧。
从原题目入手,年龄的三次方是4位数,那么我们可以得出一个范围来,我们可以声明一个long类型变量来储存这个值
long  sum1;
sum1的取值范围我们可以明确的知道大于1000并且小于10000。
(sum1>1000 &

&

sum1 <10000)
接下来我们可以再从第二个条件知道,年龄的4次方是6位数,于是我们再声明一个long类型变量sum2来储存这个值,并且得到他的取值范围是在100000和1000000之间:
long sum2;
     (sum2>100000 &

&

sum2<1000000);


说到这里,顺便说一下,算是补漏吧,千万不要写出下面类型的判断语句出来,这是C/C++不认同的:
(100000<sum2<1000000)(错误的代码);


既然说到sum1和sum2,那么大家是不是想问,sum1和sum2的值从何而来?在C/C++里面的math.h库里有个power(n,m)函数,该函数返回n的m次方值,不过今天,我们不想直接使用这个库,我们自己写一个计算幂次方的函数来调用就好,反正是公众课,所以我想大家不会嫌代码多的是吧,下面我们就简单的先把幂次方的函数定义出来:
——————————–
long power(int n,int m)
{
long s=1;

while(m–)
{
s *= n;

}

return s;

}
——————————-
既然power已经定义好了,那么我们的sum1和sum2就顺理成章的计算出来了:
sum1 = power(i,3);


     sum2 = power(i,4);


i是一个int变量,用来遍历年龄的,上面的代码如果不是因为教学的原因,可以不用写那个幂次方函数,直接使用i*i*i和i*i*i*i即可。
但是大家是不是发现一个问题,同学满足sum1和sum2的值不少,而且我们又看不见,难道说我们还要先把这个值打印出来再来研究这问题吗?其实本来有种思想就很简单的,就是自己预先演算一边,把同时满sum1和sum2的值计算出来,然后来用do while循环计算出年龄,这种方法要自己一个数字一个数字的去计算,不过可以根据我们大概的判断一下范围来围绕计算也不会是太难的,但是这不是我们今天要说的重点,毕竟我也很懒不想去想这个范围到底在哪里。既然这样,那我们把同时满足sum1和sum2的值的个数和最大值分别用一个函数计算出来,然后把他们传回main()中就可以了,下面我们分别实现返回个数和最大的两个函数:
—————————————-
//返回同时满足sum1和sum2的年龄数
int age()
{
int age[100];

int count = 0;

long sum1,sum2;

for(int i=0;

i<100;

i++)
{
sum1 = power(i,3);

sum2 = power(i,4);

if(sum1 >1000 &

&

sum1 <10000 &

&

sum2 >100000 &

&

sum2 <1000000)
{
age[i] = i;

count++;

}
}

return count;

}
————————————-
————————————-
//返回满足sum1和sum2的最大值
int agemax()
{
int age[25]={0 },max = 0;

long sum1,sum2;

for(int i=0;

i<25;

i++)
{
sum1 = power(i,3);

sum2 = power(i,4);

if(sum1 >1000 &

&

sum1 <10000 &

&

sum2 >100000 &

&

sum2 <1000000)
{
age[i] = i;

}
if(max<age[i])
{
max = age[i];

}
}

return max;

}
————————————
两个函数差不多,如果我们直接使用打印输出的话只需要一个函数就好,但是我们现在是用他们的返回值来作为参数,所以我们把他们写成两个函数,分别返回不同的值。
我们现在知道最大值和个数,再加上这些数据都是连续的整数,所以我们通过最大值+1再减去个数便得到最小满足sum1和sum2的值。
这些都准备好了,现在我们可以回来设计我们的计算部分了,这里我们会使用do while来循环计算,wo while是我们今天的主角,所以现在来说说一下这个循环的用法。
———————————-
do
{
do something;
}while(条件);
———————————–
从上面这个声明中,想必大家都清楚了,do while是先执行一遍程序然后再来判断满足否,如果不满足直接退出,如果满足继续循环,所以在三个循环函数中,可以根据具体的情况选择不同的循环来循环。
大家是不是还意识一点,在三个循环函数中,只有do while循环在while后面加分号,记住,这是一定要加的。
循环就是循环,没有什么花样,下面我们就用这个循环来计算昨天留下的问题,不过再给出最终代码之前,还是有先说一些必要的要点。
我们虽然得到一个范围,但是我们还有一个条件没有满足,那就是sum1和sum2里面没有重复的数字,这一点怎么来得出呢?首先我们要把sum1和sum2里面的所有数字取出来,怎么取?大家还记得前几讲说过的取余“%”运算符吗?现在我们就要用它和取整来对sum1和sum2取余,然后我们把每位都储存在一个数组里面,所以我们要在开头先声明一个数组,为了和早些时候的sum1和sum2区分开,我们这里声明为sum3和sum4操作如下:
——————————–
int  a[10] ={0 }//分辨用0来初始化
……
//对sum3
for(i=3;

i>=0;

i–)
{
       a[i] = sum3%10;
       sum /=10 ;

// sum = sum/10;
}
//对sum4
for(i=9;

i>3;

i–)
{
       a[i] = sum4%10;


       sum4 /= 10;


}
————————————
这样,我们便得到一个包含10个元素的数组,其中这10个元素要满足各不相同的条件,也就是他们分别是:0,1,2,3,4,5,6,7,8,9。那么怎么判断呢?我们可以再声明一个数组int s[10]={0 },同样用0去初始化,然后用a[10]的元素去作为的下标,统计这些数字出现的次数,方法如下:
————————————-
//统计数字出现的次数
for(i=0;

i<=9;

i++)
{
     s[a[i]]++;


}
————————–
接下来我们判断一下有没有重复的数字,方法如下:
——————————
//判断有没有重复数字然后顺便打印出结果
for(i=0;

i<=9;

i++)
{
     if(s[i] == 1)//如果有重复,就不会满足这个条件,然后会跳转到下面的break。
    {
         if(i == 9)//这个判断没多大意义,就是为了只打印一遍就好,否则会打印出10遍来。
            printf(” 同学的年龄是:%dn”,c);

     
      }
     else
        break;


}
————————————
说到这里,想必大家应该都清楚了,下面是完整的程序清单,当然大家可以尝试一下简单的那个方法,就是自己预先算出能够满足sum1和sum2的值,然后再做循环,那样就不需要另外的三个程序。
—————————————-
//完整清单
#include <stdio.h>#include <stdlib.h>long power(int n,int m);

int age();

int agemax();

int main()
{
int n,m,c;

long a[10]={0 },s[10]={0 },i,sum3,sum4;

n = age();

m = agemax();

c = m-n+1;

do
{
sum3 = power(c,3);

for(i=3;

i>=0;

i–)
{
a[i] = sum3%10;

sum3 = sum3/10;

}
sum4 = power(c,4);

for(i=9;

i>3;

i–)
{
a[i] = sum4%10;

sum4 = sum4/10;

}
for(i=0;

i<=9;

i++)
{
s[a[i]]++;

}
for(i=0;

i<=9;

i++)
{
if(s[i] == 1)
{
if(i == 9)
printf(“这位同学的年龄是:%dn”,c);

}
else
break;

}
c++;

}while(c<=m);

system(“PAUSE”);

return 0;

}
//实现幂次方
long power(int n,int m)
{
long s=1;

while(m–)
{
s *= n;

}

return s;

}
//求满足sum1和sum2的个数
int age()
{
int age[25];

int count = 0;

long sum1,sum2;

for(int i=0;

i<25;

i++)
{
sum1 = power(i,3);

sum2 = power(i,4);

if(sum1 >1000 &

&

sum1 <10000 &

&

sum2 >100000 &

&

sum2 <1000000)
{
age[i] = i;

count++;

}
}

return count;

}
//求出满足sum1和sum2的最大值
int agemax()
{
int age[25]={0 },max = 0;

long sum1,sum2;

for(int i=0;

i<25;

i++)
{
sum1 = power(i,3);

sum2 = power(i,4);

if(sum1 >1000 &

&

sum1 <10000 &

&

sum2 >100000 &

&

sum2 <1000000)
{
age[i] = i;

}
if(max<age[i])
{
max = age[i];

}
}

return max;

}
———————————–
现在我们来看下输出:
第十一讲 do while
哦,原来臭小子是18岁啊,如果有持怀疑精神的可以自己推算一下吧,把这个程序理解后我相信大家不但学会了do while还学会了很多东西,好吧,今天就到这里,大家有兴趣证明一下尼科彻斯吗?
====================
尼科彻斯定理:
任何一个整数的立方都可以写成一连串的连续奇数之和,大家可以编程证明这个定理,知识点不会超出我们现在所讲范围。
====================

发表评论