题目原型:

有一张标准的树状结构表,里面有Structure_Id和 Parent_Id两个关键列,记录了结点的父子关系。现在要求添加一个字段为 Structure_Code ,标记为 三位一个节点关系,比如 第一级的为 001,002,第二级的为 001 001 , 001 002等,以此类推。

现在添加了这样一列:

想要的是这样的:

为什么要这样的东西呢?因为这列中可以描述:它的父亲是谁,爷爷是谁,太爷爷是谁,祖先是谁,当然也可以描述它的所有孩子有哪些,是居家必备,出门旅行的好东西啊!!!做树状设计时强烈推荐。

那么如何处理呢??这是个算法问题,请大家自行设计一下,我们对比一下执行效率。我的答案是5K条左右的数据,共需0.5秒。如果你的算法更优,请告诉我。

我的思路,不要先看啊,请自行设计一下。

解决思路:

、定义一个NodeBean,包括Structure_ID,Parent_ID,Structure_Code,Child_Count四个属性

、创建一个数据结构var dict=new Dictionary<String, NodeBean>();

、采用DataAdapter一次性将整表读入到内存,存放到dict中。

、初始化根结点:查询所有根结点,然后按Stucture_ID做为Key,查询到dict中的此实例,然后把对应的NodeBean四个属性分别给定值,Parent_ID=---,Child_Count=,Sturcture_Code分别为 ,,... 020等。

、定义一个栈,FILO的东西,http://blog.csdn.net/aladdinty/article/details/3506285

Stack<string> stack = new Stack<string>(); 这个栈用来装需要马上找到父亲的节点。

、遍历dict,找到第一条记录对应的Structure_Code,如果是空的,那么表示需要填充值,添加到上面定义好的栈里。

、查找到对应的Parent_ID,然后拿此Parent_ID为KEY去dict中查找上一级节点对应的Structure_Code,

、如果找到了,那么就可以更改父节点的,Child_Count++,表示又有一个孩子回家了。把父亲的Structure_Code放在前面,后面根据Child_Count记录001,,

、如果还是没有找到,那么继续加入到定义好的栈里。

、循环检查栈里面是不是有东西,有的话,遍历每一个,因为特殊的数据结构栈,所以是FILO的,就是先进后出,这样就把爷爷结点先和太爷爷结点建立起了关系,把它移除,然后处理父亲,最后处理孩子的。

OK,至此这个Dictionary整理完成,我们重新组装成SQL,一次性事务提交到数据库即可了。

附上代码实现:

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.SQLite;
using System.Diagnostics;
using System.Windows.Forms; namespace WindowsFormsApplication2
{
public class InsideBean
{
public String StructureId { get; set; }
public String ParentId { get; set; }
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//大字典
readonly Dictionary<String, NodeBean> _dict = new Dictionary<String, NodeBean>();
//定义一个堆
readonly Stack<String> _stack = new Stack<String>();
private String _sql = ""; private void button1_Click(object sender, EventArgs e)
{
// 开始计时
var watch = new Stopwatch();
watch.Start(); DbProviderFactory factory = SQLiteFactory.Instance;
using (var conn = factory.CreateConnection())
{
// 连接数据库
if (conn != null)
{
conn.ConnectionString = @"Data Source=c:\resource_db.db";
conn.Open(); //有哪些个学段科目
_sql = "select structure_id,parent_id,structure_node from t_resource_structure";
var adapter = new SQLiteDataAdapter(_sql, conn.ConnectionString);
var dataSet = new DataSet();
adapter.Fill(dataSet, "myTable");
var dt = dataSet.Tables[]; for (var i = ; i < dt.Rows.Count; i++)
{
var mybean=new NodeBean
{
Child_Count = ,
Parent_ID = dt.Rows[i]["parent_id"].ToString(),
StructureId = dt.Rows[i]["structure_id"].ToString(),
Structure_Code = ""
}; _dict.Add(dt.Rows[i]["structure_id"].ToString(),mybean);
}
//给所有根结点初值
_sql = "select structure_id from t_resource_structure where structure_id=xdkm_id";
adapter = new SQLiteDataAdapter(_sql, conn.ConnectionString);
dataSet = new DataSet();
adapter.Fill(dataSet, "myTable");
dt = dataSet.Tables[]; for (int i = ; i < dt.Rows.Count; i++)
{
var code = + (i + );
var resultCode = code.ToString().Substring(, );
_dict[dt.Rows[i][].ToString()].Child_Count = ;
_dict[dt.Rows[i][].ToString()].Structure_Code = resultCode;
} foreach (KeyValuePair<string, NodeBean> a in _dict)
{
if (a.Value.Structure_Code == "")
{
//入栈,表示这个家伙需要进行本轮处理
_stack.Push(a.Value.StructureId); var currentBean = new InsideBean
{
ParentId = a.Value.Parent_ID,
StructureId = a.Value.StructureId
}; while (_stack.Count > )
{
if (_dict[currentBean.ParentId].Structure_Code == "")
{
_stack.Push(currentBean.ParentId);
//结构ID
currentBean.StructureId = currentBean.ParentId;
//结构的父ID
currentBean.ParentId = _dict[currentBean.ParentId].Parent_ID;
}
else
{
//找到了它父亲的东西
_dict[currentBean.ParentId].Child_Count++;
int code = + (_dict[currentBean.ParentId].Child_Count);
String resultCode = code.ToString().Substring(, );
_dict[currentBean.StructureId].Structure_Code = _dict[currentBean.ParentId].Structure_Code + resultCode;
//把父亲出栈
_stack.Pop();
//把这个父亲的儿子
if (_stack.Count > )
{
//结构ID
currentBean.StructureId = _stack.Peek();//取出顶层元素
//结构的父ID
currentBean.ParentId = _dict[_stack.Peek()].Parent_ID;
}
}
}
}
} //保存到数据库
_sql = "update t_resource_structure set structure_node=? where structure_id=?";
var cmd = conn.CreateCommand();
var trans = conn.BeginTransaction();
cmd.Connection = conn;
cmd.CommandText = _sql;
// 添加参数
cmd.Parameters.Add(cmd.CreateParameter());
cmd.Parameters.Add(cmd.CreateParameter());
try
{
foreach (var a in _dict)
{
cmd.Parameters[].Value = a.Value.Structure_Code;
cmd.Parameters[].Value = a.Value.StructureId;
cmd.ExecuteNonQuery();
}
trans.Commit();
}
catch (Exception err)
{
trans.Rollback();
throw;
}
} //更新一下资源与结构对应关系表
_sql =
"update t_resource_location set structure_node=(select t_resource_structure.structure_node from t_resource_structure where t_resource_structure.structure_id=t_resource_location.node_id)";
using (var cmd2 = conn.CreateCommand())
{
cmd2.Connection = conn;
cmd2.CommandText = _sql;
cmd2.ExecuteNonQuery();
}
conn.Close();
// 停止计时
watch.Stop();
MessageBox.Show("完成:耗时" + watch.Elapsed);
}
}
}
}

JAVA组程序优化综合考试试题的更多相关文章

  1. HTML5 +Java基础 大一结业认证考试试题 - 云南农业职业技术学院 - 互联网技术学院 - 美和易思校企合作专业

     第1题 [单选题][0.33分][概念理解] 关于java中的逻辑运算符,下列说法正确的是 逻辑运算符||.&&.!都是用于连接两个关系表达式</p> 当&&am ...

  2. Java高级大一结业认证考试试题 - 云南农业职业技术学院 - 互联网技术学院 - 美和易思校企合作专业

     第1题 .关于XML的文档结构描述错误的是 一个基本的XML文档通常由序言和文档元素两部分组成 XML文档中的序言可以包括XML声明.处理指令和注释 XML文档中的元素以树形结构排列 XML文档的声 ...

  3. Android开发,java开发程序员常见面试题,求100-200之间的质数,java逻辑代码

    public class aa{ public static void main (String args []){ //author:qq986945193 for (int i = 100;i&l ...

  4. JAVA 综合面试题

    JAVA 综合面试题 2007-08-12 目录 TOC \o "1-3" \h \z \u Java面试题整理 9 Java面向对象 9 1. super()与this()的区别 ...

  5. Java初中级程序员面试题宝典

    Java基础部分 &与&&区别? &和&&都是逻辑运算符,都是判断两边同时真则为真,否则为假:但是&&当第一个条件不成之后,后面的条件都 ...

  6. 2018.6.20 Java考试试题总结(Java语言基础与面向对象编程)最新版

    Java考试试题总结 一.单选题(每题1分 * 50 = 50分) 1.java程序的执行过程中用到一套JDK工具,其中javac.exe指( B ) A.java语言解释器 B.java字节码编译器 ...

  7. java web项目优化记录:优化考试系统

    考试系统在进行压力測试时发现,并发量高之后出现了button无反应.试题答案不能写到数据库的问题,于是针对这些核心问题,进行了优化. 数据库方面: Select语句:Select * from TEB ...

  8. Java 程序优化 (读书笔记)

    --From : JAVA程序性能优化 (葛一鸣,清华大学出版社,2012/10第一版) 1. java性能调优概述 1.1 性能概述 程序性能: 执行速度,内存分配,启动时间, 负载承受能力. 性能 ...

  9. 从设计模式的角度看Java程序优化

    一.前言 Java程序优化有很多种渠道,比如jvm优化.数据库优化等等,但都是亡羊补牢的措施,如果能在设计程序架构时利用设计模式就把程序的短板解决,就能使程序更加健壮切容易维护迭代 二.常用的设计模式 ...

随机推荐

  1. source 命令

    作用: 当我修改了/etc/profile文件,我想让它立刻生效,而不用重新登录:这时就想到用source命令,如:source /etc/profile 介绍:source命令也称为“点命令”,也就 ...

  2. 嵌入式 hi3518平台获取网络环境中的ip、netmask、broadcast等信息

    <span style="font-family:Courier New;"> /********************************** (C) COPY ...

  3. linux下动态库编译的依赖问题

    这里主要是想试验一下,对一个具有多层嵌套的动态库进行编译时,是否要把最底层的库也包含进来的问题,结论是:只要直接依赖的库名称,不需要最底层库名称. 一,目录结构ZZZ├── add│   ├── ad ...

  4. Golang 绘图技术(image/draw包介绍)

          image/draw 包仅仅定义了一个操作:通过可选的蒙版图(mask image),把一个原始图片绘制到目标图片上,这个操作是出奇的灵活,可以优雅和高效的执行很多常见的图像处理任务. 1 ...

  5. selenium python (十四)上传文件的处理

    #!/usr/bin/python# -*- coding: utf-8 -*-__author__ = 'zuoanvip' #上传过程一般要打开一个系统的windows窗口,从窗口选择本地文件添加 ...

  6. 匿名函数自执行原理和instanceof运算符执行原理

    今天收到RSS订阅中有一篇<Javascript – Arraylike的7种实现>,看第一种实现方式是,瞬间被!function(){}()这种匿名函数自执行方式给亮瞎了眼睛.这种写法绝 ...

  7. 从今天开始写博客、托管代码到 Github

    最近看了一篇文章,译名<简历危险>,原名<Resumes are dangerous>. 作者为Alex Maccaw,他有一篇文章曾经在网上流传甚广——<Traveli ...

  8. MVC dropdownlist使用

    View中代码 @{ ViewBag.Title = "dropdownlist"; } <h2>dropdownlist</h2> @using (Htm ...

  9. Linux_搜文件

    Linux 下搜文件, 通常先用 whereis 或 locate ,如果找不到,才以 find 搜寻!因为 whereis 与 locate 是利用数据库来搜寻数据,省时间! <<鸟哥的 ...

  10. httpcomponents 学习1--并发多线程GET

    package org.apache.http.examples.client; import org.apache.http.HttpEntity; import org.apache.http.H ...