一周错题5(编程题)

【一周错题5(编程题)】1、整数与IP地址间的转换
ip地址的每段可以看成是一个0-255的整数,把每段拆分成一个二进制形式组合起来,然后把这个二进制数转变成一个长整数。

import java.util.Scanner; public class Solution2 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); while (scanner.hasNext()) { String ip = scanner.nextLine(); String ip10 =scanner.nextLine(); System.out.println(convertIp10(ip)); //ip转十进制 System.out.println(convertIp(ip10)); //十进制转ip } }private static String convertIp(String ip10) { StringBuffer sb = new StringBuffer(); String ip2 = Long.toBinaryString(Long.parseLong(ip10)); //长整型转二进制字符串 String as = ""; if(ip2.length()<32){//不足32位前面补0 for(int i=0; i<32-ip2.length(); i++){ as +="0"; } } ip2 = as+ip2; //IP地址每一段进行拼接 String[] ips = new String[4]; ips[0] = ip2.substring(0,8); ips[1] = ip2.substring(8,16); ips[2] = ip2.substring(16,24); ips[3] = ip2.substring(24); for(int i=0; i<4; i++){ sb.append(Integer.parseInt(ips[i],2)); if(i!=3){ sb.append("."); } } return sb.toString(); }private static long convertIp10(String ip) { String[] ips = ip.split("\\."); StringBuffer sb = new StringBuffer(); for (int i = 0; i < ips.length; i++) { sb.append(binaryString(ips[i])); } return Long.parseLong(sb.toString(),2); }private static String binaryString(String s) { StringBuffer sb = new StringBuffer(); int num = Integer.parseInt(s); int k = 1<<7; for(int i=0; i<8; i++){ int flag = (num&k)==0?0:1; sb.append(flag); num=num<<1; } return sb.toString(); } }

思路:P地址转10进制IP地址:IP地址拆分,每段转二进制 ,二进制字符串转Long。
10进制IP地址转IP地址:10进制IP地址转二进制字符串,不足32位补位,按照每段8位进行拆分,每段转10进制,拼接4段组成IP地址
2、年会抽奖
今年公司年会的奖品特别给力,但获奖的规矩却很奇葩:
1. 首先,所有人员都将一张写有自己名字的字条放入抽奖箱中;
2. 待所有字条加入完毕,每人从箱中取一个字条;
3. 如果抽到的字条上写的就是自己的名字,那么“恭喜你,中奖了!”
现在告诉你参加晚会的人数,请你计算有多少概率会出现无人获奖?
import java.util.Scanner; public class Solution3 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); while (scanner.hasNext()) { int n =scanner.nextInt(); float sum1 = factorial(n); float sum2 = count(n); float result1 = (sum2/sum1)*100; System.out.println(String.format("%.2f", result1) + "%"); } }private static float count(int n) { if (n==1) { return 0; } else if (n==2) { return 1; } else { return (n-1)*(count(n-1)+count(n-2)); } }private static float factorial(int num) { float result = 1; if (num==0) { return 1; } else if (num>0) { result = num*factorial(num-1); } return result; } }

思路:抽奖可能出现的情况作为分母:Fn = 1 出现 1 种情况;n = 2 出现 2 种情况;n = 3 出现 6 种情况;n 出现 n! 种情况
每个人不可能抽中的情况作为分子:C假设每个人都中奖,可以认为 n 个元素都在中奖的位置,如果每个人都不中奖,那么只要确保n个元素不在原有中奖位置即可,那么问题转化为如何错排n个元素。无法中奖的概率即为:C / F * 100 %
3、奇偶校验
输入一个字符串,然后对每个字符进行奇校验,最后输出校验后的二进制数(如'3’,输出:10110011)。
import java.util.Scanner; public class Solution4 { public static void main(String[] args) { Scanner in = new Scanner(System.in); while(in.hasNext()){ String str = in.nextLine(); jiQiaoYan(str.toCharArray()); //将输入的字符串统一转换为字符数组 } }private static void jiQiaoYan(char[] s) { int[] result = new int[8]; for(int i = 0; i < s.length; i++) { int n = 0x01; int j = 7; int sum = 0; while (j > 0) { //需要进行7次与运算,得出1的个数 及 二进制形式 result[j] = (s[i] & n) == 0 ? 0 : 1; //与运算 if (result[j] == 1) sum++; //个数 n = n << 1; j--; } if ((sum & 1) == 0) result[0] = 1; //进行校验 for (int k = 0; k < result.length; k++) { System.out.print(result[k]); } result[0] = 0; System.out.println(); } } }

思路:将数字和字母统一看成是char类型的,所以数字3实际存储时为ASCII码中的‘3’,其十进制表示是51,转化为二进制表示就是0110011,取最高位为奇校验位,校验位为1,所以校验后的二进制数为10110011,字母同理。故本题只需将输入的字符减去‘\0’得到字符的十进制表示,再将其转化为七位二进制数加上一位校验位输出即可。



    推荐阅读