小编Bon*_*uin的帖子

为什么我的自下而上合并在Java中排序这么慢?

我花了几个小时试图找出为什么我的排序算法的Java版本比递归合并排序慢两倍,因为C和C++版本的速度提高了40-50%.我一直在删除越来越多的代码,直到我将所有代码都删除到一个简单的循环并合并,但它仍然是两倍慢.为什么这只在Java中这么慢?

作为参考,这是自下而上的合并排序可能是这样的:

public static <T> void sort(T[] a, T[] aux, Comparator<T> comp) {
    int N = a.length;
    for (int n = 1; n < N; n = n+n)
        for (int i = 0; i < N-n; i += n+n)
            merge(a, aux, i, i+n-1, Math.min(i+n+n-1, N-1), comp);
}
Run Code Online (Sandbox Code Playgroud)

这是递归版本:

public static <T> void sort(T[] a, T[] aux, int lo, int hi, Comparator<T> comp) {
    int mid = lo + (hi - lo) / 2;
    sort(a, aux, lo, mid, comp); …
Run Code Online (Sandbox Code Playgroud)

java sorting performance mergesort

8
推荐指数
1
解决办法
1121
查看次数

为什么编译器只向后看类型和函数声明?

这纯粹是为了满足我自己的好奇心,但为什么函数和类型只能在代码中先前定义的那些中解析,而不是在同一范围内的任何地方

有时它会在函数需要相互调用时显示:

void foo(int depth) { bar(depth + 2); }
void bar(int depth) { if (depth > 0) foo(depth - 3); }
Run Code Online (Sandbox Code Playgroud)

你需要在foo之前移动bar,或者事先声明bar:

void bar(int);
void foo(int depth) { bar(depth + 2); }
void bar(int depth) { if (depth > 0) foo(depth - 3); }
Run Code Online (Sandbox Code Playgroud)

在更复杂的示例中,您可能需要查看#include树和#ifndef警卫,以找出您的代码无法识别某个其他文件中定义的函数或类型的原因,如果您已经知道您应该检查该代码.


然后当然有这个经典:

typedef struct {
    Node *next;
} Node;
Run Code Online (Sandbox Code Playgroud)

你需要知道这是可能的:

typedef struct Node {
    struct Node *next;
} Node;
Run Code Online (Sandbox Code Playgroud)

......但显然许多人不这样做,他们只是到处都使用'void*'或'struct Node'.


那么,这些编译器也没有解决这个问题的原因吗?我可以理解预处理器只是向后检查,因为事情可以是#undefined,但是一旦声明了类型或函数,它就会存在并且不能被后来的定义重载.

这是出于历史原因,它们在首次开发时可用的技术有限吗?或者是否存在一些我遗漏的逻辑歧义?

c c++ parsing

6
推荐指数
1
解决办法
214
查看次数

C语言中可变参数宏的问题

我在C中的#define语句中有可选参数的问题,或者更具体地说是gcc 4.2:

bool func1(bool tmp) { return false; }
void func2(bool tmp, bool tmp2) {}
#define CALL(func, tmp, ...) func(tmp, ##__VA_ARGS__)

int main() {
   // this compiles
   CALL(func2, CALL(func1, false), false);

   // this fails with: Implicit declaration of function 'CALL'
   CALL(func2, false, CALL(func1, false));
}
Run Code Online (Sandbox Code Playgroud)

这显然是一个人为的例子,但确实显示了问题.有谁知道我怎么能得到正确的"解决"的可选参数?


附加信息:如果我删除##之前__VA_ARGS__,并执行以下操作:

bool func2(bool tmp, bool tmp2) { return false; }
#define CALL(func, tmp, ...) func(tmp, __VA_ARGS__)

int main() {
   CALL(func2, false, CALL(func2, false, false));
}
Run Code Online (Sandbox Code Playgroud)

编译,但它不再适用零参数,因为它将解决 func(tmp, ) …

c c-preprocessor variadic-macros

4
推荐指数
1
解决办法
2204
查看次数

具有递归函数的分段错误

当我尝试执行此操作时:

#include<stdio.h>

int byteland(int a)
{
   int e,f,g;
   if ((a/2 + a/3 + a/4) < a)
      return a;
   else
   {
      e = byteland(a/2);
      f = byteland(a/3);
      g = byteland(a/4);
      return e + f + g;
   }
}

int main()
{
   int a, b;
   scanf("%d", &a);
   b = byteland(a);
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

我得到分段错误(核心转储).有解决方案吗

c segmentation-fault

1
推荐指数
1
解决办法
59
查看次数