【问题标题】:MySQL simple stored procedure calling another simple one and never endingMySQL 简单存储过程调用另一个简单存储过程并且永无止境
【发布时间】:2021-07-19 13:49:56
【问题描述】:

尝试计算 m 个元素的 n x k 组合(即无序)的总和。

要计算 k 组合,我需要创建一个计算阶乘的函数。

代码很简单,而且有效:

BEGIN
DECLARE factorial INT DEFAULT 1;
DECLARE counter INT;
SET counter = m;  --  m is my variable
factorial_loop: REPEAT
SET factorial = factorial * counter;
SET counter = counter - 1;
UNTIL counter = 1
END REPEAT;
RETURN factorial;
END

然后我想创建一个简单的函数,添加 k 组合直到给定阈值。

示例:我想知道 4 个元素中的 7 个元素存在多少个 k 组合。

这是:

  • 7 个元素中 7 个元素的组合 = 1 个无序组合
  • 7 个元素中 6 个元素的组合 = 7 个无序组合
  • 7 个元素中 5 个元素的组合 = 21 个无序组合
  • 7 个元素中 4 个元素的组合 = 35 个无序组合

总计 = 64

为此,我创建了第二个存储过程,调用第一个。

BEGIN
DECLARE tempo INT DEFAULT 0;
DECLARE counter2 INT;
SET counter2 = X;  --  X is the number of elements, in the example 7
combisum_loop: REPEAT
SET tempo = tempo + factorial(x)/(factorial(counter2)*factorial(x-counter2));  --  the mathematical formula for k-combinations
SET counter2 = counter2 - 1 ;
UNTIL counter2 = Y  --  Y is the thresold, in the example 4
END REPEAT;
RETURN tempo;
END

问题:即使用这些小数字调用第二个函数也永远不会结束。我做错了什么?

PS:一些想法:

  • 如果我用数字 1 替换数学函数,它会返回 4(正确的结果)
  • 如果我通过对阶乘函数的唯一调用来替换数学公式,它就可以工作! (即完成,但这当然不是我想要达到的结果)
  • 如果我用整个公式创建了一个 k 组合函数但没有循环它也可以工作!!!
  • 如果我在循环中调用 k 组合函数,它会失败

所以问题似乎是当我同时有一个循环和几个(间接)调用 - 确实很简单 - 阶乘函数时。

注意:尝试修改第二个存储过程以避免@nbk 建议的阶乘(0),但这仍然失败:

BEGIN
DECLARE tempo INT DEFAULT 1;
DECLARE counter2 INT;
SET counter2 = X-1;
voila3_loop: REPEAT
SET tempo = tempo + factorial(x)/(factorial(counter2)*factorial(x-counter2));
SET counter2 = counter2 - 1 ;
UNTIL counter2 = Y
END REPEAT;
RETURN tempo;
END

第一次迭代应该是 tempo = 1 + factorial(7)/(factorial(6)*factorial(7-6));并且绝对应该工作

【问题讨论】:

    标签: mysql combinations


    【解决方案1】:

    除了代码中的小问题。

    您的第二个函数的第一轮以除以 NULL 开始

    因为factorial(0) =0

    我不熟悉你使用的公式

    所以函数根本不运行。

    所以公式似乎不正确。

    CREATE Function factorial(m INT)
    RETURNS BIGINT unsigned DETERMINISTIC
    BEGIN
    DECLARE factorial BIGINT UNSIGNED DEFAULT 1;
    DECLARE counter INT;
    SET counter = m;  --  m is my variable
    factorial_loop: REPEAT
    SET factorial = factorial * counter;
    SET counter = counter - 1;
    UNTIL counter <= 1
    END REPEAT;
    RETURN factorial;
    END
    
    SELECT factorial(4)/(factorial(4) * factorial(0))
    
    |阶乘(4)/(阶乘(4) * 阶乘(0)) | | -----------------------------------------: | | |
    SELECT factorial(4)/(factorial(3) * factorial(1))
    
    |阶乘(4)/(阶乘(3) * 阶乘(1)) | | -----------------------------------------: | | 4.0000 |
    SELECT factorial(4)/(factorial(2) * factorial(2))
    
    |阶乘(4)/(阶乘(2) * 阶乘(2)) | | -----------------------------------------: | | 6.0000 |
    SELECT factorial(4)/(factorial(1) * factorial(3))
    
    |阶乘(4)/(阶乘(1) * 阶乘(3)) | | -----------------------------------------: | | 4.0000 |
    CREATE Function factor(x INT)
    RETURNS BIGINT unsigned DETERMINISTIC
    BEGIN
    DECLARE tempo BIGINT UNSIGNED  DEFAULT 0;
    DECLARE counter2 INT;
    SET counter2 = x;  --  X is the number of elements, in the example 7
    combisum_loop: REPEAT
    SET @a := counter2;
    SET tempo = tempo + factorial(x)/(factorial(counter2)*factorial(x-counter2));  --  the mathematical formula for k-combinations
    
    SET counter2 = counter2 - 1 ;
    UNTIL counter2 <= Y  --  Y is the thresold, in the example 4
    END REPEAT;
    RETURN tempo;
    END
    
    SELECT factor(4)
    
    SELECT @a
    
    | @a | | -: | | 4 |

    db小提琴here

    【讨论】:

    • 哇,你说的太对了!!!我确保倒数(从 7 到 0),我忘记了阶乘(x-counter2)......谢谢很多
    • 请不要忘记accept the answer
    • mmmhhh 修改了查询,因此它从 X-1 而不是 X 开始,所以没有阶乘 (0) - 因为它在之后开始并在之前停止 - 而且它仍然失败......
    • 没有代码运行dbfiddle.uk/…
    • 好吧,除了数据类型,我在代码中没有发现任何差异,但是当我复制/粘贴你的代码时,它就可以了,就这样吧! ;-)
    猜你喜欢
    • 2011-05-05
    • 2012-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-31
    • 2014-09-17
    相关资源
    最近更新 更多