[英]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 的澄清(请参阅我的最高评论)。
因此...
我添加了代码来选择一个长度相等但总和更大的序列。
因为对我的代码的改动很小,所以我选择了最长的序列:
-2 -1 1 2
的输入,这是一个和为 0 的 4 序列。它不是2 -2 -1
和1 2
和 3 的两个序列。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.