⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sequence.jam

📁 boost库提供标准的C++ API 配合dev c++使用,功能更加强大
💻 JAM
字号:
#  (C) Copyright David Abrahams 2002. Permission to copy, use, modify, sell and
#  distribute this software is granted provided this copyright notice appears in
#  all copies. This software is provided "as is" without express or implied
#  warranty, and with no claim as to its suitability for any purpose.

import assert ;
import numbers ; 
import modules ;

# Note that algorithms in this module execute largely in the caller's
# module namespace, so that local rules can be used as function
# objects. Also note that most predicates can be multi-element
# lists. In that case, all but the first element are prepended to the
# first argument which is passed to the rule named by the first
# element.

# Return the elements e of $(sequence) for which [ $(predicate) e ]
# has a non-null value.
rule filter ( predicate + : sequence * )
{
    local caller = [ CALLER_MODULE ] ;
    local result ;

    for local e in $(sequence)
    {
        if [ modules.call-in $(caller) : $(predicate) $(e) ]
        {
            result += $(e) ;
        }
    }
    return $(result) ;
}

# return a new sequence consisting of [ $(function) $(e) ] for each
# element e of $(sequence).
rule transform ( function + : sequence * )
{
    local caller = [ CALLER_MODULE ] ;
    local result ;

    for local e in $(sequence)
    {
        result += [ modules.call-in $(caller) : $(function) $(e) ] ;
    }
    return $(result) ;
}


rule less ( a b )
{
    if $(a) < $(b)
    {
        return true ;
    }
}

# insertion-sort s using the BinaryPredicate ordered.
rule insertion-sort ( s * : ordered * )
{
    if ! $(ordered)
    {
        return [ SORT $(s) ] ;
    }
    else 
    {           
        local caller = [ CALLER_MODULE ] ;
        ordered ?= sequence.less ;
        local result = $(s[1]) ;
        if $(ordered) = sequence.less
        {
            local head tail ;
            for local x in $(s[2-])
            {
                head = ;
                tail = $(result) ;
                while $(tail) && ( $(tail[1]) < $(x) )
                {
                    head += $(tail[1]) ;
                    tail = $(tail[2-]) ;
                }
                result = $(head) $(x) $(tail) ;
            }
        }
        else
        {
            for local x in $(s[2-])
            {
                local head tail ;
                tail = $(result) ;
                while $(tail) && [ modules.call-in $(caller) : $(ordered) $(tail[1]) $(x) ]
                {
                    head += $(tail[1]) ;
                    tail = $(tail[2-]) ;
                }
                result = $(head) $(x) $(tail) ;
            }
        }
        
        return $(result) ;
    }    
}

# merge two ordered sequences using the BinaryPredicate ordered.
rule merge ( s1 * : s2 * : ordered * )
{
    ordered ?= sequence.less ;
    local result__ ;
    local caller = [ CALLER_MODULE ] ;

    while $(s1) && $(s2) {
        if [ modules.call-in $(caller) : $(ordered) $(s1[1]) $(s2[1]) ]
        {
            result__ += $(s1[1]) ;
            s1 = $(s1[2-]) ;
        }
        else if [ modules.call-in $(caller) : $(ordered) $(s2[1]) $(s1[1]) ]
        {
            result__ += $(s2[1]) ;
            s2 = $(s2[2-]) ;
        }
        else 
        {           
            s2 = $(s2[2-]) ;
        }
        
    }
    result__ += $(s1) ;
    result__ += $(s2) ;

    return $(result__) ;
}

# join the elements of s into one long string. If joint is supplied,
# it is used as a separator.
rule join ( s * : joint ? )
{
    joint ?= "" ;
    return $(s:J=$(joint)) ;
}

# Find the length of any sequence in log(N) time.
rule length ( s * )
{
    local length = "" ;
    local zeros p10 d z ; # declared once for speed

    # Find the power of 10 that is just less than length(s)
    zeros = "" ;
    p10 = 1 ;
    while $(s[$(p10)0])
    {
        p10 = $(p10)0 ;
        zeros = $(zeros[1])0 $(zeros) ;
    }

    # zeros is a list of the form  ... 000 00 0 ""
    for z in $(zeros) # for each digit in the result
    {
        # Find the next digit
        d = 0 1 2 3 4 5 6 7 8 9 ;
        while $(s[$(d[2])$(z)])
        {
            d = $(d[2-]) ;
        }

        # append it to the result
        length = $(length)$(d[1]) ;

        # Explanation: $(d[1])$(z) the largest number x of the form
        # n000..., where n is a digit, such that x <= length(s). Here
        # we're deleting x elements from the list. Since $(s[n]-)
        # removes n - 1 elements from the list, we chop an additional
        # one off the end.
        s = $(s[$(d[1])$(z)--2]) ;
    }
    return $(length) ;
}

rule unique ( list * )
{
    local result ;
    for local f in $(list)
    {
        if ! $(f) in $(result)
        {
            result += $(f) ;
        }
    }
    return $(result) ;
}

# Returns the maximum number in 'elements'. Uses 'ordered' for comparisons,
# or 'numbers.less' is none is provided.
rule max-element ( elements + : ordered ? )
{
    ordered ?= numbers.less ;

    local max = $(elements[1]) ;
    for local e in $(elements[2-]) 
    {
        if [ $(ordered) $(max) $(e) ] 
        {
            max = $(e) ;
        }
    }
    return $(max) ;           
}

# Returns all of 'elements' for which corresponding element in parallel
# list 'rank' is equal to the maximum value in 'rank'.
rule select-highest-ranked ( elements * : ranks * )
{
    if $(elements)
    {        
        local max-rank = [ max-element $(ranks) ] ;
        local result ;
        while $(elements) 
        {
            if $(ranks[1]) = $(max-rank)
            {
                result += $(elements[1]) ;
            }
            elements = $(elements[2-]) ;
            ranks = $(ranks[2-]) ;
        }
        return $(result) ;
    }    
}
NATIVE_RULE sequence : select-highest-ranked ;


local rule __test__ ( )
{
    # use a unique module so we can test the use of local rules.
    module sequence.__test__
    {
        import assert ;
        import sequence ;
        
        local rule is-even ( n )
        {
            if $(n) in 0 2 4 6 8
            {
                return true ;
            }
        }

        assert.result 4 6 4 2 8
          : sequence.filter is-even : 1 4 6 3 4 7 2 3 8 ;

        # test that argument binding works
        local rule is-equal-test ( x y )
        {
            if $(x) = $(y)
            {
                return true ;
            }
        }

        assert.result 3 3 3 : sequence.filter is-equal-test 3 : 1 2 3 4 3 5 3 5 7 ;

        local rule append-x ( n )
        {
            return $(n)x ;
        }

        assert.result 1x 2x 3x : sequence.transform append-x : 1 2 3 ;

        local rule repeat2 ( x )
        {
            return $(x) $(x) ;
        }

        assert.result 1 1 2 2 3 3 : sequence.transform repeat2 : 1 2 3 ;

        local rule test-greater ( a b )
        {
            if $(a) > $(b)
            {
                return true ;
            }
        }
        assert.result 1 2 3 4 5 6 7 8 9 : sequence.insertion-sort 9 6 5 3 8 7 1 2 4 ;
        assert.result 9 8 7 6 5 4 3 2 1 : sequence.insertion-sort 9 6 5 3 8 7 1 2 4 : test-greater ;
        assert.result 1 2 3 4 5 6 :  sequence.merge 1 3 5 : 2 4 6 ;
        assert.result 6 5 4 3 2 1 :  sequence.merge 5 3 1 : 6 4 2 : test-greater ;
        assert.result 1 2 3 : sequence.merge 1 2 3 : ;
        assert.result 1 : sequence.merge 1 : 1 ;

        assert.result foo-bar-baz : sequence.join foo bar baz : - ;
        assert.result substandard : sequence.join sub stan dard ;
        assert.result 3.0.1 : sequence.join 3.0.1 : - ;

        assert.result 0 : sequence.length ;
        assert.result 3 : sequence.length a b c ;
        assert.result 17 : sequence.length 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 ;

        assert.result 1 : sequence.length a ;
        assert.result 10 : sequence.length a b c d e f g h i j ;
        assert.result 11 : sequence.length a b c d e f g h i j k ;
        assert.result 12 : sequence.length a b c d e f g h i j k l ;

        local p2 = x ;
        for local i in 1 2 3 4 5 6 7 8
        {
          p2 = $(p2) $(p2) ;
        }
        assert.result 256 : sequence.length $(p2) ;

        assert.result 1 2 3 4 5
          : sequence.unique 1 2 3 2 4 3 3 5 5 5 ;
                
        assert.result 5 
          : sequence.max-element 1 3 5 0 4 ;
        
        assert.result e-3 h-3 
          : sequence.select-highest-ranked e-1 e-3 h-3 m-2 : 1 3 3 2 ;
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -