Pythonプログラマのインタビューブック---問題解決のアルゴリズムの概要:文字の特定の順序で文字の配列をソートする方法第5章文字列5.11

# -*- coding: utf-8 -*-

'''
Python程序员面试算法宝典---解题总结: 第5章 字符串 5.11 如何按照给定的字母序列对字符数组排序

题目:
已知字母序列[d, g, e, c, f, b, o, a],请实现一个方法,要求对输入的一组字符串
input=["bed", "dog", "dear", "eye"]按照字母顺序排序并打印。
本例的输出顺序为: dear, dog, eye, bed。

分析:
问题的关键就是实现一个比较方法,
因为之前对字符串排序是按照字典顺序比较的。
举例:
比较"bed"和"dog"
分别比较第一个字符,如果哪个字符串第一个字符排在给定
字符序列的前面,则设置哪个字符串在较前的位置。
关键就是遍历字符序列,有没有一种快速的方式,看谁的
序列小。
最简单的方式,
建立:
[d, g, e, c, f, b, o, a]
对应的字典,每个字符设置一个数值
<d, 0>
<g, 1>
....

关键:
1 书上解法
对没有出现在字符序列中其他元素怎么排序,默认设置为-1

2 插入排序
找出L[i]在L[1...i-1]中的插入位置k
然后将L[k...i-1]的所有元素后移
将L[i]复制到L[k]
    for i in range(1, size):
        value = stringList[i]
        # 寻找插入位置,即L[i] < L[i-1]
        low = 0
        high = i - 1
        while low <= high:
            mid = (low + high) / 2
            string = stringList[mid]
            # 说明中间的元素大于当前元素,当前元素应该在mid之前
            result = compareString(value, string, charDict)
            if result < 0:
                high = mid - 1
            else:
                low = mid + 1
        # 从后向前移动元素
        for j in range(i - 1, high, -1):
            stringList[j + 1] = stringList[j]
        stringList[high + 1] = value

3 之所以没想到
是因为不知道如果没有出现在字符序列中的字符,
默认值为-1
另外需要使用插入排序(
每次查找到待插入位置,该位置后面所有元素后移)
来排序

参考:
Python程序员面试算法宝典
'''

def buildDict(charList):
    result = {}
    if not charList:
        return result
    for i, char in enumerate(charList):
        result[char] = i
    # 对没有出现在字符序列中其他元素怎么排序,默认设置为-1
    return result


# 这里比较单个字符
def compareChar(char1, char2, charDict):
    if not char1 or not char2 or not charDict:
        return -1
    if char1 == char2:
        return 0
    value1 = charDict.get(char1) if char1 in charDict else -1
    value2 = charDict.get(char2) if char1 in charDict else -1
    if value1 < value2:
        return -1
    elif value1 > value2:
        return 1
    else:
        return 0


def compareString(str1, str2, charDict):
    if not str1 and not str2:
        return 0
    elif not str1:
        return -1
    elif not str2:
        return 1
    len1 = len(str1)
    len2 = len(str2)
    i = 0
    j = 0
    while i < len1 and j < len2:
        char1 = str1[i]
        char2 = str2[j]
        result = compareChar(char1, char2, charDict)
        if result != 0:
            return result
        else:
            i += 1
            j += 1
    # str1还有字符,那么str1就是较大的字符串,返回1
    if i < len1:
        return 1
    else:
        return -1

'''
对字符串数组进行排序,这里用插入排序
插入排序:
每次将一个元素插入到前面已经排好序的结果
'''
def insertSort(stringList, charDict):
    if not stringList or not charDict:
        return stringList
    size = len(stringList)
    # 注意最后一个元素需要比较,从除第0个元素以外的第1个元素到第n-1个元素
    for i in range(1, size):
        value = stringList[i]
        # 寻找插入位置,即L[i] < L[i-1]
        low = 0
        high = i - 1
        while low <= high:
            mid = (low + high) / 2
            string = stringList[mid]
            # 说明中间的元素大于当前元素,当前元素应该在mid之前
            result = compareString(value, string, charDict)
            if result < 0:
                high = mid - 1
            else:
                low = mid + 1
        # 从后向前移动元素
        for j in range(i - 1, high, -1):
            stringList[j + 1] = stringList[j]
        stringList[high + 1] = value
    return stringList


def process():
    charList = ['d', 'g', 'e', 'c', 'f', 'b', 'o', 'a']
    charDict = buildDict(charList)
    strList = ['bed', 'dog', 'dear', 'eye']
    results = insertSort(strList, charDict)
    print results


if __name__ == "__main__":
    process()

 

おすすめ

転載: blog.csdn.net/qingyuanluofeng/article/details/94493481