C#编程之神奇程序找数

问题1:这个程序要找的是符合什么条件的数?

问题2:这样的数存在么?符合这一条件的最小的数是什么?

问题3:在电脑上运行这一程序,你估计多长时间才能输出第一个结果?时间精确到分钟(电脑:单核CPU 4.0G Hz,内存和硬盘等资源充足)。

问题4:在多核电脑上如何提高这一程序的运行效率?

(注:该程序、用C#语言编写,但是只要有C语言基础完全没有阅读压力,如果对部分语句不懂请自行查询)

将上述问题结果写到博客上,截止时间本周日(3月19日)晚8时

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);
        }
      }
    }
  }
}

首先,对于上述的几个问题我先不做回答,我先谈一下自己对于这个程序的理解,这个程序我自己运行了差不多三个小时,但是并没有出来结果,我想这应该是大多数同学共同的问题。第一眼看到这段代码的时候,我以为会在一分钟以内出来结果,然而第一次运行直接宣告了我认知上的错误。这说明这个程序有自己的内部原理,并不是我们常规情况下所遇到的很快就会出现结果的程序。运行没有得到任何的结果,但我并没有就此放弃,通过在稿纸上的模拟运算,我基本上了解了这段代码的目的。这段代码看起来并不难,但实际上它的运算量是相当庞大的。说完自己的理解,接下来我就对于这几个问题做简单分析解答。

问题1:

对于第一个问题,我的理解是寻找一个变量i,而这个i满足的条件应该是这几个条件:

条件一:(i % rg[j]!= 0)&&(i % rg[j+1]!= 0)&&(i % rg[j+2]== 0),也就是说对于三个连续的数a,b,c;i不能整出a和b,但可以整除c,比如当a=7,b=8,c=9;此时当i=54时满足这个条件;这是我分析的第一个条件。

条件二:在条件一的基础上还必须满足(hit == 2)&& (hit1+1==hit2)这个条件,此时这个数的范围就可以进一步缩小了,因为hit==2,这说明这个数只有不能被rg[j]和rg[j+1]整除,它可以被除rg[j]和rg[j+1]之外的所有数整除。

问题二:

1、对于这个问题,我们应该注意到问题1中的两个条件,因为通过问题1已经分析到rg[j]和rg[j+1]是两个连续的数,那么我们可以确定rg[j]和 rg[j+1]不小于16,以为如果rg[j]一旦小于16,那么rg[j]*2也在rg[]数组内,这样肯定是不满足(hit == 2)&& (hit1+1==hit2)这个条件的。最后得到的hit结果必然大于2。

2、rg[j]和rg[j+1]这两个连续的数也不能由rg[]数组中其他成员变量相乘得到,如果rg[j]和rg[j+1]中任意一个数可由数组中两个数相乘得到,那么该数组中将至少有四个数可以被i整除,也不满足(hit == 2)&& (hit1+1==hit2)这个条件。

3、结合以上两点我们将满足上述条件的数筛选出来{17,19,23,29,31},那么我们需要寻找的rg[j]和rg[j+1]中肯定有一个数在这个数组当中,而且我们完全可以分析得到这两个数是一奇一偶,那我们考虑乘积最小且必须满足第一点的情况,那就是rg[j]和rg[j+1]为16和17,与此同时,我们也考虑17和18,我们分析一下这两组数的区别,不能被16和17整除,但需要被数组内其他所有数整除,虽然16可以由2和8相乘得到,但2是8的因子,所以只要i能整除8,就必能整除2,这就是说i应该可以被8整除但不能被16整除。如果我们考虑18,那么i应该是可以被2和9整除的,但却不能被18整除,这显然是矛盾的。所以rg[j]和rg[j+1]为16和17。

4、以上这几点分析都是个人观点,而最后的答案我自己感觉应该是一个比较大的数,其实我个人观点是通过计算缩小i取值范围之后,可以从高位依次向下取值,这样可以更快的接近结果。具体答案我们可以参考CSDN上边也有大神的具体讲解,这里我对答案做一个引用i=8*25*27*7*11*13*19*23*29*31=2123581660200,之所以考虑到8,25,27,而不考虑除17之外的所有素数,能被27整除的数一定能被3和9整除,反之就不一定了。同理我们可以理解其他情况。

问题三:

对于这个问题,我自己的想法是考虑程序执行一次外循环,大约执行平均10次左右内循环,那么我们就需要计算执行着一次循环所需的时间,当然我自己确实没有什么更好的方法,参考网上的计算方法:我们可以假设该原子操作需要120个时钟周期。因此4GHz的CPU在1秒内能跑4*10^9 / 120= 3.33*10^7 即1670万次原子操作。对于外层循环执行了2123581660200次,内层循环取决于i的情况,这里我们粗略估计,内层循环平均可以跑10次,通过这样的计算方式我们大致可以得出总共执行的操作约为2123581660200/3.33*10^7=6.37*10^5秒,也就是大约10616分钟。

问题四:

首先多核运行比单核要快些,虽然系统说是可多任务运行,但对于单核来说实际上任务在CPU上还是串行处理,而多核就可以由多核来实现并行处理,总体运行速度当然也得到提高。这样我们就可以对程序进行并行运算,我的想法是将数值范围缩小到2...31相乘然后除去特殊数,并且让i从高位数开始计算。这样可能会提高程序效率。那么如果以自己电脑作为参照,我的笔记本在内核版本是占优为双核,但是CPU频率2.5GHZ,按照这些来进行计算,并且考虑对于算法的优化,那么这个时间大约为2123581660200/(2.5*10^9 / 200)= 16984分钟。那么如果是一个双核4GHZ的CPU,这个时间应该将减少大约一半。

总结:

这次的作业如果要说学到了什么,那我就觉得我学到了如何去分析一个程序的条件以及如何把复杂的问题转换为简单,通过一层一层的分析,最终接近了问题的答案,这次的作业有很多地方是参照大神们的方法进行理解和求解的,当然也有自己思考为什么要这么去做?感觉这次的作业应该是对于问题求解的方法的思考,如果我们直接考虑问题的答案,那么我们估计很难通过程序运行得到最终的结果。如果方法得当结果应该自然就可以得到了,至于思考的结果应该是仁者见仁智者见智了,当然具体我们可以参考这篇文章http://blog.csdn.net/zhuhuiby/article/details/6742980,这篇博客对于作业的前三个问题做了详细的分析以及作答,我们当然想不到这么全面,但是大概的思路是值得我们借鉴和学习的。

C#编程之神奇程序找数的更多相关文章

  1. UC高级编程--实现myls程序

    跟着达内视频,学习UC高级编程,完毕程序小练习. 主要练习的函数为:  int lstat(const char *path, struct stat *buf);  size_t strftime( ...

  2. AOP称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题

    AOP称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等待,Struts2的拦截器设计就是基于AOP的思想,是个比较经典的例子. 一 AOP的基本概念 (1)Asp ...

  3. JavaScript之父Brendan Eich,Clojure 创建者Rich Hickey,Python创建者Van Rossum等编程大牛对程序员的职业建议

    软件开发是现时很火的职业.据美国劳动局发布的一项统计数据显示,从2014年至2024年,美国就业市场对开发人员的需求量将增长17%,而这个增长率比起所有职业的平均需求量高出了7%.很多人年轻人会选择编 ...

  4. vc++编程之在程序中加入网址链接

    在vc++对话框编程中,我们处于某种需要(介绍自己的软件或者自己的博客)可以在对话框上增加一个网址链接,用户只要一点击,就进入了相应的网页,我在此演示下如何完成. 1 打开编译器,我们新建一个基于对话 ...

  5. Java经典算法四十例编程详解+程序实例

    JAVA经典算法40例 [程序1]   题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?   1.程 ...

  6. Linux shell编程02 shell程序的执行 及文件权限

    第一个shell脚本 1.       shell编程的方式 交互式shell编程 非交互式shell编程:执行的语句存放到一个文件 shell脚本:可以任意文件名,建议扩展名为sh 2.       ...

  7. Socket编程之聊天程序 - 模拟Fins/ModBus协议通信过程

    设备控制软件编程涉及到的基本通信方式主要有TCP/IP与串口,用到的数据通信协议有Fins与ModBus. 更高级别的通信如.net中的Remoting与WCF在进行C/S架构软件开发时会采用. 本篇 ...

  8. Linux 高性能服务器编程——高性能服务器程序框架

    问题聚焦:     核心章节.     服务器一般分为如下三个主要模块:I/O处理单元(四种I/O模型,两种高效事件处理模块),逻辑单元(两种高效并发模式,有效状态机)和存储单元(不讨论). 服务器模 ...

  9. Linux 高性能服务器编程——Linux服务器程序规范

    问题聚焦:     除了网络通信外,服务器程序通常还必须考虑许多其他细节问题,这些细节问题涉及面逛且零碎,而且基本上是模板式的,所以称之为服务器程序规范.     工欲善其事,必先利其器,这篇主要来探 ...

随机推荐

  1. webdriver 获取页面response

    在selenium webdriver实现自动化抓取数据过程中,发现无法从webdriver获取页面response 查来查去最终在 stackoverflow 上找到了这一篇文章 文章中说:webd ...

  2. 对Dataguard的三种模式的理解

    模式1:最大可保护模式: 必须同步. 模式2:最大可用性模式: 能同步就同步,不能同步就不同步. 模式3:最大性能模式: 异步模式.

  3. Python day1 ---python基础1

    本节内容 Python介绍 编程语言分类 Hello World程序 变量 字符编码 用户输入 数据类型初识 表达式if ...else语句 表达式while 循环 表达式for 循环 break a ...

  4. P1903 [国家集训队]数颜色 带修改莫队板子

    大概就是要多加一维time 然后按照(l的块,r的块,time)为关键字排序 转移区间修改还是按照莫队的方式(每个修改要记修改前后的状态) 然后玄学dalao告诉窝块大小设为\(O(n^{\frac{ ...

  5. idea 搜索不到前端的ajax controller接口的原因

    这是因为我把 web 目录设置成了 Excluded ,没有索引所以找不到了 参考: https://www.cnblogs.com/kinome/p/9991022.html IDEA 出现 upd ...

  6. Tomcat 下载与安装

    下载地址:http://tomcat.apache.org 根据自己电脑的系统下载Core节点下不同的版本.   Tomcat文件目录结构 bin:存放启动与关闭Tomcat的脚本文件 conf:存放 ...

  7. mybatis学习(一)-------XML 映射配置文件详解

    XML 映射配置文件 MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置(settings)和属性(properties)信息.文档的顶层结构如下: configuration 配 ...

  8. Jmeter+Ant+Jenkins持续集成方案改进

    关于Jmeter+Ant+Jenkins如何搭建持续集成环境,网上资料一大把,就不多说了,本文主要谈一下期间的问题及扩展该持续集成方案. 其实核心的流程不复杂,Jenkins管理构建项目,Ant配置脚 ...

  9. Playfair加密

    前面讲的不管是单码加密还是多码加密都属于单图加密,什么是单图加密和多图加密呢,简单来说单图加密就是一个字母加密一个字母,而多图加密就是一个字符组加密一个字符组.比如双图加密就是两个字母加密两个字母,这 ...

  10. Android工程导入Unity3D(避坑版)

    最近与各种牛逼的项目管理软件打交道,比如SourceTree,要看英文版的才看得懂,中文反而不会用!... 这篇博客适合没怎么接触过安卓的小伙伴们,网上也有很多相关的教程,但是大多都没有具体的操作或则 ...