增长最快的子序列

时间:2014-12-06 15:09:14

标签: c

任务是在给定的整数数组中找到最长子序列的长度,以便子序列的所有元素按升序排序。例如,{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;
}

帮助表示赞赏。谢谢!

1 个答案:

答案 0 :(得分:1)

哦,很好的复杂。你在这里有未定义的行为,它表达自己的方式是有益的。一般问题是

            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也增加了,因此条件永远不会(除非真的,见下文)false,并且循环继续。从这一点开始,条件

a[i]>a[track[j]]

总是假的,因为你不断比较相同的两个数字,所以l每回合递增一次,这就一直在发生。

此问题一直持续到track已满两(因为i仍为2)。实际上,它在 track已满后继续,写入内存中track后面发生的任何事情。这是什么没有在C语言标准中定义;对我来说,这恰好是a,然后是Nmax_val等等,按照声明的顺序(发现用调试器,我鼓励你研究一下这个工具)。因人而异。因此,对我而言,a也已填充,然后N2覆盖,max_val等也会被2覆盖,然后{{ 1}}被l覆盖,然后循环才结束。然后你回到

2

...现在for(i=0;i<N;++i) N2正在增加到i。然后循环结束,然后程序结束。

也许不用说,这不是你可以依赖的行为。编译器不必按此顺序排列堆栈变量,优化编译器甚至可以生成不会将某些变量保存在内存中(或根本不存在)的代码。但这就是发生的事情。