题目要求

数据格式

Q 系统的输入为纯文本格式的文件,由若干行组成,每一行由城市编号、年龄、收入组成,相邻两项之间用一个空格分隔。以下是输入的一个片段:

1001 20 12000

1001 50 24200

1020 30 30000

其中,城市编号是四位数(第一位不为 0),年龄与收入为整数类型。

查询描述

Q 系统需要实现以下三个常用的查询功能:

  • Q1: 查询城市 X 某个年龄段的平均收入;
  • Q2: 查询城市 X 的收入最高的前 K 位的收入;
  • Q3: 分别查询某些城市某一年龄段收入的中位数。

一、下面的程序使用多线程比单线程快了将近一倍。

下面代码简化了输入过程,让输入的数据提前确定好,便于看时间的效率。

import java.io.*;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;
class My_Thread implements Runnable{
public File file=new File("src/xian/chen01/city.txt"); /*city.txt中存放数据*/
public BufferedReader reader = null;
public List<Integer> list=null;
public List<Integer> n_list=null; /*List方便排序*/
public int line=0;
public int n_line=0;
public int k=50;
public String x_number="1001";
public String n_number="1001";
public int n_age=20;
public BigInteger age=null;
public int back=0;
public long t1=0;
public My_Thread(){
t1=System.currentTimeMillis();
try{
reader = new BufferedReader(new FileReader(file));
list=new ArrayList<Integer>();
n_list=new ArrayList<Integer>();
age=new BigInteger("0");
}catch(Exception e){}
}
@Override
public void run() {
/*此处代码是核心,加锁避免了java.io.IOException: Stream closed 问题*/
synchronized (this) {
if(back==0)
hui(); /*取出文件的内容*/
else
{ if(back==1)
print(); /*打印结果*/
else
return ;
}
}
}
public synchronized void hui (){
try{
//long t1=System.currentTimeMillis(); String tempString = null;
while ((tempString =reader.readLine())!=null) {
String str[]=tempString.split(" ");
if(x_number.equals(str[0]))
{
age=age.add(new BigInteger(str[1]));
int a=Integer.parseInt(str[2]);
list.add(a);
line ++ ;
}
if(n_number.equals(str[0])&&(n_age+"").equals(str[1]))
{
n_list.add(Integer.parseInt(str[2]));
n_line++;
}
}
reader.close();
back=1;
}catch(Exception e){
System.out.println(e);
}
};
public synchronized void print(){
Comparator<Integer> comparator = new Comparator<Integer>()
{
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1; /*降序*/
}
};
if(line>0)
{
age=age.divide(new BigInteger(line+""));
Collections.sort(list,comparator);
System.out.println("该城市的总人数:"+line);
System.out.println("list的大小:"+list.size());
System.out.println("该城市的平均年龄:"+age);
System.out.print("该城市的前k位收入是:");
for(int i=0;i<k&&i<list.size();++i)
System.out.print(list.get(i)+"、");
System.out.println();
}
else
System.out.println("该城市编号不存在");
/*下面是求某个城市的年龄段的中位数收入*/
System.out.print("编号n城市中位数是:");
if(n_line>0)
{
Collections.sort(n_list,comparator);
if(n_line%2==1)
System.out.println(n_list.get(n_line/2));
else
{
System.out.println((n_list.get(n_line/2)+n_list.get((n_line-1)))/2);
}
}else
System.out.println("编号n城市对应的年龄不存在");
back=2;
System.out.println("时间:"+(System.currentTimeMillis()-t1));
};
};
public class Scoket_Q_City_Query2 {
public static void main(String[] args) throws Exception { My_Thread thread=new My_Thread();
new Thread(thread).start();
new Thread(thread).start();
new Thread(thread).start();
new Thread(thread).start();
new Thread(thread).start();
};
}

运行结果:54毫秒

二、下面是仅仅是一个单线程实现(也可以不建立单线程,只在main主线程实现也可以)

import java.io.*;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;
class MyThread implements Runnable{
@Override
public void run() {
hui();
}
public synchronized void hui (){
try{
long t1=System.currentTimeMillis();
Scanner sc=new Scanner(System.in);
Comparator<Integer> comparator = new Comparator<Integer>()
{
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1; /*降序*/
}
};
System.out.print("输入X城市的编号:");
String x_number=null;
//sc.next();
x_number="1001";
System.out.print("收入X城市的k值:");
int k=50;
//sc.nextInt();
System.out.print("输入某个n城市的编号:");
String n_number="1001";
//sc.next();
System.out.print("输入n城市的某个年龄:");
int n_age=20;
//sc.nextInt();
sc.close();
File file=new File("src/xian/chen01/city.txt");
BufferedReader reader = null;
String tempString = null;
BigInteger age=new BigInteger("0");
int line =0;
int n_line =0;
List<Integer> list=new ArrayList<Integer>();
List<Integer> n_list=new ArrayList<Integer>();
reader = new BufferedReader(new FileReader(file));
while ((tempString =reader.readLine())!=null) {
String str[]=tempString.split(" ");
if(x_number.equals(str[0]))
{
age=age.add(new BigInteger(str[1]));
int a=Integer.parseInt(str[2]);
list.add(a);
line ++ ;
}
if(n_number.equals(str[0])&&(n_age+"").equals(str[1]))
{
n_list.add(Integer.parseInt(str[2]));
n_line++;
}
}
reader.close(); if(line>0)
{
age=age.divide(new BigInteger(line+""));
Collections.sort(list,comparator);
System.out.println("该城市的总人数:"+line);
System.out.println("list的大小:"+list.size());
System.out.println("该城市的平均年龄:"+age);
System.out.print("该城市的前k位收入是:");
for(int i=0;i<k&&i<list.size();++i)
System.out.print(list.get(i)+"、");
System.out.println();
}
else
System.out.println("该城市编号不存在");
/*下面是求某个城市的年龄段的中位数收入*/
System.out.print("中位数是:");
if(n_line>0)
{
Collections.sort(n_list,comparator);
if(n_line%2==1)
System.out.println(n_list.get(n_line/2));
else
{ System.out.println((n_list.get(n_line/2)+n_list.get((n_line-1)/2))/2);
}
}else
System.out.println("编号n城市对应的年龄不存在");
System.out.println("运行时间:"+(System.currentTimeMillis()-t1));
}catch(Exception e){}
};
};
public class Scoket_Q_City_Query {
public static void main(String[] args) throws Exception { MyThread thread=new MyThread();
Thread th=new Thread(thread);
th.start();
};
}

时间:84毫秒

多线程中共享变量——CCF总决赛试题的更多相关文章

  1. 【多线程】Java线程面试题 Top 50(转载)

    Java线程面试题 Top 50 原文链接:http://www.importnew.com/12773.html   本文由 ImportNew - 李 广 翻译自 javarevisited.欢迎 ...

  2. JAVA基础再回首(二十五)——Lock锁的使用、死锁问题、多线程生产者和消费者、线程池、匿名内部类使用多线程、定时器、面试题

    JAVA基础再回首(二十五)--Lock锁的使用.死锁问题.多线程生产者和消费者.线程池.匿名内部类使用多线程.定时器.面试题 版权声明:转载必须注明本文转自程序猿杜鹏程的博客:http://blog ...

  3. BlockingQueue阻塞队列(解决多线程中数据安全问题 可用于抢票,秒杀)

    案例:一个线程类中 private static BlockingQueue<Map<String, String>> dataQueue = new LinkedBlocki ...

  4. java多线程中的三种特性

    java多线程中的三种特性 原子性(Atomicity) 原子性是指在一个操作中就是cpu不可以在中途暂停然后再调度,既不被中断操作,要不执行完成,要不就不执行. 如果一个操作时原子性的,那么多线程并 ...

  5. Java Volatile关键字 以及long,double在多线程中的应用

    概念: volatile关键字,官方解释:volatile可以保证可见性.顺序性.一致性. 可见性:volatile修饰的对象在加载时会告知JVM,对象在CPU的缓存上对多个线程是同时可见的. 顺序性 ...

  6. python 多线程中的同步锁 Lock Rlock Semaphore Event Conditio

    摘要:在使用多线程的应用下,如何保证线程安全,以及线程之间的同步,或者访问共享变量等问题是十分棘手的问题,也是使用多线程下面临的问题,如果处理不好,会带来较严重的后果,使用python多线程中提供Lo ...

  7. 多线程(三)~多线程中数据的可见性-volatile关键字

    我们先来看一段代码: ①.线程类,用全局布尔值控制线程是否结束,每隔1s打印一次当前线程的信息 package com.multiThread.thread; publicclassPrintStri ...

  8. Java多线程中提到的原子性和可见性、有序性

    1.原子性(Atomicity)   原子性是指在一个操作中就是cpu不可以在中途暂停然后再调度,既不被中断操作,要不执行完成,要不就不执行. 如果一个操作时原子性的,那么多线程并发的情况下,就不会出 ...

  9. c#初学-多线程中lock用法的经典实例

    本文转载自:http://www.cnblogs.com/promise-7/articles/2354077.html 一.Lock定义     lock 关键字可以用来确保代码块完成运行,而不会被 ...

随机推荐

  1. c语言指针疑惑[转载]

    c99的动态数组是在栈上面开辟的,而new出来的是在堆上面开辟的.栈和堆的地址是从两端相向增长的.栈很小,一般只有几十k,vc6好像是64k.堆很大,在win32的虚拟地址空间可以分配到2g的内存.栈 ...

  2. 数据库 sql server

    1. if exists(select * from sys.objects where name='test') drop table test go create table test ( id ...

  3. RunLoop和autorelease的一道面试题

    有这么一道iOS面试题 以下代码有没有什么问题?如果有?如何解决? for (int i = 0; i < largeNumber; i++) { NSString *str = [NSStri ...

  4. STM32之SRAM调试

    在学习STM32的时候,由于烧FLASH的所造成的时间会比较慢,而在SRAM中调试的时间会比FLASH快很多,再加上FLASH的时候会经常擦除芯片,会对芯片的寿命造成一定的影响, 其实我本人觉得在学习 ...

  5. JavaScript字符串的操作-课堂笔记

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. 关于datagridview里使用combox的总结

    最近写的程序中需要在DataGridView中使用下拉选择的功能,首选方案是列的ColumnType属性 使用EditingControlShowing事件, if (e.Control is Com ...

  7. Thinkphp 1.验证规则 2.静态定义 3.动态验证

    一.验证规则 数据验证可以对表单中的字段进行非法的验证操作.一般提供了两种验证方式: 静态定 义($_validate 属性)和动态验证(validate()方法). //验证规则 array( ar ...

  8. VS2013 GIT 克隆远程仓库

    1.配置本地GIT 工具->选项->源代码管理,选择GIT 2.打开团队资源管理器,找到GIT克隆选项 3.单击克隆,在输入框内输入远程仓库地址,然后单击克隆即可 GIT 插件配置:参考  ...

  9. JS基础知识

    JavaScript的三个不同的组成部分: (1)ECMAScript,提供核心语言功能,所有浏览器大体上都支持ECMA第三版 (2)文本对象模型(DOM),提供访问和操作网页内容的方法和接口 (3) ...

  10. SqList *L 和 SqList * &L的区别/学习数据结构突然发现不太懂 小祥我查找总结了一下

    小祥在学习李春葆的数据结构教程时发现一个小问题,建立顺序表和输出线性表,这两个函数的形参是不一样的. 代码在这里↓↓↓ //定义顺序表L的结构体 typedef struct { Elemtype d ...