Java 数组分区最小差

Java 数组分区最小差,java,c#,algorithm,Java,C#,Algorithm,我需要根据C#/Java中的最小差异对数组数据进行分区 e、 g B3和D4之间的差值=| 3-4 |=1 A23和B25之间的差值=| 23-25 |=2 D4和C7之间的差值=| 4-7 |=3 B12和A12之间的差值=| 12-12 |=0 这些规则是: 对于每组,字母不能重复 对于每个组,它可以包含1-4个元素 元素之间的差异必须您提供的输入包含多个解决方案。大概15岁左右(A1-A2、A35-A36、D4-C7将改变解决方案)。因为我问你想要哪种解决方案时你没有回答,所以我写了

我需要根据C#/Java中的最小差异对数组数据进行分区

e、 g

  • B3和D4之间的差值=| 3-4 |=1

  • A23和B25之间的差值=| 23-25 |=2

  • D4和C7之间的差值=| 4-7 |=3

  • B12和A12之间的差值=| 12-12 |=0

这些规则是:

  • 对于每组,字母不能重复

  • 对于每个组,它可以包含1-4个元素


  • 元素之间的差异必须您提供的输入包含多个解决方案。大概15岁左右(A1-A2、A35-A36、D4-C7将改变解决方案)。因为我问你想要哪种解决方案时你没有回答,所以我写了这段代码,它将为这个问题提供一个(最简单的)“解决方案=)

    在这种情况下,Solve()的输出将是:

    { A2, B3, D4 },{ C7 },{ B12, A12, C14, D15 },{ C22, A23, B25 },{ A35, D37 },{ A36 }
    

    重要提示:此代码假定输入中的字符串是唯一的。

    用并行数组处理语言编写代码只花了10分钟,但我花了2小时写下答案。为了不打破问题中的语言限制,我将不提交任何代码,但我将尝试使用数据和一些伪代码来澄清以下原则

    如果参数具有固定顺序,则有512种可能的解决方案,如下所示:

    ┌──────────┬─┬─┬──┬──┬───┬───┬──┬──┬──┬──┬─────┐
    │Partitions│6│7│8 │9 │10 │11 │12│13│14│15│Total│
    ├──────────┼─┼─┼──┼──┼───┼───┼──┼──┼──┼──┼─────┤
    │Solutions │1│9│36│84│126│126│84│36│9 │1 │512  │
    └──────────┴─┴─┴──┴──┴───┴───┴──┴──┴──┴──┴─────┘
    
    具有最小分区(6)的解决方案是:

    下一个(有7个分区)是:

    最后一个(分成15个分区)自然是:

    ┌──┬──┬──┬──┬──┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
    │A1│A2│B3│D4│C7│B12│A12│C14│D15│C22│A23│B25│A35│A36│D37│
    └──┴──┴──┴──┴──┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
    
    解决这个问题的最好、最安全的方法是使用蛮力并遍历所有可能性。首先,您需要调整使用0和1来指示分区位置的原则。因为参数中有15个元素,所以我们使用15个长度的二进制向量来完成这项工作。例如:

    (1 0 0 1 0 0 0 0 1 0 0 1 0 0 0) partition 'stackoverflowex'
    
    暗示/应返回4个分区:

    ┌───┬─────┬───┬────┐
    │sta│ckove│rfl│owex│
    └───┴─────┴───┴────┘
    
    您还可以分割另一个15长度的布尔向量:

    (1 0 0 1 0 0 0 0 1 0 0 1 0 0 0) partition (1 1 0 0 1 1 0 1 0 0 0 1 1 0 0)
    
    应返回:

    ┌─────┬─────────┬─────┬───────┐
    │1 1 0│0 1 1 0 1│0 0 0│1 1 0 0│
    └─────┴─────────┴─────┴───────┘
    
    您可以计算每个分区中的和。上面的一个将返回:

    ┌─┬─┬─┬─┐
    │2│3│0│2│
    └─┴─┴─┴─┘
    
    要解决问题,必须生成所有可能的分区向量。做起来比说起来简单。您只需要这两者之间的所有分区向量:

    1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 // This would create 1 single, big partition
    1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 // This would create 15 small partitions
    
    这些是什么?非常简单,它们是16384和32767的2基(二进制)表示。您必须简单地循环遍历16384和32767之间的所有数字(包括这两个数字),将每个数字转换为2进制,按此对数据进行分区,然后查看当前分区是否可接受(=符合您的标准,如“对于每个组,字母不能重复”)。转换间隔中的所有数字将覆盖所有可能的分区-任何可能的零和一的组合都在其中。计算只需要一秒钟的时间

    伪:

    // The character part of the argument: 15-length vector of characters:
    Chars = "A","A","B","D","C","B","A","C","D","C","A","B","A","A","D" 
    
    // From that, extract the locations of the unique characters:
    CharsA = 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0 // Where Chars == A
    CharsB = 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0 // Where Chars == B
    CharsC = 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0 // Where Chars == C
    CharsD = 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1 // Where Chars == D
    
    // The numeric part of the argument: 15-length vector of numbers:
    // Btw, is this about lottery... hmmm
    Nums = 1, 2, 3, 4, 7, 12, 12, 14, 15, 22, 23, 25, 35, 36, 37
    
    :For Number :In [all numbers between 16384 and 32767]
    
        Base2 = [2-base of Number] // 20123 would give: 1 0 0 1 1 1 0 1 0 0 1 1 0 1 1
    
        // Test 1: "For each group, it can contains 1 - 4 elements"
            [using Base2, partition the partition vector Base2 itself;
             bail out if any partition length exceeds 4]
    
        // Test 2: "Difference between element must be <= 3"
            [using Base2, partition Nums; 
             check differences inside each partition; 
             bail out if bigger than 3 anywhere]
    
        // Test 3: "For each group, letter cannot be repeated"
            [using Base2, partition CharsA, CharsB, CharsC, CharsD (each in turn);
             count number of ones in each partition;
             bail out if exceeds 1 anywhere (meaning a character occurs more than once)]
    
        // If we still are here, this partition Number is ACCEPTABLE
        [add Number to a list, or do a parallel boolean marking 1 for Number]
    
    :End
    

    是否支持
    A
    B
    C
    D
    以外的字母?您是希望最大化每个组的大小,还是最大化组的数量?问题在于,对于大多数输入,存在多个解决方案。我的问题是:你想要哪一个?您的解决方案也缺少A1。示例中的
    A1
    发生了什么?它应该被排除在外吗?如果是,为什么?你需要澄清你想要什么。事实上,没有什么能阻止每个元素都有一个组?@FilipeBorges这对于家庭作业来说似乎太难了(除非它是算法的研究生课程)。如果输出包含
    {A35},{A36,D37}
    非常详细的答案,那就更好了!
    ┌───┬─────┬───┬────┐
    │sta│ckove│rfl│owex│
    └───┴─────┴───┴────┘
    
    (1 0 0 1 0 0 0 0 1 0 0 1 0 0 0) partition (1 1 0 0 1 1 0 1 0 0 0 1 1 0 0)
    
    ┌─────┬─────────┬─────┬───────┐
    │1 1 0│0 1 1 0 1│0 0 0│1 1 0 0│
    └─────┴─────────┴─────┴───────┘
    
    ┌─┬─┬─┬─┐
    │2│3│0│2│
    └─┴─┴─┴─┘
    
    1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 // This would create 1 single, big partition
    1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 // This would create 15 small partitions
    
    // The character part of the argument: 15-length vector of characters:
    Chars = "A","A","B","D","C","B","A","C","D","C","A","B","A","A","D" 
    
    // From that, extract the locations of the unique characters:
    CharsA = 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0 // Where Chars == A
    CharsB = 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0 // Where Chars == B
    CharsC = 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0 // Where Chars == C
    CharsD = 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1 // Where Chars == D
    
    // The numeric part of the argument: 15-length vector of numbers:
    // Btw, is this about lottery... hmmm
    Nums = 1, 2, 3, 4, 7, 12, 12, 14, 15, 22, 23, 25, 35, 36, 37
    
    :For Number :In [all numbers between 16384 and 32767]
    
        Base2 = [2-base of Number] // 20123 would give: 1 0 0 1 1 1 0 1 0 0 1 1 0 1 1
    
        // Test 1: "For each group, it can contains 1 - 4 elements"
            [using Base2, partition the partition vector Base2 itself;
             bail out if any partition length exceeds 4]
    
        // Test 2: "Difference between element must be <= 3"
            [using Base2, partition Nums; 
             check differences inside each partition; 
             bail out if bigger than 3 anywhere]
    
        // Test 3: "For each group, letter cannot be repeated"
            [using Base2, partition CharsA, CharsB, CharsC, CharsD (each in turn);
             count number of ones in each partition;
             bail out if exceeds 1 anywhere (meaning a character occurs more than once)]
    
        // If we still are here, this partition Number is ACCEPTABLE
        [add Number to a list, or do a parallel boolean marking 1 for Number]
    
    :End
    
    1 1 0 0 0 1 0 0 0 1 0 0 1 1 0