简体   繁体   中英

function to find the longest increasing subsequence without arrays

I need to make a program in C with those instructions: the problem is its kinda easy to do with arrays but without them,I cant think anything else.

we need to write a function that takes int n and then takes the sequences of numbers, the function need to return us the sum of the biggest sequence. for 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) here we will get the print 50.`

for n = 2 and the sequence 7,19 the function will print 26. for n = 8 and the sequence 8,6,4,2 ,11,14,15,16 the longest length is 4 so the function will print 20.

can't find any solution here without 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;
          }
        }
    }

I had coded this up, but needed clarification from OP (see my top comments).

As a result...

I added code to pick a sequence of equal length to the best but with a larger sum.

Because it was minimal changes to my code, I chose that the longest sequence wins:

  1. For input of -2 -1 1 2 , this is a sequence of 4 with sum 0. It is not two sequences of 2 -2 -1 and 1 2 with sum 3.
  2. For input of 1 1 1 1 1 , this is a sequence of 5 with sum 5 and not 5 sequences of 1 [each] with sum 1

Here is the code. It is annotated:

#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;
}

Input:

4
-2 -1 1 2

Output: 0


Input:

5
1 1 1 1 1

Output: 5


Input:

2
7 19

Output: 26


Input:

8
2 4 6 8 11 14 17 9

Output: 62


Input:

8
8 6 4 2 11 14 15 16

Output: 58


Input:

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

Output: 18


Input:

2
2 1

Output: 2


Here is the perl script that I used to generate the tests:

Edit: Updated for example below.

#!/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

UPDATE:

Here is a version that adds some debug printing (-DDEBUG). And, selection of <= vs < (-DLE).

I've updated the runseq script above to handle this version [it is backwards compatible].

#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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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