[problem4]欧拉

A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.

Find the largest palindrome made from the product of two 3-digit numbers.

最优运算时间:8ms来自代码B。

这个看似简单的问题再一次教会我了很多原来从未注意过考虑过的东西。从中学到的:

1. 能调用库函数一定调用库函数,不要自己写:效率实在有很大差距 (下面有运算时间的数据对比)。

2. 在问题规模大的情况下,判断是否回文数的函数调用要尽量减少。两种方法:1. 用stl::set去存下来已经判断过的i*j,来避免对同一个数的重复判断。结论:用了比不用还慢。 可见,使用sorted容器是有代价的;2. 先比大小再判断是否回文数。虽然逻辑上看不如把比大小放在确定是回文数的if里合理,但却显著减少了对判断回文数函数的调用次数,大大减少了运算时间。

代码A:只改变判断回文数的算法,一种用库函数,另一种自己写实现,效率相差52s / 1s = 52倍!

View Code
#include <string>
#include 
<iostream>
#include 
<set>
#include
<ctime>
using namespace std;

bool ispalindromic(int val)
{
    
// Call CRT functions, cost 1s.
    char a[10];
    memset(a, 
010);
    _itoa_s(val, a, 
10); // instead of using itoa.
    char b[10];    
    strcpy_s(b, a); 
// instead of usiing strcpy.
    _strrev(b);// directly reverse b array.
    return 0 == strcmp(a, b) ? true : false;    

    
// Call myself code, cost 52 seconds.
    
//string strVal;
    
//while(val > 0)
    
//{    
    
//    char oneChar = val%10 + '0'; // 8 + '0' = '8'
    
//    strVal.push_back(oneChar);
    
//    val = val/10;
    
//}
    
//
    
//size_t cnt = strVal.size();    
    
//bool bFlag = true;
    
//for(size_t i = 0; i < cnt/2; i++)
    
//{
    
//    if(strVal.at(i) != strVal.at(cnt-1-i))
    
//    {
    
//        bFlag = false;
    
//        break;
    
//    }
    
//}

    
//return bFlag;
}

int _tmain(int argc, _TCHAR* argv[])
{
    time_t startTime 
= time(NULL);
    
//clock_t a = clock();
    int maxProduct = 0;
    
for(int i = 999; i >= 100; i--)
    {
        
for(int j = 999; j >= 100; j--)
        {
            
int temp = i*j;            
            
if(ispalindromic(temp))
            {
                
if(temp > maxProduct)
                    maxProduct 
= temp;
            }
        }
    }        
    time_t endTime 
= time(NULL);
    
//clock_t b = clock();
    double spendTime = difftime(endTime, startTime);
    
//spendTime = difftime(b, a);
    cout << maxProduct << endl;
    cout 
<< "timespent: " << spendTime << endl;

    
return 0;
}
 

代码B:基于代码A,调整temp > maxProduct的判断位置从而有效减少了判断回文函数的调用次数,效率相比代码A 554ms / 8ms = 69倍!

View Code
#include <string>
#include 
<iostream>
#include 
<set>
#include
<ctime>
using namespace std;

bool ispalindromic(int val)
{    
    
char a[10];
    memset(a, 
010);
    _itoa_s(val, a, 
10); // instead of using itoa.
    char b[10];    
    strcpy_s(b, a); 
// instead of usiing strcpy.
    _strrev(b);// directly reverse b array.
    return 0 == strcmp(a, b) ? true : false;        
}

int _tmain(int argc, _TCHAR* argv[])
{
    clock_t a 
= clock();
    
int maxProduct = 0;
    
for(int i = 999; i >= 100; i--)
    {
        
for(int j = 999; j >= 100; j--)
        {
            
int temp = i*j;    

            
// cost 8ms.
            if(temp > maxProduct && ispalindromic(temp))
            {
                maxProduct 
= temp;
            }

            
// cost 554 ms (it's the 1s for CodeA).
            /*if(ispalindromic(temp))
            {
                if(temp > maxProduct)
                    maxProduct = temp;
            }
*/
        }
    }        
    clock_t b 
= clock();
    
double spendTime = difftime(b, a);
    cout 
<< maxProduct << endl;
    cout 
<< "timespent: " << spendTime << endl;

    
return 0;
}

代码C:基于代码B,使用stl::set做所谓的优化,效率相比代码B 16s/8ms = 2000倍的时间损耗!

View Code
#include <string>
#include 
<iostream>
#include 
<set>
#include
<ctime>
using namespace std;

bool ispalindromic(int val)
{    
    
char a[10];
    memset(a, 
010);
    _itoa_s(val, a, 
10); // instead of using itoa.
    char b[10];    
    strcpy_s(b, a); 
// instead of usiing strcpy.
    _strrev(b);// directly reverse b array.
    return 0 == strcmp(a, b) ? true : false;        
}

int _tmain(int argc, _TCHAR* argv[])
{
    clock_t a 
= clock();
    
int maxProduct = 0;
    
set<int> results;
    
for(int i = 999; i >= 100; i--)
    {
        
for(int j = 999; j >= 100; j--)
        {
            
int temp = i*j;    

            
// cost 16s or so!!
            /*if(results.end() != results.find(temp))
                continue;
            else
                results.insert(temp);
*/

            
// cost 8ms.
            if(temp > maxProduct && ispalindromic(temp))
            {
                maxProduct 
= temp;
            }            
        }
    }        
    clock_t b 
= clock();
    
double spendTime = difftime(b, a);
    cout 
<< maxProduct << endl;
    cout 
<< "timespent: " << spendTime << endl;

    
return 0;
}

 

 

posted @ 2011-03-02 22:29  能巴  阅读(168)  评论(0)    收藏  举报