相关疑难解决方法(0)

在bash中有"goto"声明吗?

在bash中有"goto"声明吗?我知道这被认为是不好的做法,但我需要特别"goto".

linux bash shell goto

186
推荐指数
9
解决办法
34万
查看次数

为什么 Python 递归如此昂贵,我们能做些什么?

假设我们要计算一些斐波那契数,以 997 为模。

因为n=500在 C++ 中我们可以运行

#include <iostream>
#include <array>

std::array<int, 2> fib(unsigned n) {
    if (!n)
        return {1, 1};
    auto x = fib(n - 1);
    return {(x[0] + x[1]) % 997, (x[0] + 2 * x[1]) % 997};
}

int main() {
    std::cout << fib(500)[0];
}
Run Code Online (Sandbox Code Playgroud)

在 Python 中

def fib(n):
    if n==1:
        return (1, 2)
    x=fib(n-1)
    return ((x[0]+x[1]) % 997, (x[0]+2*x[1]) % 997)

if __name__=='__main__':
    print(fib(500)[0])
Run Code Online (Sandbox Code Playgroud)

两者都可以毫无问题地找到答案 996。我们采用模数来保持合理的输出大小,并使用对来避免指数分支。

对于n=5000,C++ 代码输出 783,但 Python 会抱怨

RecursionError: …
Run Code Online (Sandbox Code Playgroud)

c++ python stack-overflow recursion

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

为什么Haskell中的因子计算要比Java中快得多

我遇到的一个编程问题涉及计算大数(最多10 ^ 5的数字)的阶乘.我见过一个简单的Haskell代码,就像这样

factorial :: (Eq x, Num x) => x -> x
factorial 0 = 1
factorial a = a * factorial (a - 1)
Run Code Online (Sandbox Code Playgroud)

即使没有代码中涉及的任何缓存,它也会隐式处理大量数字并以某种方式运行得更快.

当我尝试使用Java解决问题时,我不得不使用BigInteger来保存大数字并使用因子的迭代版本

public static BigInteger factorialIterative(int n)
{
        if(n == 0 || n == 1) return BigInteger.valueOf(1);
        BigInteger f = BigInteger.valueOf(1);
        for(int i = 1 ; i <= n ;i++)
            f = f.multiply(BigInteger.valueOf(i));
        return f;
}
Run Code Online (Sandbox Code Playgroud)

上述代码超出了程序执行的设定时间限制.我也尝试了factorial的缓存递归版本

public static BigInteger factorial(int n)
{
     if(cache[n] != null) 
         return cache[n];
     else if(n == 0) 
         return new …
Run Code Online (Sandbox Code Playgroud)

java haskell factorial

21
推荐指数
3
解决办法
4433
查看次数

在Java 8中实现无堆栈递归

如何在Java中实现无堆栈递归?

似乎出现最多的词是"蹦床",我不知道这意味着什么.

有人在IN DETAIL中解释如何在Java中实现无堆栈递归吗?还有什么是"蹦床"?

如果你不能提供其中任何一个,你能指出我正确的方向(即一本书来阅读它或一些教导所有这些概念的教程)?

java stack-overflow recursion tail-call-optimization

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

C API函数回调到C++成员函数代码中

所以,我正在使用FMOD api,它确实是一个C api.

不是那个坏或什么的.它只是它与C++代码没有良好的接口.

例如,使用

FMOD_Channel_SetCallback( channel, callbackFunc ) ;
Run Code Online (Sandbox Code Playgroud)

它想要一个C风格的函数callbackFunc,但我想传递一个类的成员函数.

我最终使用Win32技巧,使成员函数静态.然后它作为FMOD的回调.

现在我必须破解我的代码以使一些成员静态,只是为了解释FMOD的C-ness.

我想知道它是否可能在FMOD中或者是否有解决方法将回调链接到特定C++对象的实例成员函数(不是静态函数).它会更顺畅.

c c++ fmod static-functions

10
推荐指数
2
解决办法
6114
查看次数

展开框架,但不要在C中返回

我的编程语言编译为C,我想实现尾递归优化.这里的问题是如何将控制传递给另一个函数而不从当前函数"返回".

如果控件传递给同一个函数,这很容易:

void f() {
    __begin:
    do something here...
    goto __begin; // "call" itself
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,没有返回值和参数,这些参数在一个由全局变量处理的单独堆栈中传递.

另一种选择是使用内联汇编:

#ifdef __clang__
    #define tail_call(func_name) asm("jmp " func_name " + 8");
#else
    #define tail_call(func_name) asm("jmp " func_name " + 4");
#endif

void f() {
    __begin:
    do something here...
    tail_call(f); // "call" itself
}
Run Code Online (Sandbox Code Playgroud)

这类似于goto但是当goto将控制传递给函数中的第一个语句时,跳过编译器生成的"入口代码" jmp是不同的,它的参数是一个函数指针,你需要添加4或8个字节来跳过进入代码.

上述两者都可以工作,但前提是被调用者和调用者对由被调用者的入口代码分配的局部变量使用相同数量的堆栈.

我想leave用内联汇编手动,然后替换堆栈上的返回地址,然后执行legal函数调用f().但我的所有尝试都崩溃了.你需要修改BPSP以某种方式.

那么再次,如何为x64实现这一点?(再次,假设函数没有参数并返回void).没有内联装配的便携式方式更好,但是接受装配.也许longjump可以用?

也许你甚至可以在堆栈上推送被叫地址,替换原来的返回地址而已ret

c compiler-construction tail-recursion

8
推荐指数
2
解决办法
120
查看次数

如何跳出Lisp中的函数?

在(Common)Lisp中是否可以跳转到另一个函数而不是调用另一个函数?我的意思是,当前函数被打破而另一个被调用,没有跳过数千个函数,就好像我决定自己是否完成尾调用优化,即使它不是尾部.我不确定"(从fn x返回)"是否,我想要什么.

例:

(defun fn (x)
  (when x
    (princ x)
    (jump 'fn (cdr x)))
  (rest))
Run Code Online (Sandbox Code Playgroud)

'jump'应该像调用下面的函数而不保存这个函数的位置,而是返回原来的funcall所在的位置,这样就不会有堆栈溢出.只有x为零才能执行'rest'.

lisp return common-lisp trampolines tail-call-optimization

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

C中结构中的类型

在本文中:http://publib.boulder.ibm.com/infocenter/macxhelp/v6v81/index.jsp?topic=/com.ibm.vacpp6m.doc/language/ref/clrc03defst.htm

句子是什么意思"在C中,结构成员可以是任何类型,除了"函数返回T"(对于某些类型T)

感谢所有的答案!

c struct

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

迭代函数可以调用自身吗?

在观看下面的 MIT 6.001 课程视频时,教师在 28:00 将此算法标记为迭代。但是,在 30.27,他说这个算法和实际的“递归”算法都是递归的。该函数使用基本情况调用自身,那么这个迭代如何?

https://www.youtube.com/watch?v=dlbMuv-jix8&list=PLE18841CABEA24090&index=2

private int iterativeSum(int x, int y)
{
    System.out.println("x "+x+" y "+y);
    if(x == 0)
    {
        return y;
    }
    return iterativeSum(--x, ++y);
}
Run Code Online (Sandbox Code Playgroud)

java iteration recursion scheme sicp

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

多次调用方法

int noOfAttempts = 3;
void StartServer();
bool IsServerRunning();
Run Code Online (Sandbox Code Playgroud)

我需要StartServer()根据结果重新尝试3次IsServerRunnig().像这样的东西:

StartServer();
if (!IsServerRunning())
{
    StartServer();
    if (!IsServerRunning())
    {
        StartServer();
        if (!IsServerRunning())
        {
            StartServer();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我不想使用for循环或像上面那样丑陋的代码.有没有更好的方法呢?一种方式,如果noOfAttempts将来改变,我将不必更改我的代码?

编辑: 我期待"委托"概念(如果可能的话).

.net c#

-3
推荐指数
3
解决办法
7496
查看次数