1、 从一个数组中找出一个平衡点,即这个点的左边的和与右边的和相等。这个数组可能非常大。
2、 找出数组中出现次数超过一次的数,数组长度可能超过100万。
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author peijunlin
*
*/
public class BalanceNum1 {
/**
* @param args
*/
public static void main(String[] args) {
int[] nums = {2,3,2,-2,-3,2,3};
List list = getBalanceIndex(nums);
for(int i=0;i<list.size();i++){
System.out.print(list.get(i)+" ");
}
}
/**
* 本方法用BigDecimal类来保存数组之和
* 确保int[] 数组之和不会发生越界而产生错误
*
* @param nums int[]数组
* @return List所有平衡点下标集合
*/
public static List getBalanceIndex(int[] nums){
List list = new ArrayList();
int n_length = nums.length;
BigDecimal sumBig = new BigDecimal(0);
BigDecimal leftBig = new BigDecimal(0);
BigDecimal rightBig = new BigDecimal(0);
for(int i=0;i<n_length;i++){
BigDecimal bigi = new BigDecimal(nums[i]);
sumBig = bigi.add(sumBig);
}
for(int i=0;i<n_length;i++){
rightBig = leftBig.negate().add(sumBig).add(new BigDecimal(nums[i]).negate());
System.out.println("nums["+i + "]" + leftBig);
System.out.println("nums["+i + "]" + rightBig);
if(leftBig == rightBig)
list.add(i);
leftBig = new BigDecimal(nums[i]).add(leftBig);
}
return list;
}
}
/* 运行结果:
nums[0]0
nums[0]5
nums[1]2
nums[1]2
nums[2]5
nums[2]0
nums[3]7
nums[3]2
nums[4]5
nums[4]5
nums[5]2
nums[5]3
nums[6]4
nums[6]0
1 4
即下标为 :1 和 4 的位置的数为平衡数
*/
import java.util.HashMap;
import java.util.Map;
/**
* 采用将原数组进行分段存取的策略
* 本类将原数据分为三段进行存取,当然可以分的更多一些;
*
* @author peijunlin
*
*/
public class ReData1 {
//存放1000以下的数据
Map<Integer,Integer > map1000 = new HashMap<Integer,Integer>();
//存放1000-10000之间的数据
Map<Integer,Integer> map10000 = new HashMap<Integer,Integer >();
//存放10000以上的数据
Map<Integer,Integer> mapOther = new HashMap<Integer,Integer >();
/**
*
* @param args
*/
public static void main(String[] args) {
ReData1 redata = new ReData1();
//假如有数组长度有一百万
int[] bigints = new int[1000000];
//把大数组阶段成较小的数组,每段10000
for(int i=0;i<bigints.length;i+=10000){
int[] small = new int[10000];
System.arraycopy(bigints, i, small, 0, 10000);
redata.dataAdd2Map(small);
}
}
/**
* 循环遍历一个数组将其中的数据加到Map中去
*
* @param nums
*/
public void dataAdd2Map(int[] nums){
int nums_length = nums.length;
for(int i=0;i<nums_length;i++){
add2Map(nums[i]);
}
}
/**
* 根据int参数值的范围选择对应的Map进行存放
* @param num
*/
public void add2Map(int num){
Map<Integer ,Integer> map = new HashMap<Integer,Integer>();
if(num<1000){
map = map1000;
}else if(num>1000 && num<10000) {
map = map10000;
}else {
map = mapOther;
}
Integer key = map.get(num);
if(key == null){
map.put(num, 1);
}else{
Integer n = map.get(num);
map.put(num, n+1);
}
}
}
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 百万级的数据一般存放在数据文件或数据库中,
* 本Demo设计针对数据存放在数据文件中的情况。
*
* 用读取IO流的方式读取大数据文件,让后再去将重复
* 数据存到另一个数据文件中,但是同样在JVM中使用分段
* Map保存数据。
*
*/
public class ReData2 {
//存放1000以下的数据
static Map<Integer,Integer > map1000 = new HashMap<Integer,Integer>();
//存放1000-10000之间的数据
static Map<Integer,Integer> map10000 = new HashMap<Integer,Integer >();
//存放10000以上的数据
static Map<Integer,Integer> mapOther = new HashMap<Integer,Integer >();
public static void main(String[] args) throws Exception {
ReData2 rd = new ReData2();
rd.readData();
Set<Integer> set = map1000.keySet();
Iterator it = set.iterator();
while(it.hasNext()){
Integer key = (Integer)it.next();
Integer value = map1000.get(key);
System.out.println("map1000 ["+key+","+value+"]");
}
rd.writeData(map1000,"redata.txt");
}
/**
* 将数据文件中的数据读取到Map中去
* @throws Exception
*/
public void readData() throws Exception {
InputStreamReader is = new InputStreamReader(new FileInputStream("datafile.txt"));
BufferedReader reader = new BufferedReader(is);
String s;
while((s=reader.readLine())!=null){
List<Integer> list = str2int(s);
list2Map(list);
}
reader.close();
}
/**
* 将指定的Map中的数据存放到指定的文件中
* @param map
* @param file 存放数据的文件名(包括路径)
* @throws Exception
*/
public void writeData(Map<Integer,Integer> map,String file) throws Exception {
FileOutputStream fos=new FileOutputStream(file);
OutputStreamWriter out = new OutputStreamWriter(fos);
PrintWriter writer=new PrintWriter(out);
Map<Integer,Integer > maps = new HashMap<Integer,Integer>();
maps = map;
Set<Integer> set = map.keySet();
Iterator it = set.iterator();
int number=0;
while(it.hasNext()){
Integer data = (Integer)it.next();
Integer nums = map.get(data);
if(nums>1 ){
number++;
writer.write(data+",");
}
if(number >= 1000){
writer.flush();
number = 0;
}
}
writer.close();
}
/**
* 一个字符串数据分割之后,将有效数据保存到List中
* @param s String字符串
* @return List<Integer>
*/
public List<Integer> str2int(String s){
List<Integer> list = new ArrayList<Integer>();
String[] ss = s.split(",");
int ss_length = ss.length;
for(int i=0;i<ss_length;i++){
String str = ss[i];
if(!"".equals(str))
list.add(Integer.parseInt(str));
}
return list;
}
/**
* 将List中的数据存放到指定的Map中
* @param list
*/
public void list2Map(List list){
int size = list.size();
for(int i=0;i<size;i++){
Integer num = (Integer) list.get(i);
add2Map(num);
}
}
/**
* 根据int参数值的范围选择对应的Map进行存放
* @param num
*/
public void add2Map(int num){
Map<Integer ,Integer> map = new HashMap<Integer,Integer>();
if(num<1000){
map = map1000;
}else if(num>1000 && num<10000) {
map = map10000;
}else {
map = mapOther;
}
Integer key = map.get(num);
// System.out.println("key:"+key);
if(key == null){
map.put(num, 1);
}else {
Integer n = map.get(num);
// System.out.println("n:"+n);
map.put(num, n+1);
}
}
}
2、 找出数组中出现次数超过一次的数,数组长度可能超过100万。
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author peijunlin
*
*/
public class BalanceNum1 {
/**
* @param args
*/
public static void main(String[] args) {
int[] nums = {2,3,2,-2,-3,2,3};
List list = getBalanceIndex(nums);
for(int i=0;i<list.size();i++){
System.out.print(list.get(i)+" ");
}
}
/**
* 本方法用BigDecimal类来保存数组之和
* 确保int[] 数组之和不会发生越界而产生错误
*
* @param nums int[]数组
* @return List所有平衡点下标集合
*/
public static List getBalanceIndex(int[] nums){
List list = new ArrayList();
int n_length = nums.length;
BigDecimal sumBig = new BigDecimal(0);
BigDecimal leftBig = new BigDecimal(0);
BigDecimal rightBig = new BigDecimal(0);
for(int i=0;i<n_length;i++){
BigDecimal bigi = new BigDecimal(nums[i]);
sumBig = bigi.add(sumBig);
}
for(int i=0;i<n_length;i++){
rightBig = leftBig.negate().add(sumBig).add(new BigDecimal(nums[i]).negate());
System.out.println("nums["+i + "]" + leftBig);
System.out.println("nums["+i + "]" + rightBig);
if(leftBig == rightBig)
list.add(i);
leftBig = new BigDecimal(nums[i]).add(leftBig);
}
return list;
}
}
/* 运行结果:
nums[0]0
nums[0]5
nums[1]2
nums[1]2
nums[2]5
nums[2]0
nums[3]7
nums[3]2
nums[4]5
nums[4]5
nums[5]2
nums[5]3
nums[6]4
nums[6]0
1 4
即下标为 :1 和 4 的位置的数为平衡数
*/
import java.util.HashMap;
import java.util.Map;
/**
* 采用将原数组进行分段存取的策略
* 本类将原数据分为三段进行存取,当然可以分的更多一些;
*
* @author peijunlin
*
*/
public class ReData1 {
//存放1000以下的数据
Map<Integer,Integer > map1000 = new HashMap<Integer,Integer>();
//存放1000-10000之间的数据
Map<Integer,Integer> map10000 = new HashMap<Integer,Integer >();
//存放10000以上的数据
Map<Integer,Integer> mapOther = new HashMap<Integer,Integer >();
/**
*
* @param args
*/
public static void main(String[] args) {
ReData1 redata = new ReData1();
//假如有数组长度有一百万
int[] bigints = new int[1000000];
//把大数组阶段成较小的数组,每段10000
for(int i=0;i<bigints.length;i+=10000){
int[] small = new int[10000];
System.arraycopy(bigints, i, small, 0, 10000);
redata.dataAdd2Map(small);
}
}
/**
* 循环遍历一个数组将其中的数据加到Map中去
*
* @param nums
*/
public void dataAdd2Map(int[] nums){
int nums_length = nums.length;
for(int i=0;i<nums_length;i++){
add2Map(nums[i]);
}
}
/**
* 根据int参数值的范围选择对应的Map进行存放
* @param num
*/
public void add2Map(int num){
Map<Integer ,Integer> map = new HashMap<Integer,Integer>();
if(num<1000){
map = map1000;
}else if(num>1000 && num<10000) {
map = map10000;
}else {
map = mapOther;
}
Integer key = map.get(num);
if(key == null){
map.put(num, 1);
}else{
Integer n = map.get(num);
map.put(num, n+1);
}
}
}
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 百万级的数据一般存放在数据文件或数据库中,
* 本Demo设计针对数据存放在数据文件中的情况。
*
* 用读取IO流的方式读取大数据文件,让后再去将重复
* 数据存到另一个数据文件中,但是同样在JVM中使用分段
* Map保存数据。
*
*/
public class ReData2 {
//存放1000以下的数据
static Map<Integer,Integer > map1000 = new HashMap<Integer,Integer>();
//存放1000-10000之间的数据
static Map<Integer,Integer> map10000 = new HashMap<Integer,Integer >();
//存放10000以上的数据
static Map<Integer,Integer> mapOther = new HashMap<Integer,Integer >();
public static void main(String[] args) throws Exception {
ReData2 rd = new ReData2();
rd.readData();
Set<Integer> set = map1000.keySet();
Iterator it = set.iterator();
while(it.hasNext()){
Integer key = (Integer)it.next();
Integer value = map1000.get(key);
System.out.println("map1000 ["+key+","+value+"]");
}
rd.writeData(map1000,"redata.txt");
}
/**
* 将数据文件中的数据读取到Map中去
* @throws Exception
*/
public void readData() throws Exception {
InputStreamReader is = new InputStreamReader(new FileInputStream("datafile.txt"));
BufferedReader reader = new BufferedReader(is);
String s;
while((s=reader.readLine())!=null){
List<Integer> list = str2int(s);
list2Map(list);
}
reader.close();
}
/**
* 将指定的Map中的数据存放到指定的文件中
* @param map
* @param file 存放数据的文件名(包括路径)
* @throws Exception
*/
public void writeData(Map<Integer,Integer> map,String file) throws Exception {
FileOutputStream fos=new FileOutputStream(file);
OutputStreamWriter out = new OutputStreamWriter(fos);
PrintWriter writer=new PrintWriter(out);
Map<Integer,Integer > maps = new HashMap<Integer,Integer>();
maps = map;
Set<Integer> set = map.keySet();
Iterator it = set.iterator();
int number=0;
while(it.hasNext()){
Integer data = (Integer)it.next();
Integer nums = map.get(data);
if(nums>1 ){
number++;
writer.write(data+",");
}
if(number >= 1000){
writer.flush();
number = 0;
}
}
writer.close();
}
/**
* 一个字符串数据分割之后,将有效数据保存到List中
* @param s String字符串
* @return List<Integer>
*/
public List<Integer> str2int(String s){
List<Integer> list = new ArrayList<Integer>();
String[] ss = s.split(",");
int ss_length = ss.length;
for(int i=0;i<ss_length;i++){
String str = ss[i];
if(!"".equals(str))
list.add(Integer.parseInt(str));
}
return list;
}
/**
* 将List中的数据存放到指定的Map中
* @param list
*/
public void list2Map(List list){
int size = list.size();
for(int i=0;i<size;i++){
Integer num = (Integer) list.get(i);
add2Map(num);
}
}
/**
* 根据int参数值的范围选择对应的Map进行存放
* @param num
*/
public void add2Map(int num){
Map<Integer ,Integer> map = new HashMap<Integer,Integer>();
if(num<1000){
map = map1000;
}else if(num>1000 && num<10000) {
map = map10000;
}else {
map = mapOther;
}
Integer key = map.get(num);
// System.out.println("key:"+key);
if(key == null){
map.put(num, 1);
}else {
Integer n = map.get(num);
// System.out.println("n:"+n);
map.put(num, n+1);
}
}
}