【问题标题】:Optimizing Modulo of Large Multiplication C++优化大乘法 C++ 的模
【发布时间】:2023-04-04 09:05:02
【问题描述】:

我正在尝试使我的程序更快,该程序处理带模的大数乘法。这是我当前的代码:

#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;
}

【问题讨论】:

    标签: c++ multiplication modulo


    【解决方案1】:

    (首先,我收到一个警告,因为您使用符号%d 来打印long,也许您可​​以只使用int,它不会有任何区别,因为最大值是26。)

    我认为您可以通过使用无符号整数类型来提高速度,因为对于无符号整数来说,模数更简单一些。 (仅通过查看生成的程序集很难确定...https://goo.gl/LAc42f

    【讨论】:

    • 我进行了更正并将其更改为无符号整数,但仍然超出时间限制。不知道是不是真的是速度的原因,还是上传时程序卡死的其他原因。
    • 我认为你可以摆脱 iostream 包括? iiuc 当您包含该标头时,一些静态初始化内容会添加到您的程序中。但这里应该很少……时间限制是多少?
    • 你为什么要读到“\n”?你确定他们给你的输入是“\n”终止的吗?我在声明中没有看到这一点。我猜它说的是第一行......嗯......
    • 成功了!将条件更改为 isupper() ,它终于起作用了。在我尝试了大量算法后,我知道这是导致程序卡住的原因,而不是它的实际速度哈哈。谢谢!
    • 嘿嘿没问题的伙伴:)
    【解决方案2】:

    我猜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;
    }
    

    分块阅读和快捷方式优化可能是您打破时间限制所需要的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-03-10
      • 2021-06-02
      • 2010-09-14
      • 2012-02-19
      • 2015-12-25
      • 1970-01-01
      相关资源
      最近更新 更多