天天看点

C#代码分析

作为一个计算机专业的学生,代码分析是一件很平常的,并且需要经常做的事情。

当刚接手一个程序编码、课设或者一个项目时,常常会因找不到思路而抓狂。而网络就是最好的工具,查看许多IT人的技术博客网站,经常采集他人代码的长处,就会得到非同一般的效果。如下代码是由C#编写,对这种语言不是很熟悉,但有C语言的基础,应该不是特别难。

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

现在把代码进行分解:基本看来是个找数的操作,它是由两个for循环嵌套控制,for (Int64 i = 1; i < Int64.MaxValue; i++)

首先Int64.MaxValue这个数是多大?在网上找到了答案,Int64是有符号 64 位整数数据类型,相当于C++中的long long、 C# 中的 long 和 SQL Server 中的 bigint,表示值介于 -2^63 ( -9,223,372,036,854,775,808) 到2^63-1(+9,223,372,036,854,775,807 )之间的整数。存储空间占 8 字节。用于整数值可能超过 int 数据类型支持范围的情况。那就应该是个很大的数了,在这么大的范围为了找几个数,看来不是很好找。。。

C#代码分析

再看小循环,for (int j = 0; (j < rg.Length) && (hit <=2) ; j++),rg[]是个内部含有由2~31的整数组成,共有30个数,rg.length=30。

那究竟什么样的数才会是要找的数呢

if ((hit == 2)&& (hit1+1==hit2))
	        {
	          Console.WriteLine("found {0}", i);
	        }
      

hit==2&&hit1+1==hit2满足这个条件才会输出,看一看判断条件if ((i % rg[j]) != 0),也就是说要从1~MaxLalue之内判断不能够整除的数,hit1为第一个不能整除数的下标,hit2为第二个不能整除数的下标。要求hit1+1==hit2,那就是说这两个数要连续,而第二个条件就是hit==2,for (int j = 0; (j < rg.Length) && (hit <=2) ; j++),hit>2就要退出小循环hit还要等于2,也就是说只能有两个不能被整除的数,而且要连续。

只能说这个数真心不太好找。。。

用vs运行了一下,等了90分钟没有结果。于是我改了下范围,大循环i<Int32.MaxValue,如下图,found1是循环结束的小标记(因为在Int64.MaxValue迟迟没有结束,就想着用一句话来标记一下,Int32.MaxValue运行时间为99.4314475)

运行时间代码:

TimeSpan ts2 = new TimeSpan(DateTime.Now.Ticks);
            string spanTotalSeconds = ts2.Subtract(ts1).Duration().TotalSeconds.ToString(); //计算整个程序的运行时间
            Console.WriteLine(spanTotalSeconds);
            Console.ReadKey();      
C#代码分析

范围是Int16.MaxValue时,运行如下:

C#代码分析

 然而或许我没等到时间,90分钟还没有结束(感觉第一次运行这么久),我的电脑是这样的配置,或许这样的数真的不存在

C#代码分析
C#代码分析

假设这个数出现在范围的一半位置,那么需要找2^62=4.611686018X10^18,假设计算机每秒计算一次,因为小循环内平均要执行4步,小循环会有2-30次不等,因为条件比较苛刻,所以估算大约要执行20步,那么,因为计算机位4.0GHZ,所以,计算机每秒执行2X10^8个小循环,即寻找这么多个数,那么需要,2.3X10^10秒,即为4X10^8分钟。。。。于是放弃了计算。。。。。。。

如果想提高计算速度,在多核电脑上我们可以给每个核分配不同的找数范围,提高计算效率,虽然觉得现在基本上多核技术都是在流水线技术上做文章,但是表示并不懂原理,只能想着在找数范围上做文章了。。。。。。