任务是在给定的整数数组中找到最长子序列的长度,以使该子序列的所有元素都按升序排序。例如,{15、27、14、38、26、55、46、65、85}的LIS的长度为6,而增加的最长子序列为{15、27、38、55、65、85}。
以下是我编写的代码。我不确定我的逻辑是否正确,但是代码无法正常运行。如果我尝试输入以下测试用例
9 15 27 14
程序停止读取14之后的值,并给我输出2。它应该读取9个值,但是代码仅读取3个值。我已经多次检查了我的代码,但不幸的是,我无法发现该错误。
#include<stdio.h>
int main()
{
int N,max_val,i,j,k,l=1;
int a[100000], track[100000];
track[0]=0;
max_val=1;
scanf("%d",&N);
for(i=0;i<N;++i)
{
printf("x");
scanf(" %d",&a[i]);
if(i!=0)
{
for(j=0;j<l;++j)
{
if(a[i]>a[track[j]])
{
max_val++;
track[0]=i;
l=1;
break;
}
else
{
track[l]=i;
l++;
}
}
}
}
printf("%d",max_val);
return 0;
}
感谢您的帮助。谢谢!
哦,真是令人费解。您在这里有未定义的行为,它表达自己的方式很有启发性。普遍的问题是
if(a[i]>a[track[j]]) // <-- when i == 2, this first is false with
{ // your input
max_val++;
track[0]=i;
l=1;
break;
}
else
{
track[l]=i; // <-- and you end up here, where you write
l++; // into track[l] and increase l.
}
后l
增加,你回到环
for(j=0;j<l;++j)
这里j
增加了,但是由于l
也增加了,所以条件永远不会(除非不是真的,请参阅下文)为假,并且循环继续进行。从这一点开始,
a[i]>a[track[j]]
总是错误的,因为您一直在比较相同的两个数字,所以l
每转都会递增,并且这种情况一直在发生。
继续进行直到track
满为二(因为i
仍然为2
)。实际上,它在充满后 继续运行track
,写入track
内存中任何可能发生的情况。在C语言标准中没有定义什么。对我来说,这恰好是按声明的顺序先是a
,然后是N
,max_val
依此类推(用调试器发现了这一点,我鼓励您研究一下该工具)。YMMV。因此,对我来说,a
也被填充,然后N
被覆盖2
,max_val
等等,也被覆盖2
,然后l
被覆盖2
,然后循环才结束。然后你回到
for(i=0;i<N;++i)
...现在和现在N
都在递增到的位置。然后循环结束,然后程序结束。2
i
3
也许不用说,这不是您可以依靠的行为。编译器不必按此顺序排列堆栈变量,而优化的编译器甚至可以生成不将某些变量保存在内存中(或根本不保存)的代码。但这就是发生的情况。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句