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)

    运行效果截图:

       

  • 相关阅读:
    Javascript FP-ramdajs
    微信小程序开发
    SPA for HTML5
    One Liners to Impress Your Friends
    Sass (Syntactically Awesome StyleSheets)
    iOS App Icon Template 5.0
    React Native Life Cycle and Communication
    Meteor framework
    RESTful Mongodb
    Server-sent Events
  • 原文地址:https://www.cnblogs.com/Liu928011/p/14905277.html
Copyright © 2011-2022 走看看