在bash中有"goto"声明吗?我知道这被认为是不好的做法,但我需要特别"goto".
假设我们要计算一些斐波那契数,以 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) 我遇到的一个编程问题涉及计算大数(最多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中实现无堆栈递归?
似乎出现最多的词是"蹦床",我不知道这意味着什么.
有人在IN DETAIL中解释如何在Java中实现无堆栈递归吗?还有什么是"蹦床"?
如果你不能提供其中任何一个,你能指出我正确的方向(即一本书来阅读它或一些教导所有这些概念的教程)?
所以,我正在使用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,我想实现尾递归优化.这里的问题是如何将控制传递给另一个函数而不从当前函数"返回".
如果控件传递给同一个函数,这很容易:
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()
.但我的所有尝试都崩溃了.你需要修改BP
并SP
以某种方式.
那么再次,如何为x64实现这一点?(再次,假设函数没有参数并返回void
).没有内联装配的便携式方式更好,但是接受装配.也许longjump
可以用?
也许你甚至可以在堆栈上推送被叫地址,替换原来的返回地址而已ret
?
在(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'.
在本文中:http://publib.boulder.ibm.com/infocenter/macxhelp/v6v81/index.jsp?topic=/com.ibm.vacpp6m.doc/language/ref/clrc03defst.htm
句子是什么意思"在C中,结构成员可以是任何类型,除了"函数返回T"(对于某些类型T)
感谢所有的答案!
在观看下面的 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) 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
将来改变,我将不必更改我的代码?
编辑: 我期待"委托"概念(如果可能的话).