问题:对于一组数据,只有一个数字出现了一次,其余的均出现了n次, 请你找出这个出现了一次的数据。
思路:对于这种问题我们可以使用hashmap的键值对来操作。但我们这里换一种思路,对于十个十进制数13来说,将每一位数字进行无进位加法,结果就变成了00,所以我们可以推断对于k个k进制数进行无进位加法结果一定是0。
这里我们就利用这种思想来解决这一题。
public class Main {
public static void main(String[] args) {
// 定义一个n这里表示在这个数列中一个数重复的次数,便于Scanner输入
int n = 4;
// 定义一个数组,以后可以改进为Scanner输入值
int[] arr = { 1, 1, 1, 1, 13, 13, 13, 13, 28, 28, 28, 28, 35 };
// 定义一个二维的字符数组存储转化为n进制的数
char[][] ch = new char[arr.length][];
// 定义一个变量存储所有n进制数的最长的长度,以便于后面做不进位加法
int loest = 0;
// 利用for循环将所有的数都转化为n进制数,并存人ch数组
for (int i = 0; i < arr.length; i++) {
/*
* 这一步比较难理解,创建一个StringBuffer变量(目的是为了使用其reverse()方法将字符串进行翻转),
* 并利用Integer.toString()方法把十进制数转化为n进制的字符串形式
* 使用reverse()方法是为了将n进制的高位与低位互换,以便在做加法时对齐低位 再利用toString()将StringBuffer对象转化为字符串
* 再利用toCharArray()将字符串转为字符数组
*/
ch[i] = new StringBuffer(Integer.toString(arr[i], n)).reverse().toString().toCharArray();
// 做一个判断获取n进制串的最大长度
if (ch[i].length > loest) {
loest = ch[i].length;
}
}
// 定义一个int数组存放每一位相加时的总值
int[] a = new int[loest];
// 做一个循环将ch数组的每一列相加
for (int i = 0; i < loest; i++) {
for (int j = 0; j < arr.length; j++) {
// 如果一个数的n进制长度不够最大长度,就在其最高位补0相加;
if (ch[j].length <= i) {
a[i] += 0;
} else {
// 将每一位数进行相加
a[i] += ch[j][i] - '0';
// 对n求余来达到无进位的效果
a[i] = a[i] % n;
}
}
}
// 将n进制数转化为十进制
int res = 0;
for (int i = 0; i < a.length; i++) {
res += a[i] * Math.pow(n, i);
}
System.out.println(res);
}
}