题目是这样的:给定10亿+个int型数,要求找出重复出现的数字,并输出。(前提是在32位的机器上)
首先,对题目进行认识,如果给定的int型数据很少的话,筛选数据的一般方法是直接建立整型数组存入数据,再利用冒泡或者其他排序方式进行排序就可以很容易筛选出重复的。
然后,要判断机器运算的范围究竟是多大。32位的机器,内存有2的32次方bit,换算成GB是4G,然而实际计算机能用到的不到2G。。。10亿个int,每个int等于4个byte,1个byte等于8个bit,如果全部导入内存的话需要的空间将近30G,远远超出计算机的计算范围。
所以,要将int型数转化之后才能导入内存。计算机内的最小存储单位是bit,如果把数字全存到bit数组里会多大呢?计算之后发现用不了1G,所以可以尝试。用bit数组的下标来记录数字,因为bit只有0和1,所以可以让bit做标志位,初值为0,当该下标的数出现时变为1,当已经为1时证明该下标的数已出现过,one by one的判断。
例如要找的数是100,只需判断bit[100]为0还是1。
然而,代码能开的最小数组是byte,开不了bit的。所以建立byte数组后需要先找到要找的数(bit位)在byte数组中的位置,把该数展开为8位的bit,将用到的位提取出来,对该位上的符号进行判断和处理。
例如还是找100,100/8=12余4,即要找的"bit[100]"其实就在byte[12]中(因为从byte[0]开始),将byte[12]按位展开,得到范围为0-7的8位字符,假设得到的是"00000000",因为余数是4,所以第4位就变为1(从第0位开始),变成"00001000"。
找“bit数组”中的位置就变成找byte数组中的位置(下标)和该位置 按位 展开后某一位的位置。用要找的数除以8,商就是byte数组的下标,余数就是8位中的位置。
至于将byte展开为bit的方法可以自己按位运算写一个方法也可以直接调用如下方法:
String string = Integer.toBinaryString(byte[n]);
这个方法可以将10进制数转化为2进制字符串。然后就可以从字符串中提取当前所需要的位进行操作。具体操作如下代码,如果该位为1即已出现,输出;如果该位为0说明第一次出现,赋值为1。
char[] c=new char[8]; for (int j = 0; j <8; j++) { c[j]=string.charAt(j); } if(c[yu]=='1'){ System.out.println(a[i]+"已出现"); } else{ c[yu]='1'; }
对位运算过后因为要保存数据,所以更改过的位要重新写入byte数组中 。
String st=""; for(int m=0;m<8;m++){ st=st+c[m]; } bytes[zheng]=(byte) Integer.parseInt(st, 2);
另外要注意的一点是因为我们用java写的代码,java中byte是有符号的。
在把byte转展开为2进制数时,如果数展开不足8位,及为较小正数时,系统不会自动左补零补够8位。
在把string的8位当做2进制转成byte时,因为是强制转型,当该数为负时会变成32位,左边全部是1。
具体解决方案如下:
0不够就左补0,为负时就截取最后8位。
while(string.length()<8){//为正小于八位时左补零 string="0"+string; } while(string.length()>9){//为负大于八位截取最后八位 string=string.substring(24,32); }
最后,所有要找的数全部由随机产生。
完整代码如下:
package com.test.myNum; import java.util.Random; public class test { public static void main(String[] args) { byte[] bytes=new byte[170000000]; Random random=new Random(); int a[]=new int[10000000]; int zheng,yu,flag=0; for(int i=0;i<1000000;i++){ a[i]=random.nextInt(1000000000); zheng=a[i]/8; yu=a[i]%8; String string = Integer.toBinaryString(bytes[zheng]); while(string.length()<8){//为正小于八位时左补零 string="0"+string; } while(string.length()>9){//为负大于八位截取最后八位 string=string.substring(24,32); } char[] c=new char[8]; for (int j = 0; j <8; j++) { c[j]=string.charAt(j); } if(c[yu]=='1'){ System.out.println(a[i]+"已出现"); flag++; } else{ c[yu]='1'; } String st=""; for(int m=0;m<8;m++){ st=st+c[m]; } System.out.println(st); bytes[zheng]=(byte) Integer.parseInt(st, 2);// System.out.println(a[i]); } System.out.println("所有数字共重复出现"+flag+"次"); } }
相关推荐
5. **错误处理**:在转换过程中,程序需要具备良好的错误处理机制,例如检查TXT文件格式是否正确,数值是否超出可存储范围等,以防止因数据问题导致的程序异常。 6. **兼容性**:由于不同的单片机系统可能有不同的...
数据结构是计算机科学中至关重要的一个领域,它研究如何有效地组织和存储数据,以便于高效地访问和处理。实验报告中的内容聚焦于线性表这一基础数据结构,它是一种简单的数据组织形式,其中元素按顺序排列。在这个...
5. 视图在Visual FoxPro中是一种虚拟表,它不存储数据,而是基于一个或多个表的查询结果。选项D正确,视图可以从表导出,但不能直接用于存储数据。 6. 计算机可以直接执行的是可执行程序(A),即已经编译好的机器...
5. **存储程序**:存储程序是MySQL提供的一种功能,它可以将一组SQL语句存储在服务器上,然后像普通函数或过程一样调用,提高了数据库操作的效率和安全性。 6. **锁**:在多用户环境下,锁用于控制对数据的并发访问...
JVM会将字节码翻译成对应操作系统的机器码,实现了“一次编写,到处运行”的目标。字节码不依赖于特定的硬件平台,因此能在不同的操作系统上运行。 在Java编程中,`import`语句用于导入所需的类库。`java`和`javax`...
这个项目非常适合学习者加深对C语言的理解,尤其是如何处理超出标准整型范围的数字。下面我们将详细分析这个大数计算器的实现原理和关键知识点。 首先,我们要理解C语言的标准数据类型,如int、long、long long等,...
7. 数据结构与存储结构:逻辑数据结构可以有不同的存储实现,每种实现可能影响数据处理效率。 8. 二进制表示:八位二进制最多表示255(11111111二进制),因此296和256无法用8位二进制表示,而333和199可以,但333...
- **有效性规则**:"出厂价"字段的属性设置为数值必须大于0且小于100,超出范围时显示错误提示"输入价格有误请重新输入",确保数据准确性。 - **输入掩码**:"规格"字段的输入掩码设置为"220V-"后跟两位数字(0-9...
在Java中,数组是一种对象,可以存储基本数据类型或引用数据类型。 **导入(Import)**: 导入语句用于将一个包中的类引入到当前的Java文件中,使得可以使用这些类而不需要写出完整的包路径。 **块(Block)**: 块...
5. **离线数据分析**:将数据批量导入到数据仓库或大数据处理平台(如Hadoop),进行深度分析以获取商业洞察。 #### 三、Kafka的核心组件 Kafka的核心组件包括: 1. **生产者(Producer)**:负责向特定的Topic发布...
Python是一种广泛使用的高级编程语言,它具有简洁易读的语法和强大的库支持,使得它在科学计算、数据分析、人工智能、网络开发等多个领域非常受欢迎。Python 3.5.5是Python 3.x系列的一个版本,该版本的库文档长达...
8. 显示器性质 - 显示器是一种输出设备,用于显示信息。 9. 赋值语句 - A、C选项不合法,因为i++ - --j是运算符的不正确组合,D选项中的a(0)不是合法的数组访问方式。 10. Word 剪切功能 - 剪切按钮用于移除选定...
NURBS(Non-Uniform Rational B-Splines)曲线是一种高级的曲线表示形式,广泛应用于CAD/CAM系统和图形渲染中。NURBS曲线的一个重要性质是凸包性,这意味着曲线完全包含在控制点所形成的凸包内。这种性质保证了曲线...
- **解释**: 冯·诺依曼架构是现代计算机的基础,其核心思想是将程序指令和数据存储在同一个存储器中,并通过中央处理器(CPU)执行这些指令。 ### 13. 自由表字段命名规则 - **知识点**: 在自由表中,一个字段名...
一种具体的编程方式,通过封装、继承和多态来组织代码。 - **JDK**: Java Development Kit,Java开发工具包。包含了编译、运行Java程序所需的所有工具和文档。 - **JVM**: Java Virtual Machine,Java虚拟机。一个...
在编程世界中,开发游戏是一种极好的学习实践方式。Python作为一门易学且功能强大的语言,非常适合初学者用来开发各种类型的游戏,其中贪吃蛇游戏尤为经典。这篇内容将深入探讨Python实现贪吃蛇游戏的核心知识点,...
- **Array**: 数组,一种基本的数据结构,用于存储固定数量的同类型元素。 - **Method**: 方法,封装在类中的一段可重复使用的代码。 - **Element**: 元素,集合中的基本单位。 - **Add**: 添加,用于将元素添加到...
用户可以输入自己选择的六个号码(范围为1到45),然后程序将随机生成一组同样范围内的号码,并对比用户输入的号码与随机生成的号码,输出两个号码组之间匹配的数量。 ### 二、关键代码解析 #### 1. 导入必要的...
面向对象是一种编程范式,它通过将数据和处理数据的方法封装在对象中来模拟现实世界中的实体。面向对象编程(OOP)利用类、对象等概念来简化软件开发过程,并增强代码的可重用性和灵活性。 #### OOP (Object-...