📜  在竞争性编程中测试代码的技巧

📅  最后修改于: 2021-06-26 18:43:49             🧑  作者: Mango

测试编码问题有时会变得很忙。这是测试算法编程问题时要使用的一些技巧。

程序中的缺陷通常有四大类:

  1. 句法错误
  2. 语义错误
  3. 运行时错误/异常
  4. 逻辑错误

句法错误

语法错误通常是程序中的语法错误。

要检查程序中的语法错误,您应该按照以下步骤操作:

  • 在编译器中编译代码
  • 一些常见的语法错误是:
    • 大括号,括号等错位
    • 评论末尾放错位置
    • 印刷错误
    • 错位的关键字

语义错误

语义错误可能会服从语法,但会违反其他语言规则。
一些常见的语义错误是:

  • 对原始数据类型执行不正确的操作。
  • 调用未定义的实例方法。
  • 在使用变量之前不声明变量。

运行时错误/异常

运行时错误通常在程序执行时发生。
运行时错误/异常的示例包括:

  • 被零除
  • 数组索引超出范围
  • 格式错误数
  • 空指针异常

逻辑错误

逻辑错误是类设计或算法实现中的错误。
可以通过以下方法避免逻辑错误:

  • 力求简洁明了
  • 考虑极端或极端情况
  • 思考前/后条件
  • 组织代码

使用示例测试代码中的逻辑错误

测试代码中的逻辑错误/错误很难找到。这是在示例的帮助下,逐步测试了代码中的逻辑错误。

最大成对乘积问题–给定一个数组或N个数字的序列,目标是找到一个数字,该数字可以通过将该序列中的两个数字相乘得到。

解决方案

天真的解决方案– O(N 2 )

使用嵌套的for循环遍历序列中的每个可能的对。

C++
// Function to find the maximum
// pairwise product
int MaxPairwiseProduct(
    const std::vector& numbers)
{
    int max_product = 0;
    int n = numbers.size();
  
    // Loop to find the pairs
    // with the maximum product
    for (int first = 0; first < n;
         ++first) {
        for (int second = first + 1;
             second < n; ++second) {
            max_product
                = std::max(
                    max_product,
                    numbers[first]
                        * numbers[second]);
        }
    }
    return max_product;
}


C++
// Efficient Approach for the
// maximum product pair
long long MaxPairwiseProductFast(
    const std::vector& numbers)
{
    int large1 = -1;
    int large2 = -1;
    int n = numbers.size();
  
    // Loop to iterate over the elements
    // of the given array
    for (int i = 0; i < n; ++i) {
        if (numbers[large1] < numbers[i]
            || large1 == -1)
            large1 = i;
    }
    for (int j = 0; j < n; ++j) {
        if ((numbers[j] != numbers[large1])
            && ((numbers[large2] < numbers[j])
                || (large2 == -1))) {
            large2 = j;
        }
    }
  
    return ((long long)numbers[large1]
            * numbers[large2]);
}


C++
#include 
using namespace std;
  
// Function to show the stress
// Testing of the code
int main()
{
    while (true) {
        int n = rand() % 3 + 2;
        cout << n << endl;
        std::vector a;
        for (int i = 0; i < n; ++i) {
            a.push_back(rand() % 10);
        }
        for (int i = 0; i < n; ++i) {
            cout << a[i] << ' ';
        }
        cout << endl;
        long long res1 = MaxPairwiseProduct(a);
        long long res2 = MaxPairwiseProductFast(a);
        if (res1 != res2) {
            cout << "Wrong Answer: "
                 << res1 << ' '
                 << res2 << endl;
            break;
        }
        else
            cout << "OK\n";
    }
    return 0;
}


C++
// Function to find the maximum
// pair wise product
long long MaxPairwiseProductSuperFast(
    const std::vector& numbers)
{
    int poslarge1 = INT_MIN,
        poslarge2 = INT_MIN;
    int neglarge1 = INT_MIN,
        neglarge2 = INT_MIN;
    int n = numbers.size();
  
    if (n < 2) {
        return 0;
    }
    if (n == 2) {
        return ((long long)numbers[0]
                * numbers[1]);
    }
  
    // Loop to iterate over the elements
    // of the array and find the two
    // largest and two smallest elements
    for (int i = 0; i < n; ++i) {
        if (numbers[i] > poslarge1) {
            poslarge2 = poslarge1;
            poslarge1 = numbers[i];
        }
        else if (numbers[i] > poslarge2)
            poslarge2 = numbers[i];
        if (numbers[i] < 0
            && abs(numbers[i]) > abs(neglarge1)) {
            neglarge2 = neglarge1;
            neglarge1 = numbers[i];
        }
        else if (numbers[i] < 0
                 && abs(numbers[i]) > abs(neglarge2))
            neglarge2 = numbers[i];
    }
  
    return (
        std::max(
            (long long)poslarge1 * poslarge2,
            (long long)neglarge1 * neglarge2));
}


高效方法:

解决此问题的最佳方法是从序列中找到两个最大和两个最小的数字,并返回(最大,第二大)和(最小,第二最小)之间的乘积最大值。那将是O(n)时间。

下面是上述方法的实现:

C++

// Efficient Approach for the
// maximum product pair
long long MaxPairwiseProductFast(
    const std::vector& numbers)
{
    int large1 = -1;
    int large2 = -1;
    int n = numbers.size();
  
    // Loop to iterate over the elements
    // of the given array
    for (int i = 0; i < n; ++i) {
        if (numbers[large1] < numbers[i]
            || large1 == -1)
            large1 = i;
    }
    for (int j = 0; j < n; ++j) {
        if ((numbers[j] != numbers[large1])
            && ((numbers[large2] < numbers[j])
                || (large2 == -1))) {
            large2 = j;
        }
    }
  
    return ((long long)numbers[large1]
            * numbers[large2]);
}

测验

您可以对代码进行各种测试,但是最常见的测试可以是以下三种:

  1. 在提交代码进行评估之前,应该使用问题陈述中的示例测试来对代码进行测试,这是最容易输入和验证的代码。
  2. 小巧的案例,您可以手动输入,并且您知道答案。我们还解决了实现中的一些极端情况:(长长)处理整数范围问题,(if语句)和(abs)检查。
  3. 大型随机测试,由简单的脚本生成以测试时间复杂度。这种测试称为压力测试。

压力测试您的代码:

解决算法编程问题时,这实际上是一个非常标准的情况。那么什么是压力测试?通常,它是一个脚本,可以在无限循环中创建随机测试,并且对于每个测试,它都会在此测试中调用您的解决方案,并在同一测试中调用替代正确解决方案,并比较输出。如果您发现解决方案输出有所不同的测试,则可以检查其中一个返回错误的答案,对其进行调试,然后重新运行压力测试脚本。

下面是上述示例问题代码的压力测试示例:

C++

#include 
using namespace std;
  
// Function to show the stress
// Testing of the code
int main()
{
    while (true) {
        int n = rand() % 3 + 2;
        cout << n << endl;
        std::vector a;
        for (int i = 0; i < n; ++i) {
            a.push_back(rand() % 10);
        }
        for (int i = 0; i < n; ++i) {
            cout << a[i] << ' ';
        }
        cout << endl;
        long long res1 = MaxPairwiseProduct(a);
        long long res2 = MaxPairwiseProductFast(a);
        if (res1 != res2) {
            cout << "Wrong Answer: "
                 << res1 << ' '
                 << res2 << endl;
            break;
        }
        else
            cout << "OK\n";
    }
    return 0;
}

这个简单的脚本是您的压力测试算法。运行此命令,您会发现在某些情况下,当数组中出现重复的元素时,先前的实现会有所不同。

现在,这是由于算法中的一个被忽略的错误,即,我们检查了位置j处的数字是否与我们已经找到的最大值不同。但这正是问题所在。相反,我们需要的是j必须与large1不同,因为我们不想找到相同的索引,但是我们可以找到等于第一个找到的最大值的数字。因此,代替此比较,我们实际需要的是将jlarge1进行比较。

没有错误的最终解决方案:

C++

// Function to find the maximum
// pair wise product
long long MaxPairwiseProductSuperFast(
    const std::vector& numbers)
{
    int poslarge1 = INT_MIN,
        poslarge2 = INT_MIN;
    int neglarge1 = INT_MIN,
        neglarge2 = INT_MIN;
    int n = numbers.size();
  
    if (n < 2) {
        return 0;
    }
    if (n == 2) {
        return ((long long)numbers[0]
                * numbers[1]);
    }
  
    // Loop to iterate over the elements
    // of the array and find the two
    // largest and two smallest elements
    for (int i = 0; i < n; ++i) {
        if (numbers[i] > poslarge1) {
            poslarge2 = poslarge1;
            poslarge1 = numbers[i];
        }
        else if (numbers[i] > poslarge2)
            poslarge2 = numbers[i];
        if (numbers[i] < 0
            && abs(numbers[i]) > abs(neglarge1)) {
            neglarge2 = neglarge1;
            neglarge1 = numbers[i];
        }
        else if (numbers[i] < 0
                 && abs(numbers[i]) > abs(neglarge2))
            neglarge2 = numbers[i];
    }
  
    return (
        std::max(
            (long long)poslarge1 * poslarge2,
            (long long)neglarge1 * neglarge2));
}

如果您希望与行业专家一起参加现场课程,请参阅《 Geeks现场课程》和《 Geeks现场课程美国》。