【发布时间】:2014-07-20 19:53:50
【问题描述】:
好吧,这有点奇怪。我有一个算法可以找到最大可能的数字回文数,它是两个因子的倍数,每个因子都有 K 个数字。
我用来查找最高有效回文的方法是查看数字集的最高可能回文(即,如果 k=3,则最高可能是 999999,然后是 998899,等等)。然后我检查那个回文是否有两个 K 位数的因子。
对于调试,我认为将我正在检查的每个回文都打印到控制台是个好主意(以确保我得到了所有内容。令我惊讶的是,添加
Console.WriteLine(palindrome.ToString());
对于每次寻找回文的迭代,我的运行时间从 ~24 到 ~14 下降了惊人的 10 秒。
为了验证,我运行了几次程序,然后注释掉了控制台命令并运行了几次,每次都更短使用控制台命令。
这看起来很奇怪,有什么想法吗?
如果有人想试一试,这里是来源:
static double GetHighestPalindromeBench(int k)
{
//Because the result of k == 1 is a known quantity, and results in aberrant behavior in the algorithm, handle as separate case
if (k == 1)
{
return 9;
}
/////////////////////////////////////
//These variables will be used in HasKDigitFactors(), no need to reprocess them each time the function is called
double kTotalSpace = 10;
for (int i = 1; i < k; i++)
{
kTotalSpace *= 10;
}
double digitConstant = kTotalSpace; //digitConstant is used in HasKDigits() to determine if a factor has the right number of digits
double kFloor = kTotalSpace / 10; //kFloor is the lowest number that has k digits (e.g. k = 5, kFloor = 10000)
double digitConstantFloor = kFloor - digitConstant; //also used in HasKDigits()
kTotalSpace--; //kTotalSpace is the highest number that has k digits (e.g. k = 5, kTotalSpace = 99999)
/////////////////////////////////////////
double totalSpace = 10;
double halfSpace = 10;
int reversionConstant = k;
for (int i = 1; i < k * 2; i++)
{
totalSpace *= 10;
}
double floor = totalSpace / 100;
totalSpace--;
for (int i = 1; i < k; i++)
{
halfSpace *= 10;
}
double halfSpaceFloor = halfSpace / 10; //10000
double halfSpaceStart = halfSpace - 1; //99999
for (double i = halfSpaceStart; i > halfSpaceFloor; i--)
{
double value = i;
double palindrome = i;
//First generate the full palindrome
for (int j = 0; j < reversionConstant; j++)
{
int digit = (int)value % 10;
palindrome = palindrome * 10 + digit;
value = value / 10;
}
Console.WriteLine(palindrome.ToString());
//palindrome should be ready
//Now we check the factors of the palindrome to see if they match k
//We only need to check possible factors between our k floor and ceiling, other factors do not solve
if (HasKDigitFactors(palindrome, kTotalSpace, digitConstant, kFloor, digitConstantFloor))
{
return palindrome;
}
}
return 0;
}
static bool HasKDigitFactors(double palindrome, double totalSpace, double digitConstant, double floor, double digitConstantFloor)
{
for (double i = floor; i <= totalSpace; i++)
{
if (palindrome % i == 0)
{
double factor = palindrome / i;
if (HasKDigits(factor, digitConstant, digitConstantFloor))
{
return true;
}
}
}
return false;
}
static bool HasKDigits(double value, double digitConstant, double digitConstantFloor)
{
//if (Math.Floor(Math.Log10(value) + 1) == k)
//{
// return true;
//}
if (value - digitConstant > digitConstantFloor && value - digitConstant < 0)
{
return true;
}
return false;
}
请注意,我已将 HasKDigits 中的 Math.Floor 操作注释掉。当我试图确定我的数字检查操作是否比 Math.Floor 操作快时,这一切都开始了。谢谢!
编辑:函数调用
我正在使用 StopWatch 来测量处理时间。我还使用了物理秒表来验证 StopWatch 的结果。
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
double palindrome = GetHighestPalindromeBench(6);
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}:{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);
Console.WriteLine();
Console.WriteLine(palindrome.ToString());
Console.WriteLine();
Console.WriteLine(elapsedTime);
【问题讨论】:
-
你的测量结果如何?
-
是在调试模式还是在发布模式下运行?什么 .NET 版本?你测量这个吗?您没有显示该度量的代码。
-
这确实是一个很大的猜测:可能是因为您正在写入 IO,您的线程会获得更多的处理器时间,因为 WriteLine 是同步的,因此会阻塞其他线程。
-
用函数调用编辑。谢谢!
-
@ForguesR 好主意!很可能就是这样。不过看起来还是很奇怪
标签: c# algorithm console performance