如何计算循环所需的元素?

How to calculate elements needed from a loop?

我有以下数据: y-n-y-y-n-n-n 这样无限重复,比如: y-n-y-y-n-n-n-y-n-y-y-n-n-n-y-n-y-y-n-n-n...

我有 5 个"x"。 "x" 只坚持 "y"。 意思是,如果我在上面的循环中分配 x,它将是: y-n-y-y-n-n-n-y-n-y-y-n-n-n x---x-x-----x-x

我想计算我需要使用多少循环元素来传播 5 倍,答案是 10。

如何用公式计算?

我想您的意思是您需要处理无限列表的前 10 个元素以获得 5 个 Y,其中 match/stick 与您拥有的 5 个 X。

y-n-y-y-n-n-n-y-n-y-y-n-n-n-y-n-y-y-n-n-n... 
x-_-x-x-_-_-_-x-_-x 
                  ^
                  L____ 10 elements read from the infinite list to place the 5 x's. 

我还假设您的问题是:给定 5 个 X 的输入,您需要在无限列表中处理多少个元素才能匹配这 5 个 X。

您可以使用如下伪代码的循环来计算它:

iElementsMatchedCounter = 0 
iXsMatchedCounter = 0 
iXLimit = 5 
strElement = "" 

if (InfiniteList.IsEmpty() == false) 
{ 
    do 
    { 
        strElement = InfiniteList.ReadNextElement()

        if (strElement == "y") 
        { 
            iXsMatchedCounter += 1 
        } 

        iElementsMatchedCounter += 1 

    } while ( (InfiniteList.IsEndReached() == false) AND (iXsMatchedCounter < iXLimit) ) 
} 

if (iXsMatchedCounter = iXLimit) 
    then Print(iElementsMatchedCounter) 
    else Print("End of list reached before all X's were matched!") 

上述方法的缺点是您实际上正在读取无限列表,这可能不是可取的。

相反,假设您知道您的列表是相同元素 y-n-y-y-n-n-n 的无限重复序列,您甚至不需要遍历整个列表,而只需对子列表 y-n-y-y-n-n-n 进行操作。以下算法描述了如何:

鉴于您的初始输入:

  • iNumberOfXs = 5(您有 5 个 X 可以匹配)
  • iNumberOfYsInSubList = 3 (你在子列表中有 3 个 Y,总列表无限重复)
  • iLengthOfSubList = 7(子列表中有 7 个元素 y-n-y-y-n-n-n)

然后我们计算出中间结果:

  • 智商
  • iPartialLengthOfList
  • iPendingXs
  • iPendingLengthOfList
  • iResult

以下步骤应该给出结果:

  1. iNumberOfXs 除以 iNumberOfYsInSubList。在这里,这给了我们 5/3 = 1.666....
  2. 丢弃结果的剩余部分(0.666...),因此您剩下 1 作为 iQuotient。这是您必须迭代的完整子列表的数量。
  3. 将商 1 乘以 iLengthOfSubList,得到 1*7=7 为 iPartialLengthOfList。这是结果的部分和,是您迭代的完整子列表中的元素数。
  4. 同样将商乘以 iNumberOfYsInSubList,并从 iNumberOfXs 中减去此乘积,即 iNumberOfXs - (iQuotient * iNumberOfYsInSubList) = 5 - (1 * 3) = 2。将此值 2 保存为 iPendingXs,这是尚未匹配的 X 的数量。
  5. 请注意,iPendingXs 将始终小于 iLengthOfSubList(即它是一个模数,iPendingXs = iNumberOfXs MODULO iNumberOfYsInSubList)。
  6. 现在您遇到了在 y-n-y-y-n-n-n 的子列表中匹配 2 个 X(即上面计算的 iPendingXs 的值)的小问题。
  7. 要匹配的待处理项目(计为 iPendingLengthOfList)是:
    • 等于 iPendingXs 如果 iPendingXs 是 0 或 1
    • 等于 iPendingXs + 1 否则(即如果 iPendingXs 大于 1)
    • 本例中,iPendingLengthOfList = 3,因为iPendingXs大于1。
  8. iPartialLengthOfList(7)和iPendingLengthOfList(3)之和就是答案,即10。

一般来说,如果您的子列表 y-n-y-y-n-n-n 不是预定义的,那么您不能在步骤 6 中对规则进行硬编码,而是必须只循环一次子列表来计算 Y 和元素,类似于上面给出的伪代码。

在实际代码中,可以使用整数除法和取模运算分别快速完成步骤2和步骤4的运算。

iQuotient = iNumberOfXs / iNumberOfYsInSubList     // COMMENT: here integer division automatically drops the remainder 
iPartialLengthOfList = iQuotient * iLengthOfSubList 

iPendingXs = iNumberOfXs  - (iQuotient  * iNumberOfYsInSubList) 
// COMMENT: can use modulo arithmetic like the following to calculate iPendingXs 
// iPendingXs = iNumberOfXs % iNumberOfYsInSubList 

// The following IF statement assumes the sub-list to be y-n-y-y-n-n-n 
if (iPendingXs > 1) 
    then iPendingLengthOfList = iPendingXs + 1 
    else iPendingLengthOfList = iPendingXs 

iResult = iPartialLengthOfList + iPendingLengthOfList