优化大型乘法 C++ 的模
Optimizing Modulo of Large Multiplication C++
我正在尝试使我的程序更快地处理大数与模的乘法。这是我当前的代码:
#include <iostream>
#include <stdio.h>
using namespace std;
int main()
{
long multiply = 1;
char x;
while ( (x = getchar()) != '\n' )
{
multiply = (multiply*(x-64))%26;
}
if (multiply < 10)
printf("0%d\n", multiply);
else
printf("%d\n", multiply);
return 0;
}
(首先,我得到一个警告,因为你使用符号 %d
来打印 long
,可能你可以只使用 int
并且它不会有什么不同因为最大值是 26。)
我认为您可以通过使用无符号整数类型来提高速度,因为对于无符号整数,模运算要简单一些。 (仅通过查看生成的程序集很难确定...https://goo.gl/LAc42f)
我猜 getchar
是您的瓶颈。您可以尝试一次阅读更大的块:
#include <cstdio>
#include <cctype>
#define BUFFER 2048
#define OFFSET ('A' - 1)
#define MODULUS 26
using namespace std;
int main()
{
char buffer[BUFFER];
int count, done = 0, multiply = 1;
while (!done && (count = fread(buffer, sizeof(char), BUFFER, stdin)))
{
for (int i = 0; i < count; i++)
{
if (isupper(buffer[i]))
{
multiply *= (buffer[i] - OFFSET);
multiply %= MODULUS;
}
else
{
done = 1;
break;
}
}
}
printf("%02d\n", multiply);
return 0;
}
还修复了 printf
并删除了幻数。它适用于测试用例。
注意一点,如果模运算后得到的结果为零,那么继续下去就没有意义了,因为之后你的乘积将永远为零,所以你可以在那里做一个快捷方式:
#include <cstdio>
#include <cctype>
#define BUFFER 2048
#define OFFSET ('A' - 1)
#define MODULUS 26
using namespace std;
int main()
{
char buffer[BUFFER];
int count, done = 0, multiply = 1;
while (!done && multiply && (count = fread(buffer, sizeof(char), BUFFER, stdin)))
{
for (int i = 0; multiply && i < count; i++)
{
if (isupper(buffer[i]))
{
multiply *= (buffer[i] - OFFSET);
multiply %= MODULUS;
}
else
{
done = 1;
break;
}
}
}
printf("%02d\n", multiply);
return 0;
}
分块阅读和快捷方式优化可能是您克服时间限制所需要的。
我正在尝试使我的程序更快地处理大数与模的乘法。这是我当前的代码:
#include <iostream>
#include <stdio.h>
using namespace std;
int main()
{
long multiply = 1;
char x;
while ( (x = getchar()) != '\n' )
{
multiply = (multiply*(x-64))%26;
}
if (multiply < 10)
printf("0%d\n", multiply);
else
printf("%d\n", multiply);
return 0;
}
(首先,我得到一个警告,因为你使用符号 %d
来打印 long
,可能你可以只使用 int
并且它不会有什么不同因为最大值是 26。)
我认为您可以通过使用无符号整数类型来提高速度,因为对于无符号整数,模运算要简单一些。 (仅通过查看生成的程序集很难确定...https://goo.gl/LAc42f)
我猜 getchar
是您的瓶颈。您可以尝试一次阅读更大的块:
#include <cstdio>
#include <cctype>
#define BUFFER 2048
#define OFFSET ('A' - 1)
#define MODULUS 26
using namespace std;
int main()
{
char buffer[BUFFER];
int count, done = 0, multiply = 1;
while (!done && (count = fread(buffer, sizeof(char), BUFFER, stdin)))
{
for (int i = 0; i < count; i++)
{
if (isupper(buffer[i]))
{
multiply *= (buffer[i] - OFFSET);
multiply %= MODULUS;
}
else
{
done = 1;
break;
}
}
}
printf("%02d\n", multiply);
return 0;
}
还修复了 printf
并删除了幻数。它适用于测试用例。
注意一点,如果模运算后得到的结果为零,那么继续下去就没有意义了,因为之后你的乘积将永远为零,所以你可以在那里做一个快捷方式:
#include <cstdio>
#include <cctype>
#define BUFFER 2048
#define OFFSET ('A' - 1)
#define MODULUS 26
using namespace std;
int main()
{
char buffer[BUFFER];
int count, done = 0, multiply = 1;
while (!done && multiply && (count = fread(buffer, sizeof(char), BUFFER, stdin)))
{
for (int i = 0; multiply && i < count; i++)
{
if (isupper(buffer[i]))
{
multiply *= (buffer[i] - OFFSET);
multiply %= MODULUS;
}
else
{
done = 1;
break;
}
}
}
printf("%02d\n", multiply);
return 0;
}
分块阅读和快捷方式优化可能是您克服时间限制所需要的。