【问题标题】:Segmentation Fault (SIGSEGV) in Geeks for Geeks problemGeeks for Geeks 问题中的分段错误 (SIGSEGV)
【发布时间】:2020-09-02 12:18:41
【问题描述】:

您好,我正在尝试使用 brute for 方法解决 Geeks for Geeks 上的一个问题,所以问题陈述是,

给定一个正整数数组。你的任务是找到阵列中的领导者。 注意:如果数组的元素大于或等于其右侧的所有元素,则该元素是领导者。此外,最右边的元素始终是领导者。

输入: 输入的第一行包含一个整数 T,表示测试用例的数量。 T 测试用例的描述如下。 每个测试用例的第一行包含一个整数 N,表示数组的大小。 第二行包含 N 个以空格分隔的整数 A1、A2、...、AN,表示数组的元素。

输出: 打印所有的领导者。

Constraints:
1 <= T <= 100,
1 <= N <= 107,
0 <= Ai <= 107

Example:
Input:
3
6
16 17 4 3 5 2
5
1 2 3 4 0
5
7 4 5 7 3
Output:
17 5 2
4 0
7 7 3

我开发了如下解决方案,

#include <iostream>

using namespace std;

long **leader;
long *cond; 

void leader_in_array(long *A,long N,long i) {
    long check = 0, count = 0;
    for (long j = N - 1; j >= 0 ; j--)
    {
        if (check <= A[j])
        {
            check = A[j];
            leader[i][count] = check;

            count++;
        }   
    }   

    cond[i] = count;
}

int main() {
    long T;

    cin >> T;

    leader = new long*[T];
    cond = new long(T);

    for (long i = 0; i < T; i++)
    {
        long N;
        cin >> N;
        long *A = new long(N);
        leader[i] = new long[N];

        for (long j = 0; j < N; j++)
        {
            cin >> A[j];
        }

        leader_in_array(A, N, i);

        delete [] A;

    }

    for (long i = 0; i < T; i++)
    {
        
        for (long j = cond[i] - 1; j >=0 ; j--)
        {
            cout << leader[i][j] << " ";
        }
        cout << endl;
        
    }

    delete [] leader;
    delete [] cond;
    
    return 0;
}

它适用于测试用例,但是当我尝试在实际用例中提交我的代码时,我收到了错误

分段错误 (SIGSEGV)

我了解它是什么,但无法确定我哪里做错了。

【问题讨论】:

标签: c++ arrays algorithm pointers


【解决方案1】:

在您更新的代码中,您似乎在 long *A = new long(N); 有错字,我相信您想要 long *A = new long[N];

不管怎样,你把事情复杂化了。首先,使用std::vector 消除所有内存分配的东西。其次,充分处理每个测试用例——即在所有测试用例完成之前不要保存打印。运行一个测试用例并打印该测试用例的结果。重复。

这是一个例子:

#include <iostream>
#include <vector>
#include <cstdint>
 
int main() {
    uint32_t T;
    std::cin >> T;
    while (T--) {
        uint32_t N;
        std::cin >> N;
        // Create input vector and read data
        // The parameter tells the vector the initial size
        std::vector<uint32_t> data(N);
        for (auto i = 0; i < N; i++) {
            std::cin >> data[i];
        }
        // max is the maximum value at each iteration of the loop
        // Initialized to the last value of the array
        uint32_t max = data.back();
        std::vector<uint32_t> results;
        // Move backwards through the input (i.e. right to left)
        for (auto it = data.rbegin(); it != data.rend(); it++) {
            // If current value is > any value to the right
            if (*it >= max) {
                results.push_back(*it);
                max = *it;
            }
        }
        // Print in reverse order before moving on to next test case
        for (auto it = results.rbegin(); it != results.rend(); it++) {
            std::cout << *it << " ";
        }
        std::cout << "\n";
    }
    return 0;
}

注意:如果不要求按一定顺序打印结果,可以去掉results向量,找到就打印一个数字。

此外,您可以在主循环之前创建一次向量,并根据需要调整它们的大小。不确定这会节省多少执行时间。

【讨论】:

  • 是的,我做到了,但我没有使用矢量,而是使用堆栈来更新我的答案,再次感谢。
【解决方案2】:

问题是 N 最多为 10**7 (10,000,000),但您只为 Aleader 的元素分配了 10 个元素。您必须分配足够的元素。

要实现这一点,有几点:

  • 数组A 分配在堆栈上。在某些环境中,堆栈限制为几 MB,因此应将其标记为 static 以将其从堆栈中删除。
  • 只需将int leader[100][10]; 更改为int leader[100][10000000]; 将导致告诉他们分配了太多内存。为避免这种情况,您应该只分配一个查询,并在阅读后立即回答每个查询,而不是保留所有查询的答案。

【讨论】:

  • /tmp/ccPXXg8a.o: In function `leader_in_array(int*, int, int)': beabd28accf1485b585ae542d1f8d997.cpp:(.text+0x93): relocation truncated to fit: R_X86_64_32S against symbol `cond_count' defined in .bss section in /tmp/ccPXXg8a.o /tmp/ccPXXg8a.o: In function `main': beabd28accf1485b585ae542d1f8d997.cpp:(.text+0x18d): relocation truncated to fit: R_X86_64_32S against symbol `cond_count' defined in .bss section in /tmp/ccPXXg8a.o collect2: error: ld returned 1 exit status
  • @DanielLangr 感谢您的通知。我重写了我的答案。
  • 好吧,正如您所说,我应该分别回答每个查询而不是存储答案,但是正如您所看到的问题陈述,我需要先获取所有输入,然后只显示所有查询的输出,所以我认为我需要存储它们
  • 我应该使用动态数组吗?
  • @50_Seconds_Of_Coding 我不认为我们需要先获取所有输入。使用动态数组应该没问题,但需要比静态数组更加小心。
【解决方案3】:

该错误已向您指出,但不值得修复。您的尝试过于复杂,似乎有一个更简单、微不足道的解决方案:一个循环,以相反的顺序搜索数组,然后简单地保持每次发现高于迄今为止看到的最高值的值时进行跟踪。就是这样。

问题指定值为正,因此我们可以简单地将低水位线初始化为 0,然后运行它。

void all_leaders_in_array(int *arr, size_t size)
{
    int highest=0;

    while (size > 0)
    {
        if (arr[--size] > highest)
        {
              // arr[size] is a "leader" value here,
              // do whatever you want with it, print it, etc...

              highest=arr[size];
        }
    }
}

就是这样。以上将在数组中找到所有所谓的“领导者”,使用一个简单的循环,没有任何复杂的逻辑。根据定义,这会抓取数组中高于所有以下值的所有值。当数组被搜索backwards时,解决方案变得更加简单。只需按倒数顺序跟踪看到的最高值,就可以结束了。

我在问题中找不到任何说明领导者值是否必须按其原始顺序显示的内容。上面的代码将以相反的顺序查找/打印值。如果它们必须按原始出现顺序报告,只需将每个值保存在单独的数组中,然后以相反的顺序打印 那个 数组。任务完成。

【讨论】:

  • 您好,谢谢您的回复,因为我可以看到您的逻辑它与我实现的没有什么不同,它只是我用来应用相同逻辑的循环。我们的主要问题是动态有效地存储输入和输出。
【解决方案4】:
#include <iostream>
#include <stack>

using namespace std;

void leader_in_array(long *A,long N) {
    long check = 0;
    stack<long> leader;
    for (long j = N - 1; j >= 0 ; j--)
    {
        if (check <= A[j])
        {
            check = A[j];
            leader.push(check); 
        }   
    }   

    while (leader.empty() == false)
    {
        cout << leader.top() << " ";
        leader.pop();
    }
    
}

int main() {
    long T;

    cin >> T;

    for (long i = 0; i < T; i++)
    {
        long N;
        cin >> N;
        long A[N];

        for (long j = 0; j < N; j++)
        {
            cin >> A[j];
        }

        leader_in_array(A, N);
        cout << endl;

    }
    
    return 0;
}

【讨论】:

    猜你喜欢
    • 2022-12-09
    • 1970-01-01
    • 1970-01-01
    • 2012-06-01
    • 2020-06-26
    • 2020-12-16
    • 2011-01-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多