帮助

内容读取中…

内容读取中…

首页  |  相册  |  共享  |  群组
搜索

正文

生成并查询最短加法链树的C#程序 (2008-02-22 17:08)

数据库中节点值使用字符串表示,后来证明没什么意义,但其中一些思想和代码还是不错的,写出来分享一下。窗体设计可从代码中推理出来,不再贴图了。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Sql;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
/*程序主要功能:动态生成一棵树,新节点的值由其父节点和同一个链上的其他节点值相加得到,且树中不存在重复值
 *
 *
 */
namespace ShortestAddChain
{
    public partial class Form1 : Form
    {
        string conn = "Password=good;Persist Security Info=True;User ID=sa;Initial Catalog=addchain;Data Source=.";
        private Stopwatch stw = new Stopwatch();

        public Form1()
        {
            InitializeComponent();
        }

        int compare(string value1, string value2)
        {//比较两个数的大小,这两个数存储于string类型变量,且低位在前,高位在后,若value1大于value2返回1,小于返回-1,相等返回0
            if (value1.Length > value2.Length)
            {
                return 1;
            }
            else if (value1.Length < value2.Length)
            {
                return -1;
            }
            else
            {
                for (int i = value1.Length - 1; i >= 0; i--)
                {
                    if (value1[i] > value2[i])
                        return 1;
                    else if (value1[i] < value2[i])
                        return -1;
                }
                return 0;
            }
        }

        string addnumber(string value1, string value2)
        {//把两个整数相加,这两个整数都存储于string类型变量中,且低位在前,高位在后           
            string result = "";
            string temp;
            if (value1.Length < value2.Length)
            {//保证value1长度大于value2,或二者长度相等
                temp = value1;
                value1 = value2;
                value2 = temp;
            }
            int c = 0;//加法进位
            int i;
            for (i = 0; i < value2.Length; i++)
            {
                int t = value1[i] - '0' + value2[i] - '0' + c;
                result += (t % 10).ToString();
                c = t / 10;
            }
            while (i < value1.Length)
            {
                int t = value1[i] - '0' + c;
                result += (t % 10).ToString();
                c = t / 10;
                i++;
            }
            if (c != 0)
                result += (c % 10).ToString();
            return result;
        }

        private void output(Int32 position)
        {//输出最短加法链,其参数表示该节点在数据库中的记录号           

            Int32 j = position;
            string shortestaddchain = "";
            TBResult.Text = "The shortest addchain is:rn";
            int chainlength = 0;
            while (j >= 1)
            {
                string sql = "select reverse(nodevalue) as nodevalue,parentposition from addchaintable where id =" + j.ToString();
                SqlDataAdapter adapter = new SqlDataAdapter(sql, conn);
                DataSet ds = new DataSet();
                adapter.Fill(ds);
                DataTable dt = ds.Tables[0];

                shortestaddchain = "," + dt.Rows[0]["nodevalue"].ToString() + shortestaddchain;
                j = int.Parse(dt.Rows[0]["parentposition"].ToString());
                chainlength++;
                dt.Dispose();
                ds.Dispose();
                adapter.Dispose();
            }
            shortestaddchain = "1" + shortestaddchain;
            chainlength++;
            TBResult.Text += shortestaddchain;
            stw.Stop();
            TBResult.Text += "rnrnThe length of the addchain is " + chainlength.ToString();
            TBResult.Text += "rnrn" + "I have run for " + stw.Elapsed.Hours.ToString() + " Hours " + stw.Elapsed.Minutes.ToString() + " Minutes " + stw.Elapsed.Seconds.ToString() + " Seconds " + stw.Elapsed.Milliseconds.ToString() + " MilliSeconds";
            stw.Reset();
            return;
        }

        protected void DoSql(string sql)//执行sql语句
        {
            SqlConnection conn1 = new SqlConnection();//创建连接对象
            conn1.ConnectionString = conn.ToString();//给连接字符串赋值
            conn1.Open();//打开数据库
            SqlCommand cmd = new SqlCommand(sql, conn1);
            cmd.ExecuteNonQuery();//
            conn1.Close();//关闭数据库
        }
        private void BtnSearch_Click(object sender, EventArgs e)
        {
            stw.Start();
            if (TBNumber.Text.Trim() == string.Empty)
                return;
            for (int ii = 0; ii < TBNumber.Text.Length; ii++)
                if (TBNumber.Text[ii] < '0' || TBNumber.Text[ii] > '9')
                {
                    TBResult.Text = "Data Error!";
                    return;
                }

            string number = "";
            for (int ii = TBNumber.Text.ToString().Trim().Length - 1; ii >= 0; ii--)
                number += TBNumber.Text[ii];
            /*if (int.Parse(number) <= 0)
            {
                TBResult.Text = "Data Error!";
                return;
            }*/

            string sql = "select * from addchaintable where nodevalue='" + number.ToString() + "'";
            SqlDataAdapter adapter = new SqlDataAdapter(sql, conn);
            DataSet ds = new DataSet();
            adapter.Fill(ds);
            DataTable dt = ds.Tables[0];

            Int32 start, end;
            if (dt.Rows.Count > 0)
            {
                output(Int32.Parse(dt.Rows[0]["id"].ToString()));
                dt.Dispose();
                ds.Dispose();
                adapter.Dispose();
                return;
            }
            else
            {//数据库中尚未存储该节点的加法链,则先计算,然后输出它的最短加法链                   
                while (true)
                {
                    int hasfound = 0;//本次扩展时是否发现目标值
                    dt.Dispose();//释放资源
                    ds.Dispose();
                    adapter.Dispose();

                    string[] chain;
                    chain = new string[100];//存放start位置的节点所在的加法链
                    int c = 0;//当前加法链的大小
                    int level = 0;
                    sql = "select top 1 id,nodevalue,level from addchaintable where childcount = 0 order by id";
                    adapter = new SqlDataAdapter(sql, conn);
                    ds = new DataSet();
                    adapter.Fill(ds);
                    dt = ds.Tables[0];//重新从数据库中获取数据,获得start的值,即从此开始扩展树
                    start = Int32.Parse(dt.Rows[0]["id"].ToString());
                    level = Int32.Parse(dt.Rows[0]["level"].ToString());
                    //chain[c++] = dt.Rows[0]["nodevalue"].ToString();

                    sql = "select top 1 id from addchaintable order by id desc";
                    adapter = new SqlDataAdapter(sql, conn);
                    ds = new DataSet();
                    adapter.Fill(ds);
                    dt = ds.Tables[0];//重新从数据库中获取数据,获得start的值,即从此开始扩展树
                    end = Int32.Parse(dt.Rows[0]["id"].ToString());
                    Int32 j = start;
                    while (j > 0)
                    {
                        sql = "select nodevalue,parentposition from addchaintable where id =" + j.ToString();
                        adapter = new SqlDataAdapter(sql, conn);
                        ds = new DataSet();
                        adapter.Fill(ds);
                        dt = ds.Tables[0];
                        chain[c++] = dt.Rows[0]["nodevalue"].ToString();
                        j = Int32.Parse(dt.Rows[0]["parentposition"].ToString());
                    }
                    chain[c] = "1";

                    dt.Dispose();//释放资源
                    ds.Dispose();
                    adapter.Dispose();
                    int haschild = 0;
                    for (; c >= 0; c--)
                    {//将start位置的节点值与该加法链中前面的数值按从小到大的顺序相加
                        string testnumber = addnumber(chain[0].ToString(), chain[c].ToString());
                        SqlDataAdapter adaptersearch;
                        string sqlsearch = "select id from addchaintable where nodevalue='" + testnumber.ToString() + "'";
                        adaptersearch = new SqlDataAdapter(sqlsearch, conn);
                        DataSet dssearch = new DataSet();
                        adaptersearch.Fill(dssearch);
                        DataTable dtsearch = dssearch.Tables[0];
                        int found = dtsearch.Rows.Count;
                        dtsearch.Dispose();
                        dssearch.Dispose();
                        adaptersearch.Dispose();
                        if (found == 0)
                        {//树中尚无该节点值,则插入
                            end++;
                            string sqlinsert = "insert into addchaintable(id,level,nodevalue,parentposition,childcount) values('";
                            sqlinsert += end.ToString();
                            sqlinsert += "','";
                            sqlinsert += (level + 1).ToString();
                            sqlinsert += "','";
                            sqlinsert += testnumber.ToString();
                            sqlinsert += "','";
                            sqlinsert += start.ToString();
                            sqlinsert += "','0')";
                            DoSql(sqlinsert);
                            //更新父节点的子节点个数字段
                            haschild++;

                            if (compare(testnumber, number) == 0)
                            {
                                hasfound = end;
                            }
                        }
                    }
                    if (haschild == 0)
                    {//start位置上的节点没有子节点
                        string sqlupdate1 = "update addchaintable set childcount= -1 where id='" + start.ToString() + "'";
                        DoSql(sqlupdate1);
                    }
                    else
                    {
                        string sqlupdate1 = "update addchaintable set childcount= " + haschild.ToString() + " where id='" + start.ToString() + "'";
                        DoSql(sqlupdate1);
                    }

                    if (hasfound != 0)
                    {
                        output(hasfound);
                        dt.Dispose();//释放资源
                        ds.Dispose();
                        adapter.Dispose();
                        return;
                    }
                    Application.DoEvents();//若程序执行时间较长,可以响应其他事件
                }
            }
        }
    }
}

 

评论 (0) | 阅读 (88)

评论
    内容读取中…
发表评论

你还没有登录,现在登录

个人档案

内容读取中…

博客公告

内容读取中…

博客日历

内容读取中…

文章分类

内容读取中…

文章存档

    内容读取中…

最新发表

    内容读取中…

最新评论

内容读取中…

博主留言

内容读取中…

博主好友

内容读取中…

最新访客

内容读取中…

博客统计

    内容读取中…

友情链接

新闻订阅