描述

一个IP地址是由四个字节(每个字节8个位)的二进制码组成。请将32位二进制码表示的IP地址转换为十进制格式表示的IP地址输出。如果输入的数字不足32位或超过32位或输入的数字中有非0和1的数字时输出“data error!”

输入格式


在一行中给出表示IP地址的二进制字符串。

输出格式


在一行中输出十进制格式的IP地址,其由4个十进制数组成(分别对应4个8位的二进制数),中间用“.”分隔开。

输入输出示例


输入 输出
示例 1 ```

11001100100101000001010101110010

  1. |

204.148.21.114

  1. |
  2. <br /> 这个问题的求解分为3步:
  3. 一是判定是否是合法的IP地址的二进制表示,其标志为(1)字符串长度为32;(2)字符串由只‘0’和‘1’构成,不包含其他字符。
  4. 二是将这个32位的字符串切分为4段,每段为8个字符,可以使用切片方法获得(s[x:x+8])。在此基础上将切分好的每一个字符串转为其对应的十进制数字,可以利用int()函数 base参数实现(int(x,base = 2)。
  5. 三是将转换好的结果再用 “.” 连接起来构成IP地址的十进制表示形式
  6. ```python
  7. ip = input()
  8. list=[]
  9. if len(ip) == 32: # 判断长度合法时继续向下执行
  10. for c in ip: # 遍历输入的字符
  11. if c not in ['0', '1']: # 如果发现存在字符在['0','1']中不存在时
  12. print('data error!') # 输出'data error!',同时结束循环并跳过else子句的执行
  13. break
  14. else: # for循环顺利结束时执行此语句块
  15. for i in range(4):
  16. list+=[str(int(ip[i*8:(i+1)*8],2))] # 新得到的十进制数以字符串形式拼接到列表上
  17. print('.'.join(list)) # 用点连接列表中的元素
  18. else:
  19. print('data error!') # 长度不是32时输出'data error!'


判定输入字符串中是否包含非’0’,’1’可以利用集合的去重复数据的特性,先转为集合去掉重复元素一,再判定其是不是{‘0’,’1’}的子集:

  1. ip = input()
  2. s = '' # 创建一个空字符串
  3. if len(ip) == 32 and set(ip) <= {'0','1'}: # 当字符串长度为32,且转为集合后是{'0','1'}的子集时
  4. for i in range(4):
  5. if i == 0:
  6. s = s + str(int(ip[i*8:(i+1)*8],2)) # 转换后的值转为字符串拼接到字符串s 上
  7. else:
  8. s = s + '.' + str(int(ip[i*8:(i+1)*8],2)) # 转换后的值转为字符串拼接到字符串s + '.' 上
  9. print(s) #240.15.202.179 # 输出列表中元素,用点分隔
  10. else:
  11. print('data error!')

可以用strip(‘01’)去掉ip首尾的所有字符’0’和字符’1’,如果处理后的字符串长度不为0 ,则说明包含其他字符,不符合ip条件。

  1. len(ip.strip('01')) # 返回去掉首尾所有'0'和'1'之后r的字符串的长度
  1. ip = input()
  2. s = '' # 创建一个空字符串
  3. # ip.strip('01') 的作用是去掉字符串ip首尾的所有'0'和'1',如果结果长度为0,则不包含非‘0’非‘1’字符
  4. if len(ip) == 32 and len(ip.strip('01'))==0: # 当字符串长度为32,且转为集合后是{'0','1'}的子集时
  5. for i in range(4):
  6. if i == 0:
  7. s = s + str(int(ip[i*8:(i+1)*8],2)) # 转换后的值转为字符串拼接到字符串s 上
  8. else:
  9. s = s + '.' + str(int(ip[i*8:(i+1)*8],2)) # 转换后的值转为字符串拼接到字符串s + '.' 上
  10. print(s) #240.15.202.179 # 输出列表中元素,用点分隔
  11. else:
  12. print('data error!')

也可以用str.format()直接格式化输出:

  1. ip = input() # 11110000000011111100101010110011
  2. if len(ip) == 32 and set(ip) <= {'0','1'}: # 当字符串长度为32,且转为集合后是{'0','1'}的子集时
  3. print('{}.{}.{}.{}'.format(int(ip[0:8],2),int(ip[8:16],2),int(ip[16:24],2),int(ip[24:32],2))) #240.15.202.179 # 输出列表中元素,用点分隔
  4. else:
  5. print('data error!')

可以用列表存储每次转换的数值,输出时再用sep = ‘.’ 分隔:

  1. ip = input() # 11110000000011111100101010110011
  2. ls = [] # 创建一个空列表
  3. if len(ip) == 32 and set(ip) <= {'0','1'}: # 当字符串长度为32,且转为集合后是{'0','1'}的子集时
  4. for i in range(4):
  5. ls.append(int(ip[i*8:(i+1)*8],2)) # 转换后的值加入列表末尾
  6. print(*ls,sep = '.') #240.15.202.179 # 输出列表中元素,用点分隔
  7. else:
  8. print('data error!')

可以用列表推导式实现:

  1. ip = input()
  2. if len(ip) == 32 and set(ip) <= {'0','1'}: # 当字符串长度为32,且转为集合后是{'0','1'}的子集时,
  3. print('.'.join([str(int(ip[i*8:(i+1)*8],2)) for i in range(4)])) # 列表推导式得到包含4个数值转的字符串为元素的列表,再用join()方法用'.'连接到一起
  4. else:
  5. print('data error!')

可以合并到两条语句:

  1. ip = input()
  2. print('.'.join([str(int(ip[i*8:(i+1)*8],2)) for i in range(4)])) if len(ip) == 32 and set(ip) <= {'0','1'} else print('data error!')