zoukankan      html  css  js  c++  java
  • 经典算法题之约瑟夫环与全排列

    约瑟夫环

    问题描述:

    约瑟夫环问题的基本描述如下:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为1的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,要求找到最后一个出列的人或者模拟这个过程。

    解题思路:构建循环列表

    def Josephuson(n, m):
        List = list(range(1, n + 1))  #生成n序列
        index = 0
        while List:
            temp = List.pop(0)  #弹出列表的第一个值
            index += 1
            if index == m:
                print('{}-->'.format(temp), end='') #打印路径
                index = 0  #索引重新归零
                continue   #索引符合m的倍数,结束本次循环,该值不在参与循环列表的构建
            else:
                List.append(temp)  #不满足索引条件把弹出来的数值重新添加到列表尾部构建循环列表
            if len(List) == 1:  # 当列表只有1个值时结束循环
                print(List[0])
                break
    
    if __name__ == '__main__':
        n = int(input('总人数:'))
        m = int(input('报数:'))
        Josephuson(n, m)

    运行截图:

    全排列

    问题描述:输入一个字符串,按字典序打印出该字符串中字符的所有排列。

    示例: 1 2 3的全排列如下:

    1 2 3 , 1 3 2 , 2 1 3 , 2 3 1 , 3 1 2 , 3 2 1

    从上面的全排列也可以看出来了,从左往右依次增大,对这就是字典序法。可是如何用算法来实现字典序法全排列呢?

    2.1字典序算法

    例:字典序法找124653的下一个排列

    如果当前排列是124653,找它的下一个排列的方法是:

    从这个序列中从右至左找第一个左邻小于右邻的数,如果找不到,则所有排列求解完成,如果找得到则说明排列未完成。

    本例中将找到46,计4所在的位置为i,找到后不能直接将46位置互换,而又要从右到左到第一个比4大的数,本例找到的数是5,其位置计为j,将i与j所在元素交换125643,然后将i+1至最后一个元素从小到大排序(也可以说是反转,从643到346)得到125346,这就是124653的下一个排列。

    def DictSort(value):
        global number
        s_end = len(value) - 1  #尾指针
        p = s_end               #右邻指针
        q = p - 1               #左邻指针
        while p != 0:
            if value[q] >= value[p]:  #字符串左邻大于或等于右邻
                q = q - 1  # 指针往左移动
                p = p - 1  # 指针往左动动
            else:
                i = q  # 找到左邻小于右邻,记录索引
                j = s_end  # 右邻指针重新指向末尾
                while value[i] >= value[j]:  # 从右往左找,找到记录值value[i]小于右邻的值
                    j = j - 1
                value[i], value[j] = value[j], value[i]  # 找到了,交换列表中二者的值
                value[i + 1:] = value[-1:i:-1]  # 剩下的值进行反转
                number = number + 1  # 执行次数加1
                return 1
        return 0
    
    if __name__ == '__main__':
        str = input('请输入排序的字符串:')
        number = 1    #记录执行的次数
        value = list(str)  
        value.sort()
        print("第{}种排序:{}".format(number, ''.join(value)))  # 第一次最小排序
        flag = DictSort(value)  
        while flag:
            print("第{}种排序:{}".format(number,''.join(value)) )
            flag = DictSort(value)
        print('该字符串一共有{}种排序!'.format(number))

    运行效果截图:

             

     2.2全排列递归实现

    全排列的递归实现解析:

    为方便起见,用123来示例下。123的全排列有123、132、213、231、312、321这六种。

    1、首先考虑213和321这二个数是如何得出的。显然这二个都是123中的1与后面两数交换得到的。

    2、然后可以将123的第二个数和每三个数交换得到132。同理可以根据213和321来得231和312。

    3、因此可以知道——全排列就是从第一个数字起每个数分别与它后面的数字交换。

    # 递归回溯实现字符串全排列
    def AllSort(value, s, length):
        global number
        if s == length:  # 递归出口
            number = number + 1
            print("第%d中排序:" % number, ''.join(value))
    
        else:
            for i in range(s, length):
                value[s], value[i] = value[i], value[s]
                AllSort(value, s + 1, length)
                value[s], value[i] = value[i], value[s] #注意,因为递归有回溯的过程,所以需要把数字重新调换回来变为初始的排列。
    
    if __name__ == '__main__':
        str = input('请输入排序的字符串:')
        number = 0
        value = list(str)  # 字符串转列表处理
        length = len(value)
        value.sort()
        AllSort(value, 0, length)

     运行效果截图

        

     以上递归算法算然实现了全排列,但并非字典序,而且当字符串出现相同字符时,会出现相同的排列,所以如何优化呢?

    优化方案:交换前先进行判断是否重复

    def is_same(value, s, i):  # 判断排列的重复性
        while s < i:
            if value[s] == value[i]:
                return 0
            s += 1
        return 1
    
    def AllSort(value, s, length):
        global number
        if s == length:  #递归出口
            number = number + 1
            print("第%d中排序:" % number, ''.join(value))
        else:
            for i in range(s, length):
                if is_same(value, s, i):  #去重全排列
                    value[s], value[i] = value[i], value[s]
                    AllSort(value, s + 1, length)
                    value[s], value[i] = value[i], value[s]
    
    if __name__ == '__main__':
        str = input('请输入排序的字符串:')
        number = 0
        value = list(str)
        length = len(value)
        value.sort()
        AllSort(value, 0, length)

    运行效果截图:

       

  • 相关阅读:
    Spark学习笔记——安装和WordCount
    Scala学习笔记——入门
    Scala学习笔记——安装
    Maven常用命令(转)
    maven中snapshot快照库和release发布库的区别和作用 (转)
    Hadoop学习笔记——WordCount
    Hadoop学习笔记——安装Hadoop
    机器学习——利用SVD简化数据
    Python自然语言处理学习——jieba分词
    机器学习——大数据与MapReduce
  • 原文地址:https://www.cnblogs.com/Liu928011/p/14905277.html
Copyright © 2011-2022 走看看