我正在研究以下代码,目的是在扩展的Euclid算法中找出x和y的解决方案:
long gcd(long a, long b, long &x, long &y) {
long d; // place to hold final gcd
// in case b = 0, we have d=|a|, x=1 or -1, y arbitrary (say, 0)
if (b==0) {
if (a<0) {
d = -a;
x = -1;
y = 0;
} else {
d = a;
x = 1;
y = 0;
}
return d;
}
// if b is negative, here is a workaround
if (b<0) {
d = gcd(a,-b,x,y);
y = -y;
return d;
}
// if a is negative, here is a workaround
if (a<0) {
d = gcd(-a,b,x,y);
x = -x;
return d;
}
// set up recursion
long aa = b;
long bb = a%b;
long qq = a/b;
long xx,yy;
d = gcd(aa,bb,xx,yy);
x = yy +1;
y = xx - qq*yy;
return d;
}
我真正不明白的是'返回'是如何工作的。 给定两个输入数字(a,b),我试图遵循所有查看调试会话的行为(使用Apple Xcode)。
一旦b == 0,它就在这里:
if (b==0) {
if (a<0) {
d = -a;
x = -1;
y = 0;
} else {
d = a;
x = 1;
y = 0;
}
return d;
}
从这个'return d'跳转到代码末尾的最后一个'return d'。 在那里,它开始循环最后一块代码:
d = gcd(aa,bb,xx,yy);
x = yy +1;
y = xx - qq*yy;
return d;
}
直到找到所有解决方案。
我的问题是:
1)为什么从第一个'返回d'开始直接跳到最后'返回''? 2)怎么可能从那里到最后四行直到结束而不是调用函数
d = gcd(aa,bb,xx,yy);
之前做过什么?
这里我也发布了主要内容:
int main() {
long a,b,x,y;
cout << "Insert first ---> ";
cin >> a;
cout << "Insert second ---> ";
cin >> b;
cout << "The gcd of " << a << " and " << b << " is "
<< gcd(a,b,x,y)<<endl;
cout << "x is " << x << " and y is " << y << endl;
return 0;
}
非常感谢
答案 0 :(得分:0)
主要是顺序调用吗?这是我能够理解它会做到这一点的唯一原因。例如:
<EditText
android:layout_width="30dp"
android:layout_height="match_parent"
android:ems="10"
android:id="@+id/editText_code"
android:layout_marginLeft="20dp"
android:background="@android:color/transparent"
android:hint="+91"
android:textSize="14sp"
android:phoneNumber="true" />
<EditText
android:layout_width="match_parent"
android:layout_height="40dp"
android:hint="MOBILE NO"
android:singleLine="false"
android:layout_below="@+id/linearLayoutFirstName"
android:layout_toRightOf="@+id/linearLayoutFirstName"
android:layout_toEndOf="@+id/linearLayoutFirstName"
android:background="@android:color/transparent"
android:layout_gravity="center"
android:textSize="12sp"
android:layout_marginLeft="05dp"
android:id="@+id/mobileNo"
android:phoneNumber="true" />
</LinearLayout>
理论上,这会导致第一个if语句为真,并且如此评估,但是第二次调用gcd将绕过所有if语句并直接进入底部。
编辑:我想我真的不明白这个问题,不应该试图回答。但是,我所知道的是,从提供的代码中,gcd在调用时可以采用四种可能的路径:
long g1 = gcd(3, 0, x, y);
long g2 = gcd(3, 2, x, y);
如果b==0
为负数,则返回a
的绝对值并设置x = -1
。如果不是,则设为a
。b<0
这将返回对gcd的调用结果,其绝对值为b
,并取消通过引用传递的y
变量。a<0
与路径2相同,但a
和x
代替b
和y
。这可能不能很好地回答你的问题,但这就是我总是打破这些类型的问题以便进行分析和故障排除,所以我希望它有一些用处,至少可以引导你一步一步如果您尚未使用它,请使用故障排除方法。
答案 1 :(得分:0)
当你从return d;
步进时,你应该在函数的末尾结束,这是它的右括号。
如果你开始将结束括号放在他们自己的一行上,你将能够区分“最后一个语句”和“函数结束”之间的区别。
递归函数的工作方式与非递归函数完全相同 - 每次调用都会在调用之后立即返回;在您的情况下,对gcd(aa,bb,xx,yy);
的每次调用都将返回到行x = yy +1;
,这就是您认为这些行被循环的原因。
(如果你打开调试器的callstack窗口,你会看到它随着函数的调用而增长,并在你从它们返回时收缩,而你的“循环”就是在几个单独的>中返回到同一个点函数调用。)