Average of two strings in alphabetical/lexicographical order

前端 未结 8 2009
南方客
南方客 2021-02-15 17:38

Suppose you take the strings \'a\' and \'z\' and list all the strings that come between them in alphabetical order: [\'a\',\'b\',\'c\' ... \'x\',\'y\',\'z\']. Take the midpoint

8条回答
  •  没有蜡笔的小新
    2021-02-15 18:33

    Thanks for everyone who answered, but I ended up writing my own solution because the others weren't exactly what I needed. I am trying to average app engine key names, and after studying them a bit more I discovered they actually allow any 7-bit ASCII characters in the names. Additionally I couldn't really rely on the solutions that converted the key names first to floating point, because I suspected floating point accuracy just isn't enough.

    To take an average, first you add two numbers together and then divide by two. These are both such simple operations that I decided to just make functions to add and divide base 128 numbers represented as lists. This solution hasn't been used in my system yet so I might still find some bugs in it. Also it could probably be a lot shorter, but this is just something I needed to get done instead of trying to make it perfect.

    # Given two lists representing a number with one digit left to decimal point and the
    # rest after it, for example 1.555 = [1,5,5,5] and 0.235 = [0,2,3,5], returns a similar
    # list representing those two numbers added together.
    #
    def ladd(a, b, base=128):
            i = max(len(a), len(b))
            lsum = [0] * i  
            while i > 1:
                    i -= 1
                    av = bv = 0
                    if i < len(a): av = a[i]
                    if i < len(b): bv = b[i]
                    lsum[i] += av + bv
                    if lsum[i] >= base:
                            lsum[i] -= base
                            lsum[i-1] += 1
            return lsum
    
    # Given a list of digits after the decimal point, returns a new list of digits
    # representing that number divided by two.
    #
    def ldiv2(vals, base=128):
            vs = vals[:]
            vs.append(0)
            i = len(vs)
            while i > 0:
                    i -= 1
                    if (vs[i] % 2) == 1:
                            vs[i] -= 1
                            vs[i+1] += base / 2
                    vs[i] = vs[i] / 2
            if vs[-1] == 0: vs = vs[0:-1]
            return vs
    
    # Given two app engine key names, returns the key name that comes between them.
    #
    def average(a_kn, b_kn):
            m = lambda x:ord(x)
            a = [0] + map(m, a_kn)
            b = [0] + map(m, b_kn)
            avg = ldiv2(ladd(a, b))
            return "".join(map(lambda x:chr(x), avg[1:]))
    
    print average('a', 'z') # m@
    print average('aa', 'zz') # n-@
    print average('aa', 'az') # am@
    print average('cat', 'doggie') # d(mstr@
    print average('google', 'microsoft') # jlim.,7s:
    print average('microsoft', 'google') # jlim.,7s:
    

提交回复
热议问题