第三周作业(二)
要求:
阅读下面程序,请回答如下问题:
问题1:这个程序要找的是符合什么条件的数?
问题2:这样的数存在么?符合这一条件的最小的数是什么?
问题3:在电脑上运行这一程序,你估计多长时间才能输出第一个结果?时间精确到分钟(电脑:单核CPU 4.0G Hz,内存和硬盘等资源充足)。
问题4:在多核电脑上如何提高这一程序的运行效率?
using System;
using System.Collections.Generic;
using System.Text;
namespace FindTheNumber
{
class Program
{
static void Main(string[] args)
{
int [] rg =
{2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,
20,21,22,23,24,25,26,27,28,29,30,31};
for (Int64 i = 1; i < Int64.MaxValue; i++)
{
int hit = 0;
int hit1 = -1;
int hit2 = -1;
for (int j = 0; (j < rg.Length) && (hit <=2) ; j++)
{
if ((i % rg[j]) != 0)
{
hit++;
if (hit == 1)
{
hit1 = j;
}
else if (hit == 2)
{
hit2 = j;
}
else
break;
}
}
if ((hit == 2)&& (hit1+1==hit2))
{
Console.WriteLine("found {0}", i);
}
}
}
}
}
答:
看到这个程序我没想那么多,直接复制粘贴到vs里去运行一下,但是并没有出结果。所以我猜这个程序需要运行很久很久才能出结果。所以还是开始老老实实的去分析程序了。
大概的分过程是:首先从整体浏览一遍程序,发现2个语句不是很明白,于是百度了一下,一个是for (Int64 i = 1; i < Int64.MaxValue; i++)这里其中Int64表示64位有符号整数,Int64.MaxValue便是其最大值即9223372036854775807。另一个是Console.WriteLine("found {0}", i);,这个是个输出语句,输出的是i的值。因此从这里入手分析,一共一个数组(2到31共30个数组成),两个for循环。很明显最终要找到的数是由第一个循环不断累加而得到的i,而第二个循环中的j代表的是数组的下标(从这里可知j < rg.Length)。最后再去看if语句构成的约束条件。这里先从最后一个if语句入手即if ((hit == 2)&& (hit1+1==hit2)),这里要同时满足hit == 2且hit1+1==hit2,才会输出最终结果。从这里分别去上面找对应的if语句。第一个条件if ((i % rg[j]) != 0)满足即不能被某个数整出时hit+1,而结合for中hit <=2可知是不能被某两个数整除,而hit1+1==hit2导致这两个数应该是连续的。最终这个程序要找到的i不能整除数组中的r[j]和r[j+1]这两个数,且能整除数组中其它28个数(Q1)。明显这个数是可以被整除的那28个数的最小公倍数。因此这个数应该非常非常大。Q2和Q3的算法参考网上这位大神的算法就好我看了一下感觉实在是好麻烦好麻烦下面是附上链接:http://blog.csdn.net/zhuhuiby/article/details/6742980。至于Q4如何提高效率,我觉得可以提高CPU频率来实现,或者尽量减少其他进程。最后表示这程序我已经跑了4个小时了还没出结果,不知道超级计算机上能不能秒出结果。。