繁体   English   中英

function 求不带arrays的最长递增子序列

[英]function to find the longest increasing subsequence without arrays

我需要按照这些说明在 C 中制作一个程序:问题是使用 arrays 很容易,但没有它们,我想不出别的。

我们需要编写一个 function 接受 int n 然后接受数字序列,function 需要返回最大序列的和。 对于n = 8 and the sequence = 2,4,6,8,11,14,17,9' (there is 2 long sequences of 4, (when 8 starts the new sequence and closes the current sequence)这里我们将得到打印 50.`

对于 n = 2 和序列 7,19,function 将打印 26。对于 n = 8 和序列8,6,4,2 ,11,14,15,16,最长长度为 4,因此 function 将打印 20。

没有 arrays 在这里找不到任何解决方案

 printf("please choose a n");
    scanf("%d", &n);
    y = n;
    if (n == 1)
  {
        printf("Please enter the next number ");
        scanf("%d", &series);
        return series;
    }
  else
    if (n == 2)
  {
        while (i < 2) {
    {
        printf("Please enter the next number ");
            scanf("%d", &series);
            sum += series;
        }
        return sum;
    }
   printf("Plase choose another number");
scanf("%d", &last);
sum += last;
printf("please choose another number");
scanf("%d", &series);
d = series - last;
sum = series + last;
bSum = sum;
for (i = 2; i < n; i++)
    {
    last = series;
    printf("Please write another number; ");
    scanf("%d", &series);
     if (series - last == d)
      {
          sum += series;
          count++;
      }
      if (series - last != d)
      {
          if (count > length)
          {
              bSum = sum;
              length = count;
          }
          else if (count == length && sum > bSum)
          {
              bSum = sum;
          }
        }
    }

我已经对此进行了编码,但需要 OP 的澄清(请参阅我的最高评论)。

因此...

我添加了代码来选择一个长度相等但总和更大的序列。

因为对我的代码的改动很小,所以我选择了最长的序列:

  1. 对于-2 -1 1 2的输入,这是一个和为 0 的 4 序列。它不是2 -2 -11 2和 3 的两个序列。
  2. 对于1 1 1 1 1的输入,这是一个总和为 5 的 5 序列,而不是总和为 1 的 1 [每个] 的 5 个序列

这是代码。 是这样注释的:

#include <stdio.h>

int
main(void)
{

    // get count of sequence numbers
    int n;
    scanf("%d",&n);

    // length of current sequence
    int curlen = 0;

    // sum of current sequence
    int cursum = 0;

    // value of current number
    int curval;

    // value of previous number
    int oldval;

    // get the first number
    scanf("%d",&oldval);

    // add it to the current sequence
    curlen += 1;
    cursum += oldval;

    // initialize the best sequence from the current one
    int bestsum = cursum;
    int bestlen = curlen;

    // get all remaining numbers in the sequence
    for (int i = 1;  i < n;  ++i, oldval = curval) {
        // get new current number
        if (scanf("%d",&curval) != 1) {
            fprintf(stderr,"too short\n");
            break;
        }

        // reset the current sequence if we're not increasing
        if (curval < oldval) {
            cursum = 0;
            curlen = 0;
        }

        // add to the current sequence
        cursum += curval;
        curlen += 1;

        // save off the longest sequence we've seen
        if (curlen > bestlen) {
            bestlen = curlen;
            bestsum = cursum;
            continue;
        }

        // save off a sequence that is the same length as the best but has a
        // larger sum
        if ((curlen == bestlen) && (cursum > bestsum)) {
            bestsum = cursum;
            continue;
        }
    }

    // print the final/best sum
    printf("%d\n",bestsum);

    return 0;
}

输入:

4
-2 -1 1 2

Output: 0


输入:

5
1 1 1 1 1

Output:5


输入:

2
7 19

Output: 26


输入:

8
2 4 6 8 11 14 17 9

Output: 62


输入:

8
8 6 4 2 11 14 15 16

Output: 58


输入:

12
1 2 3 4
2 3 4 5
3 4 5 6

Output: 18


输入:

2
2 1

Output:2


这是我用来生成测试的perl脚本:

编辑:更新如下示例。

#!/usr/bin/perl
# runseq -- run sequence program
#
# options:
#   "-D" -- cc -D options
#   "-S<sfile>" -- source file (DEFAULT: seq.c)
#   "-clip" -- send output to xclip program
#   "-d" -- debug runseq script
#
# arguments:
#   1-- [optional] comma separated list of sequence numbers (e.g. 3,7 2,1)

master(@ARGV);
exit(0);

# master -- master control
sub master
{
    my(@argv) = @_;

    optdcd(\@argv,
        "+opt_D","opt_S","opt_clip");

    # get source file
    $sroot = $opt_S;
    $sroot //= "seq";
    $sroot =~ s/[.].+$//;

    zprtx("compiling %s ...\n",$sroot);
    $sfile = "$sroot.c";
    sysfault("runseq: no source file\n")
        unless (-e $sfile);

    push(@cc,"cc");
    push(@cc,"-o$sroot");
    foreach $opt (@opt_D) {
        push(@cc,"-D$opt");
    }
    push(@cc,$sfile);

    $cmd = join(" ",@cc);
    zprtx("%s\n",$cmd);

    $code = vxsystem(@cc);
    exit(1) if ($code);

    $tmpfile = "inp.txt";

    # send to xclip program
    if ($opt_clip) {
        open($xfout,"|xclip");
    }
    else {
        $xfout = \*STDOUT;
    }

    {
        # take tests from command line
        if (@argv > 0) {
            foreach $arg (@argv) {
                $arg =~ s/,/ /g;
                @body = ($arg);
                dosum();
            }
            last;
        }

        # get test data from below
        $xfdata = \*seq::DATA;
        while ($dat = <$xfdata>) {
            chomp($dat);

            # ignore comments
            next if ($dat =~ /^\s*#/);

            # blank line separates tests
            if ($dat =~ /^\s*$/) {
                dosum();
                next;
            }

            push(@body,$dat);
        }
    }

    # do final test
    dosum()
        if (@body > 0);

    close($xfout)
        if ($opt_clip);
}

# optdcd -- decode command line options
sub optdcd
{
    my(@syms) = @_;
    my($argv);
    my($arg);
    my($ary);
    my($symlhs,$symrhs,$val,$match);

    $argv = shift(@syms);

    # get options
    while (@$argv > 0) {
        $arg = $argv->[0];
        last unless ($arg =~ /^-/);

        shift(@$argv);

        $match = 0;
        foreach $symrhs (@syms) {
            $symlhs = $symrhs;
            $ary = ($symlhs =~ s/^[+]//);

            $opt = $symlhs;
            $opt =~ s/^opt_/-/;

            zprt("optdcd: TRYARG arg='%s' symrhs='%s' symlhs='%s' opt='%s' ary=%d\n",
                $arg,$symrhs,$symlhs,$opt,$ary);

            if ($arg =~ /^$opt(.*)$/) {
                $val = $1;

                $val =~ s/^=//;
                $val = 1
                    if ($val eq "");

                if ($ary) {
                    zprt("optdcd: PUSH val=%s\n",$val);
                    push(@$symlhs,$val);
                }
                else {
                    zprt("optdcd: SET val=%s\n",$val);
                    $$symlhs = $val;
                }

                $match = 1;
                last;
            }
        }

        sysfault("optdcd: unknown option -- '%s'\n",$arg)
            unless ($match);
    }
}

sub dosum
{
    my($bf);
    my(@rhs);
    my(@n);

    zprtx("\n")
        if ($opt_clip);

    $xfdst = xfopen(">$tmpfile","dosum");

    # get count of sequence values (i.e. "n")
    foreach $bf (@body) {
        @rhs = split(" ",$bf);
        push(@n,@rhs);
    }
    printf($xfdst "%d\n",scalar(@n));

    foreach $bf (@body) {
        zprtx("dosum: %s\n",$bf)
            if ($opt_clip);
        print($xfdst $bf,"\n");
    }
    $xfdst = xfclose($xfdst);

    # run program
    my($outval) = (`./$sroot < $tmpfile`);
    chomp($outval);

    # output test input data and program output
    outf("\n");
    outf("----------\n")
        if ($opt_clip);
    outf("Input:\n");
    outf("```\n")
        if ($opt_clip);
    $xfsrc = xfopen("<$tmpfile","dosum");
    while ($buf = <$xfsrc>) {
        outf("%s",$buf);
    }
    $xfsrc = xfclose($xfsrc);
    outf("```\n")
        if ($opt_clip);

    outf("\n")
        if ($opt_clip);
    outf("Output: %d\n",$outval);

    undef(@body);
}

sub outf
{

    printf($xfout @_);
}

sub zprt
{

    goto &zprtx
        if ($opt_d);
}

sub zprtx
{

    printf(STDERR @_);
}

sub sysfault
{

    zprtx(@_);
    exit(1);
}

sub xfopen
{
    my($file,$who) = @_;
    my($xf);

    open($xf,$file) or
        sysfault("xfopen: unable to open '%s' -- $!\n",$file);

    $xf;
}

sub xfclose
{
    my($xf) = @_;

    close($xf);

    undef($xf);

    $xf;
}

sub vxsystem
{
    my($cmd);

    $cmd = join(" ",@_);

    system($cmd);

    $? >> 8;
}

package seq;
__DATA__
-2 -1 1 2

1 1 1 1 1

7 19

2 4 6 8 11 14 17 9

8 6 4 2 11 14 15 16

1 2 3 4
2 3 4 5
3 4 5 6

2 1

更新:

这是一个添加了一些调试打印 (-DDEBUG) 的版本。 并且,选择<= vs < (-DLE)。

我已经更新了上面的runseq脚本来处理这个版本[它是向后兼容的]。

#include <stdio.h>

#if DEBUG
#define dbgprt(_fmt...) \
    fprintf(stderr,_fmt)
#else
#define dbgprt(_fmt...) \
    do { } while (0)
#endif

int
main(void)
{

    // get count of sequence numbers
    int n;

    scanf("%d", &n);

    // length of current sequence
    int curlen = 0;

    // sum of current sequence
    int cursum = 0;

    // value of current number
    int curval;

    // value of previous number
    int oldval = 0;

    // get the first number
    scanf("%d", &curval);

    // add it to the current sequence
    curlen += 1;
    cursum += curval;

    dbgprt("OLD: oldval=%d curval=%d cursum=%d curlen=%d\n",
        oldval,curval,cursum,curlen);

    oldval = curval;

    // initialize the best sequence from the current one
    int bestsum = cursum;
    int bestlen = curlen;

    // get all remaining numbers in the sequence
    for (int i = 1; i < n; ++i, oldval = curval) {
        // get new current number
        if (scanf("%d", &curval) != 1) {
            fprintf(stderr, "too short\n");
            break;
        }

        // reset the current sequence if we're not increasing
#if LE
        if (curval <= oldval) {
            cursum = 0;
            curlen = 0;
            dbgprt("ZAPLE\n");
        }
#else
        if (curval < oldval) {
            cursum = 0;
            curlen = 0;
            dbgprt("ZAPLT\n");
        }
#endif

        // add to the current sequence
        cursum += curval;
        curlen += 1;

        dbgprt("CUR: oldval=%d curval=%d cursum=%d curlen=%d\n",
            oldval,curval,cursum,curlen);

        // save off the longest sequence we've seen
        if (curlen > bestlen) {
            dbgprt("NEWLEN\n");
            bestlen = curlen;
            bestsum = cursum;
            continue;
        }

        // save off a sequence that is the same length as the best but has a
        // larger sum
        if ((curlen == bestlen) && (cursum > bestsum)) {
            dbgprt("NEWSUM\n");
            bestsum = cursum;
            continue;
        }
    }

    // print the final/best sum
    printf("%d\n", bestsum);

    return 0;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM