好的,这有点奇怪。我有一个算法来找到两个因子都有K位数字的最高可能数值回文。
我用的方法是查找数字集的最高可能回文(例如,如果k=3,则最高可能为999999,然后是998899等)。然后,我检查该回文是否具有两个K位数字的因子。
为了调试,我认为将我正在检查的每个回文打印到控制台是个好主意(以确保我得到了所有回文)。令我惊讶的是,添加
请注意,我在HasKDigits函数中把Math.Floor操作注释掉了。这是因为我当时想确定我的数字检查操作是否比Math.Floor操作更快。谢谢!
编辑:函数调用
我正在使用StopWatch来测量处理时间。我还使用了一个物理秒表来验证StopWatch的结果。
我用的方法是查找数字集的最高可能回文(例如,如果k=3,则最高可能为999999,然后是998899等)。然后,我检查该回文是否具有两个K位数字的因子。
为了调试,我认为将我正在检查的每个回文打印到控制台是个好主意(以确保我得到了所有回文)。令我惊讶的是,添加
Console.WriteLine(palindrome.ToString());
每次寻找回文数的迭代都能将我的运行时间从约24秒降低到约14秒。
为了验证,我多次运行了程序,然后注释掉了Console命令并多次运行,每次都比有Console命令时更短。
这看起来很奇怪,有什么想法吗?
如果有人想尝试,请参考以下源代码:
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);