• 位运算-出现k次与出现一次


    题目:数组中arr只有一个数出现了1次,其他的数都出现了k次,请输出这个只出现了一次的数。

    思路:这道题目要求使用位运算实现,如果采用数据结构Map就会简单很多。解此题前先了解不进位加法的思想,比如两个二进制数10+10 进行不进位加法得到的结果是00(二进制),再比如10个51进行不进位加法结果也为00(十进制),这里就可以得出结论,如果K个相同的K进制数进行无进位加法,相加的结果一定是每一位上都为0的K进制数。那么这道题的思路就是,构造一个二位数组kRadix,其中一维索引是数组arr的长度,二位索引存的就是每个数字的三进制字符串再反转过后的字符数组,这里要反转的目的是因为数组arr转化成三进制数组时的长度不一样,反转过后的字符串高位补0,这样高低位就对齐了,这样才能进行不进位加法。然后对每一列采用不进位加法,将结果存进一个一维数组resArr,再然后遍历这个数组分别对K求余累加算出十进制,得出的数据就是唯一的那个数。

    代码:

    public class 出现K次 {
    
    	public static void main(String[] args) {
    		int []arr = {2,2,2,9,7,7,7,3,3,3,6,6,6,0,0,0};
    		int len = arr.length;
    		char [][] kRadix = new char[len][];
    		int k = 3;
    		// 转成k进制字符数组
    		int maxLen = 0;
    		// 对于每个数字
    		for (int i = 0; i < len; i++) {
    			// 求每个数字的三进制字符串并反转,然后转为字符数组
    			kRadix[i] = new StringBuilder(Integer.toString(arr[i],k)).reverse().toString().toCharArray();
    			if (kRadix[i].length>maxLen) {
    				maxLen = kRadix[i].length;
    			}
    		}
    		int [] resArr = new int[maxLen];
    		// 不进位加法
    		for (int i = 0; i < len; i++) {
    			// 不进位加法
    			for (int j = 0; j < maxLen; j++) {
    				if (j>=kRadix[i].length) {
    					resArr[j] += 0;
    				}else {
    					resArr[j] += (kRadix[i][j]-'0'); // kRadix[i][j]-'0' 字符-'0'  从字符转换成了数字
    				}
    			}
    		}
    		int res = 0;
    		for (int i = 0; i < maxLen; i++) {
    			res += (resArr[i] % k ) * (int)(Math.pow(k, i));  // 累加求出十进制
    		}
    		System.out.println("数组中唯一出现的数字是:"+res);
    
    	}
    
    }
    

    结果:

      

  • 相关阅读:
    数据库得四种隔离级别(非原创,转载文章)
    c#中的数据类型简介(委托)
    c#中的数据类型简介(数组)
    c#中的数据类型简介(枚举)
    c#中的数据类型简介(string)
    c#中的数据类型简介
    二分法的查找图解
    Linux下多个.c文件的编译和Makefile文件
    C语言中const和数组
    grep和正则表达式
  • 原文地址:https://www.cnblogs.com/xiaoyh/p/10251498.html
Copyright © 2020-2023  润新知