程序员的算法趣题Q47: 格雷码循环

2023-10-11 10:59

本文主要是介绍程序员的算法趣题Q47: 格雷码循环,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

1. 问题描述

2. 解题分析

3. 代码及测试

4. 后记


1. 问题描述

2. 解题分析

        这道题目的焦点是任意M进制数的格雷码的生成。这个确实是有难度的问题,因为它已经不是常规的算法设计问题。要求对格雷码的生成算法有了解,尤其是针对任意M进制的格雷码的生成并不是一般的二进制格雷码的生成算法的简单推广。

        以本问题为契机我特意调查了一下二进制格雷码以及任意M进制格雷码的生成算法。详情参见从二进制格雷码到任意进制格雷码(1) (2)

        我自己基于格雷码的定义给出的基于深度优先搜索的任意M进制格雷码的生成算法由于(是预先一次性生成N位M进制的所有格雷码码字)需要巨量的存储,因此并不适用于作为本题的解决方案。对于M=16,N=6的情况,总共有M**N=16**6=2**24~~10**9,这个存储量有点惊人。

        原书中给出一个提示,基于二进制格雷码生成的异或转换算法的扩展得出任意M进制格雷码生成算法。。。真的有醍醐灌顶之感!

        另外,在https://en.wikipedia.org/wiki/Gray_code中给出了一种基于迭代的方式生成M进制格雷码的算法。本文先基于这种算法给出题解。关于任意M进制格雷码生成的“异或转换”算法后面再来补充。

        M进制格雷码的详细迭代生成算法这里不再解释(事实是我没有看懂这个算法是怎么设计出来的,因此无法解释,感兴趣的伙伴自己就着代码慢慢品味吧)。

        整体的算法流程如下:


3. 代码及测试

# -*- coding: utf-8 -*-
"""
Created on Thu Oct  7 10:31:11 2021@author: chenxy
"""import sys
import time
import datetime
import math
import random
from   typing import List
# from   queue import Queue
from   collections import deque
import itertools as it
import numpy as npdef baseM_toGray(M: int, N: int, value: int) -> List:''' Parameters----------M : int. Base        N : int. Number of digitsvalue : int. Natural decimal value of the input dataReturns-------ListThe base-M gray code representation. [0]: The most siginificant digit[-1]: The least siginificant digit'''# Generate the normal base-M representation of valuebaseM = N * [0]for i in range(N-1,-1,-1):baseM[i] = value % Mvalue    = value //M# Convert the normal baseM number into the Gray code equivalent. # Note that, the loop starts at the most significant digit and goes down.gray  = N * [0]shift = 0i     = 0while i <= N-1:# The Gray digit gets shifted down by the sum of the higher digits.gray[i] = (baseM[i] + shift) % Mshift   = shift + M - gray[i];	# Subtract from base so shift is positive      i       = i + 1return gray      def cyclicSteps(M: int, N: int, start: int)->int:cur = startstep  = 0while 1:step = step + 1curGray = baseM_toGray(M,N,cur)# print(curGray)# Take curGray as normal baseM representation and calulate its valuecur   = 0scale = 1        for k in range(N-1,-1,-1):            cur = cur + curGray[k] * scalescale = scale * Mif cur == start:breakreturn stepif __name__ == '__main__':           M = 16N = 6start = 0x808080step  = cyclicSteps(M,N,start)print('start = 0x{0:6x}, step = {1}'.format(start,step))start = 0xABCDEFstep  = cyclicSteps(M,N,start)print('start = 0x{0:6x}, step = {1}'.format(start,step))

        运行结果: 

        start = 0x808080, step = 8
        start = 0xabcdef, step = 64

4. 后记

        关于格雷码生成的更多参见:

        从二进制格雷码到任意进制格雷码(1) 

        从二进制格雷码到任意进制格雷码(2)

        上一篇:Q46: 唯一的OX序列

        下一篇:Q48: 翻转得到交错排列

        本系列总目录参见:程序员的算法趣题:详细分析和Python全解

这篇关于程序员的算法趣题Q47: 格雷码循环的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/187570

相关文章

深入理解Mysql OnlineDDL的算法

《深入理解MysqlOnlineDDL的算法》本文主要介绍了讲解MysqlOnlineDDL的算法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小... 目录一、Online DDL 是什么?二、Online DDL 的三种主要算法2.1COPY(复制法)

MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决

《MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决》MyBatis默认开启一级缓存,同一事务中循环调用查询方法时会重复使用缓存数据,导致获取的序列主键值均为1,... 目录问题原因解决办法如果是存储过程总结问题myBATis有如下代码获取序列作为主键IdMappe

Spring 依赖注入与循环依赖总结

《Spring依赖注入与循环依赖总结》这篇文章给大家介绍Spring依赖注入与循环依赖总结篇,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. Spring 三级缓存解决循环依赖1. 创建UserService原始对象2. 将原始对象包装成工

Java中的雪花算法Snowflake解析与实践技巧

《Java中的雪花算法Snowflake解析与实践技巧》本文解析了雪花算法的原理、Java实现及生产实践,涵盖ID结构、位运算技巧、时钟回拨处理、WorkerId分配等关键点,并探讨了百度UidGen... 目录一、雪花算法核心原理1.1 算法起源1.2 ID结构详解1.3 核心特性二、Java实现解析2.

Java中的for循环高级用法

《Java中的for循环高级用法》本文系统解析Java中传统、增强型for循环、StreamAPI及并行流的实现原理与性能差异,并通过大量代码示例展示实际开发中的最佳实践,感兴趣的朋友一起看看吧... 目录前言一、基础篇:传统for循环1.1 标准语法结构1.2 典型应用场景二、进阶篇:增强型for循环2.

Python循环结构全面解析

《Python循环结构全面解析》循环中的代码会执行特定的次数,或者是执行到特定条件成立时结束循环,或者是针对某一集合中的所有项目都执行一次,这篇文章给大家介绍Python循环结构解析,感兴趣的朋友跟随... 目录for-in循环while循环循环控制语句break语句continue语句else子句嵌套的循

MySQL存储过程之循环遍历查询的结果集详解

《MySQL存储过程之循环遍历查询的结果集详解》:本文主要介绍MySQL存储过程之循环遍历查询的结果集,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言1. 表结构2. 存储过程3. 关于存储过程的SQL补充总结前言近来碰到这样一个问题:在生产上导入的数据发现

使用雪花算法产生id导致前端精度缺失问题解决方案

《使用雪花算法产生id导致前端精度缺失问题解决方案》雪花算法由Twitter提出,设计目的是生成唯一的、递增的ID,下面:本文主要介绍使用雪花算法产生id导致前端精度缺失问题的解决方案,文中通过代... 目录一、问题根源二、解决方案1. 全局配置Jackson序列化规则2. 实体类必须使用Long封装类3.

Nginx部署React项目时重定向循环问题的解决方案

《Nginx部署React项目时重定向循环问题的解决方案》Nginx在处理React项目请求时出现重定向循环,通常是由于`try_files`配置错误或`root`路径配置不当导致的,本文给大家详细介... 目录问题原因1. try_files 配置错误2. root 路径错误解决方法1. 检查 try_f

Springboot实现推荐系统的协同过滤算法

《Springboot实现推荐系统的协同过滤算法》协同过滤算法是一种在推荐系统中广泛使用的算法,用于预测用户对物品(如商品、电影、音乐等)的偏好,从而实现个性化推荐,下面给大家介绍Springboot... 目录前言基本原理 算法分类 计算方法应用场景 代码实现 前言协同过滤算法(Collaborativ