【问题标题】:function that returns the next number of a repeating sequence返回重复序列的下一个数字的函数
【发布时间】:2019-11-04 07:00:48
【问题描述】:

首先,这是一个学校作业,所以我不能使用<math.h> 图书馆作为障碍。 所以正如标题所暗示的,我尝试编写一个函数,它获取一个正数序列作为其输入,然后返回该序列将继续的数字。例如,如果序列是3 1 1 1 1 3 3 3 1 1 1 3 3 3 1 1 1 1,那么它将返回3,因为这就是下一个数字。数字序列总是以-1 结尾,但是-1 不是序列的一部分,它只是标志着它的结束。

函数如下:

#include <stdio.h>
int predict(int seq[]) {
    int i, j;
    for (i = 0; seq[i] != -1; i++)
        ;
    int seqLength = i;
    int rep[i+1];
    for (j = 0; j < i + 1; j++)
        rep[j] = -1;
    i = 0;
    j = 1;
    while (seq[i] != -1) {
        if (rep[0] == seq[i]) {
            for (j = 1; seq[i + j] != -1; j++) {
                if (rep[j] == seq[i + j]) {
                    j++;
                } else {
                    rep[i] = seq[i];
                    j = 1;
                    break;
                }
            }
            i++;
        } else {
            rep[i] = seq[i];
            i++;
        }
    }
    for (i = 0; rep[i] != -1; i++)
        ;
    int repLength = i;
    return seq[seqLength % repLength];
}

int main() {
    int seq[20] = {1, 2, 1, 1, 2, 1, 2, 3, 1, 2, 1, 1, 2, 1, 2, -1}; /*or any other positive numbers as long as it ends with -1*/
    printf("%d\n",predict(seq));
    return 0;
}

seq(序列的缩写)是函数作为输入的数字序列。 seqLengthseq 有多少个数字。 rep(repeat 的缩写)是序列中重复自身的部分。 repLengthrep 有多少个数字。

该函数适用于我所知道的所有三个测试用例,例如:

对于3 1 1 1 1 3 3 3 1 1 1 3 3 3 1 1 1 1,它返回3
对于1 2 3 1 2 3 4 1 2 3 1 2 3 4 1 2 3,它返回1
对于1 2 1 1 2 1 2 3 1 2 1 1 2 1 2,它返回3

但是,当我将它上传到测试和评估我的功能的学校系统时,它会测试另外两个测试用例,这是错误的。问题是,我不知道另外两个测试用例的输入序列,因此我不知道要更改什么才能使我的函数适用于所有测试用例。有人能在我的工作中看到错误并知道要更改哪些内容,以使我的函数适用于任何重复的数字序列,甚至是未知的数字序列吗?

【问题讨论】:

  • 可能和this recent question一样?
  • 做更多的测试。没有阅读您的代码的建议:predict(1 1 -1)predict(1 2 3 4 -1)predict(-1) /* for sneaky teacher! */
  • 关于:for(i=0;seq[i]!=-1;i++); a -1 未在您的问题中提及。 -1 代表什么?
  • 请发帖minimal reproducible example,以便我们复制问题并帮助您调试。
  • OT:为了便于阅读和理解,请统一格式化代码。在每个左大括号“{”后缩进。在每个右大括号 '}' 之前取消缩进。建议每个缩进级别为 4 个空格。

标签: c


【解决方案1】:

存在您的算法不起作用的极端情况:如果重复序列的长度为seqLength,您将不会在rep 数组中找到-1,因为它的定义长度为seqLength并且列表标记的结尾从未被复制到那里。因此,最后一个循环将运行超过 rep 的末尾并导致未定义的行为。

恐怕还有其他问题,我们试着简化一下代码:

  • 将索引值与seqLength 进行比较而不是测试-1 会更安全,顺便说一下,您没有将其记录为列表结束标记。

  • 此外,将序列复制到 rep 数组中似乎是多余的,因为该数组将始终包含 seq 的初始部分。

  • 问题似乎归结为寻找重复模式的长度。

这是一个简化版本,seqLength 作为参数传递:

int predict(int seq[], int seqLength) {
    /* find the mininum value of repLength such that the sequence is
       a repeated pattern of length repLength */
    int i, repLength;
    for (repLength = 1; repLength < seqLength; replength++) {
        for (i = 0; i < seqLength; i++) {
            if (seq[i] != seq[i % repLength])
                break;
        }
        if (i == seqLength) {
            /* we found the pattern length */
            break;
        }
    }
    return seq[seqLength % repLength];
}

【讨论】:

  • 感谢您的反馈。修复了如果重复序列的长度为 seqLength 时导致未定义行为的部分,方法是在块的大小上加上 +1,块的大小也被 -1 填充。我没有将 seqLength 作为输入,我无法修改代码来这样做。我必须仅根据我作为唯一输入获得的块来计算它。
  • 通过稍微重写它来尝试你的版本(在函数内部计算 seqLength 而不是将其作为输入),现在它就像一个魅力。非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-18
  • 1970-01-01
  • 2021-04-22
  • 2019-09-06
  • 2019-02-18
相关资源
最近更新 更多