【问题标题】:How to make my program work faster?如何让我的程序运行得更快?
【发布时间】:2017-03-19 17:47:59
【问题描述】:

我尝试运行此代码,但在少数情况下显示超出时间限制,我该如何缩短时间?

我需要了解我在我的程序中使用了哪些时间很长的东西,比如一些函数等。我知道通过改进迭代和复杂性,我可以减少执行时间,但它没有多大帮助。请帮助

程序很简单,我取点a和点b,计算所有回文数的个数。

#include<stdio.h>
int ifpalin(int g)
{
    int rev=0;
    int tmp=g;
    while(tmp>0)
    {
        rev=rev*10+(tmp%10);
        tmp=tmp/10;
    }
    if(rev==g)
        return 1;
    else
        return 0;
}
int findpalin(int a1,int b1)
{
    int sm=0;
    for(int i=a1;i<=b1;i++)
    {
      if  (ifpalin(i)==1)
        sm++;
    }
    printf("%d",sm);
    printf("\n");
    return 0;
}
int main()
{
int a,b,n;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        scanf("%d",&a);
        scanf("%d",&b);
        findpalin(a,b);
    }
    return 0;
}

【问题讨论】:

  • C++ 还是纯 C ?
  • 如果此代码“有效”,但性能不够,codereview.stackexchange.com 可能更适合您的帖子。
  • 不要颠倒整个事情。当你不匹配或完成一半时停止。
  • 有趣的问题。你可以做几件事来优化你的程序。您可以通过从 ifpalin() 返回 rev 来摆脱至少一个 if-test,然后将返回的值与 findpalin() 中的 i 进行比较。另一种潜在的优化(测量它)是用一次调用 div() 替换 tmp 的模数和除法。
  • 您的代码不仅比应有的慢 0.0015 秒。它只是在超过时间限制后终止。它比这慢得多。您需要使用更高效的算法。

标签: c++ c algorithm optimization


【解决方案1】:

您的代码已经非常高效(作为算法的实现,这是可以改进的)。这些挑战希望你找到一种“不明显”但更高效的算法。即,在这种特殊情况下,您不应检查ab 之间的每个数字。

这里还有另一种解决方案,即您可以直接“知道”回文的数量。想一想:

一位数有10回文[0, ..., 9]

两位数有9回文[11, ..., 99]

对于三位数字,有 9 种可能性,其中第一位和最后一位数字相等 [1, ..., 9]。对于一个可行的回文,中间也必须是一个回文。由于中间有一位,我们知道这里有 10 种可能的回文,因此我们有 9 * 10 = 90 3 位回文。

四位数字,我们得到9 * 10(两位回文,现在也允许00)和五位数字9 * 100(三位数字,允许从0开始)。

因此,您可以推导出 n 位数字的公式。 然后,您可以直接导出 a 和 b 之间的大条纹的数量,只需要担心哪些数字是相关的,以及由于 a 和 b 不是10^(n-1) 和和而在开头和结尾丢失了多少数字10^n - 1

【讨论】:

    【解决方案2】:

    对于每个给定的 g,您的 int ifpalin(int g) 函数可以并行运行,因为该函数的输入数据似乎不同,对其他数据没有影响。你可以并行运行这个函数。

    int findpalin(int a1,int b1)函数中,有一个复杂度为N的for循环,你可以在这里运行你的线程。 (每个线程,运行函数ifpalin)。当然,需要一个好的并行计划。 你可以在一些逻辑上运行这个函数,然后聚合结果。

    另一方面,任何基准测试都应在发布模式下执行。

    希望对你有帮助。

    如果我的英文写得不好,请见谅,请纠正我

    【讨论】:

      【解决方案3】:
      在伊芙琳 将数字转换为字符串 反转字符串 与原作对比 如果相等,则为回文

      How to reverse an std::string?

      【讨论】:

      • 将数字转换为字符串涉及模数和除法,只是它发生在 sprintf 函数中而不是显式地发生。
      • 重点是将数字转换为字符串或const char *,然后将其反转并与原始“==”。这就是你如何知道left2right = right2left
      • 我知道你在说什么,但这种方法不会加速算法,这是问题的重点。
      • 斯坦,你差不多有东西了。诀窍是首先消除转换数字 字符串的需要,并在整个过程中保持在字符串中。
      猜你喜欢
      • 2018-08-23
      • 2021-05-11
      • 1970-01-01
      • 1970-01-01
      • 2017-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-28
      相关资源
      最近更新 更多