eaglet

本博专注于基于微软技术的搜索相关技术
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

有道难题第一题 在徐少侠的算法基础上改进

Posted on 2009-06-04 13:19  eaglet  阅读(2426)  评论(13编辑  收藏  举报
徐少侠的算法 见 有道难题第一题非OO解,极端记录160ms

这个算法的效率已经很高了,徐少侠后来又写了一个一次循环的,但效率没有提高。我的思路也是把两次循环改为一次循环,效率上提高了20%左右。

其实这个性能优化就是扣细节了,算法上没有什么改进


对两处进行改进

1. 一开始就对A和B 加 384,这样就不需要每次计算都减384了,减少了不少减法运算

2. 一次循环

 

另外eaglet 在考虑,是否可以考虑类似图像有损压缩的算法,把这个这个矩阵利用类似正交余弦变化转换到频域,

再通过频率域的数值分布得到特殊值在A,B 范围内的有效区域,然后针对这些有效区域进行运算,这样可以大大降低

运算的次数。不过这个数学模型真的很难建。

 

        static public int countSpecialNumbers(string[] field, int A, int B)
        
{
            
//一开始就对A和B 加 384,这样就不需要每次计算都减384了,减少了不少减法运算
            A += '0' * 8;  
            B 
+= '0' * 8;

            
int count = 0;
            
//因为加了一圈0以后整体行列数发生了变化
            int cols = field[0].Length + 2;

            
//将原有一维字符串数组进行转换并增加0
            string s = string.Concat(new string('0', cols + 1), String.Join("00", field), new string('0', cols + 1));

            
//int i;
            
//一次循环
            
//不循环外圈的0

            
for (int i = cols + 1; i < s.Length - cols - 1; i++)
            
{
                
int m = i % cols; //m 为 i 和 列宽取模,如果模为0 或者cols-1 则说明是外圈的0
                if (m > 0 && m < cols - 1)
                
{
                    
int number = s[i - cols - 1+ s[i - cols] + s[i - cols + 1+
                        s[i 
- 1+ s[i + 1+
                        s[i 
+ cols - 1+ s[i + cols] + s[i + cols + 1];

                    
if (number >= A && number <= B)
                    
{
                        count
++;
                    }

                }

            }


            
return count;
        }

 

测试结果

eaglet 的原来的算法
5
9
3
0
0
26
用时917毫秒
徐少侠 的算法
5
9
3
0
0
26
用时554毫秒
eaglet改进的算法
5
9
3
0
0
26
用时459毫秒

改进后性能比徐少侠的提高了18%