本人帮朋友写个小程序,我有一个朋友用的软件可以生成文本文件
文本文件格式如下货单编号1
货单编号2
货单编号3
....也就是在文本文件txt里,一行一条货单编号
他要我写个程序帮他分析出货单编号有相同的数据
我已经实现该功能,但是代码效率极低,上1万条数据就开始非常慢了,要是需要处理10万条数据以上,也许根本读不出来!
所以在这里跪求高手解决,最好是帮帮我改改代码,谢谢以下是我写的代码
代码编写环境是vs2003,再次谢谢``````````!

解决方案 »

  1.   

    塞到数据库里去distinct,不过估计也不会快,但是也许比你自己做快一些
      

  2.   

    例子
    Select 票号 From Table_Name Group By 票号 Having Count(*) > 1
      

  3.   

    数据库里肯定会快一点
    写txt的话
    我想我会用 冒泡法进行循环处理
      

  4.   

    用一个数组. 假设编号最大为500000;
     int[] ss=new int[500000]; 
     for( 每一行)
     {
       int i= 该行编号;
       ss[i]++;
       if(ss[i]>1) i的编号有ss[i]个;
    }
      

  5.   

    没有看到你的源代码在哪里.....
    据我的理解,一般做法应该是一行一行的读出来,然后与一个集合中已保存的数据比较,看看是否重复,重复的就进行标记。
    这里的瓶颈应该在数据的读取和比较上,就我所了解的,用Hashtable来进行比较是否重复是一个不错的选择。
      

  6.   

    我有个想法,如果你的帐单是按从小到大的顺序排列的话(就象你给的例子那样)
    复制帐单的TXT文件为T2 ,原始为T1, 定义记录为R, 定义count[,]为保存重复了多少的记数第一唯是重复的号码.第二维是重复数目;
    int i = 1;
    while(T1.R !=NULL)
    (
      if(T2.R 不大于 T1.R)  //当第二个文件的记录没有大过第一个文件时
      {
        if(count[i-1,0]==T2.R) //判断之前的放进重复数组里的数与即将要进入的数是不是同一个.如果同一个就在前面的记数
         {                         列中加1就不可拉.不比新开一行来记录
           count[i-1,1] += 1; 
         }
        else
         {
           count[i,0] = T2.R;
           count[i,1] = 1;
         }
       }
     }
    再判断第一个树和最后一个数分别有没重复.
    然后就读取COUNT里面的数据
    如COUT[1,3] 就等于帐单1重复3+1次.
    假设 第一列   第二列
         1        2
        2        2
        2        3
        3        4
        4        5
        5        5
        5        5
        5        6
         6       7
        7        7
        7        8
        8        
    可以得到COUNT[2,1] [5,2]  [7,1] 所以是2重复2次.5重复3次.7重复2次.
      

  7.   

    上面还漏了些东西.这里补充下
    int   i   =   1; 
    while(T1.R.readnext !=null) 

        if(T2.R   不大于   T1.R)     //当第二个文件的记录没有大过第一个文件时 
        { 
            if(count[i-1,0]==T2.R)   //判断之前的放进重复数组里的数与即将要进入的数是不是同一个.如果同一个就在前面的记数 
              {                                                   列中加1就不可拉.不比新开一行来记录 
                  count[i-1,1]   +=   1; 
                i--; 
              } 
            else 
              { 
                  count[i,0]   =   T2.R; 
                  count[i,1]   =   1; 
              } 
              i++;
          } 
      } 
    再判断第一个树和最后一个数分别有没重复. 
    然后就读取COUNT里面的数据 
    如COUT[1,3]   就等于帐单1重复3+1次. 
    假设   第一列       第二列 
              1                 2 
            2                 2 
            2                 3 
            3                 4 
            4                 5 
            5                 5 
            5                 5 
            5                 6 
              6               7 
            7                 7 
            7                 8 
            8                 
    可以得到COUNT[2,1]   [5,2]     [7,1]   所以是2重复2次.5重复3次.7重复2次. 
      

  8.   


    private void button1_Click(object sender, System.EventArgs e)

    以下是代码

                       this.progressBar1.Maximum=richTextBox1.Lines.Length-1;//最大值为1,也就是总值不减1也许不准
    label3.Text="数据分析中....";
    for(int i=0;i<richTextBox1.Lines.Length;i++)
    {



         if(this.richTextBox2.Text.ToString().IndexOf(richTextBox1.Lines.GetValue(i).ToString())==-1)//等于负1,表示指针还在开始的地方,没有移动过,就是没有相同的数据,所以进行保存
         {
    this.richTextBox2.Text=this.richTextBox2.Text+richTextBox1.Lines.GetValue(i).ToString()+"\n" ;

         }

    this.progressBar1.Value=i;
    }
    label2.Text="得到:"+Convert.ToString(richTextBox2.Lines.Length-1)+"条";
    label3.Text="分析完毕";
    MessageBox.Show("分析完毕!");
    } /// <summary>
    /// 打开方件
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void button2_Click(object sender, System.EventArgs e)// 文件打开的方法。
    {
    openFileDialog1.Filter = "文本文件(*.txt)|*.txt";
    openFileDialog1.Title = "打开要分析的文件。"; if(openFileDialog1.ShowDialog() == DialogResult.OK)
    {
    System.IO.StreamReader sr = new
    System.IO.StreamReader(openFileDialog1.FileName);
    this.richTextBox1.Text = sr.ReadToEnd();
    sr.Close();
    }
    label1.Text="共:"+richTextBox1.Lines.Length.ToString()+"条数据";
    } private void button3_Click(object sender, System.EventArgs e)
    {
    saveFileDialog1.Filter = "文本文件(*.txt)|*.txt";
    saveFileDialog1.Title = "保存分析结果.";
    if(saveFileDialog1.ShowDialog() == DialogResult.OK)
    { FileStream  fs  =  new  FileStream  (saveFileDialog1.FileName,FileMode.OpenOrCreate,FileAccess.Write);
    StreamWriter  m_streamWriter  =  new  StreamWriter  (fs)  ;
    m_streamWriter.Flush ()  ;
    //  使用StreamWriter来往文件中写入内容
    m_streamWriter.BaseStream.Seek  ( 0,SeekOrigin.Begin  )  ;
    //  把richTextBox1中的内容写入文件
    m_streamWriter.Write  (richTextBox2.Text.Replace("\n",Environment.NewLine)) ;//把\n字符替换成换新建一行的属性Environment.NewLine
    //关闭此文件
    m_streamWriter.Flush  ()  ;
    m_streamWriter.Close  ()  ;
        
    }
    }我用了两个richTextBox控件保存
    然后以上是三个按纽的操作```
      

  9.   

    数据的办法我也想过,但是如果10万条数据,插入数据库的时候效率高吗?
    我怕到时候也会很慢

    冒泡算法,用来排序,但是用来对比数据,还没用过
    nealbox 
    大哥可以帮我写写吗?
    eversammi 
    是没有从小到大的规律的
    bruesz  
    Hashtable这种办法怎么实现呢?再次谢过所以回贴的大哥`````````
    小弟在这里感谢了```````````````
      

  10.   

    下面是可以用的代码.1000条不用2秒.10000条就要用线程来做.不然会死机.
    但是那个做法除了一开时用了大数值循环插入数据外.
    在真正比较的时候才一个FOR语句. 应该比较省时才对的啊.
    代码可运行.里面有个按钮,一个RICHTEXTBOX要自己加.哈哈
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Net;
    using System.Text;
    using System.Collections;
    using System.Text.RegularExpressions;
    using System.Windows.Forms;namespace GetIP
    {
        public partial class Form1 : Form
        {
            int[] T1 = new int[1000];
            int[] T2 = new int[1000];
            int[,] Result = new int[1000, 2];
            public Form1()
            {
                InitializeComponent();
            }        private void button1_Click(object sender, EventArgs e)
            {            ShowResult();
            }
     /*       public void GetIP()
            {
                WebClient client = new WebClient();
                byte[] bytRecv = client.DownloadData("http://www.ip138.com/"); //下載數據
                richTextBox1.Text = Encoding.ASCII.GetString(bytRecv);
                string str = System.Text.Encoding.GetEncoding("gb2312").GetString(bytRecv);
                string r = @"(((\d{1,3})|(1\d{2})|(2[0-4]\d)|(25[0-5]))\.){3}((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5]))";
                string ip = Regex.Match(str, r).ToString();    //提取信息
                MessageBox.Show(ip);
                //return IPAddress.Parse(ip);
            }*/
            public void FillData()
            {
                int temp = 0;
                for (int i = 0; i < 1000; i++)
                {
                    if (i % 6 == 3||i % 6 == 2)
                    {
                        temp = temp-1;
                    }
                    T1[i] = temp;
                    temp++;
                }
                CountData();
            }
            public void CheckT2()//测试并查看数据
            {
                T2 = T1;
                for (int k = 0; k < T2.GetLength(0); k++)
                {
                    richTextBox1.Text += T2[k].ToString()+ "次\n";
                }
                richTextBox1.Text += T2.GetLongLength(0).ToString();
            }        public void CountData()
            {
                T2 = T1;
                //int i = 0;
                int j = 1;
                for(int a = 0;a<T2.GetLength(0)-1;a++)
                {
                    if (T2[a + 1].ToString()!=null)
                    {
                        if (T2[a + 1] <= T1[a])
                        {
                            if (Result[j - 1, 0] == T2[a + 1])//判断当前要进入的编号是否已存在
                            {
                                Result[j-1, 1]++;             //如果存在,只需在原来基础上+1;
                                                         //把J--以便下个记录紧接着当前记录;
                            }
                            else
                            {
                                Result[j, 0] = T2[a];        //如果当前要进入的记录不存在,则添加.
                                Result[j, 1] = 2;
                                j++;
                            }
                        }
                        
                        
                    }
                }
                
            }
            /// <summary>
            /// 创建一个线程去算.
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void Form1_Load(object sender, EventArgs e)
            {
                System.Threading.Thread n = new System.Threading.Thread(new System.Threading.ThreadStart(FillData));
                n.Start();
            }
            private void ShowResult()
            {
                for (int k = 1; k < Result.GetUpperBound(0); k++)//打印出来看结果
                {
                    richTextBox1.Text += Result[k, 0].ToString() + " 重复" + Result[k, 1] + "次\n";
                }
            }    }
    }
      

  11.   

    没那么麻烦吧?        int[] num = new int[10] { 4, 3, 4, 6, 2, 3, 1, 5, 3, 3 };
            int[] check = new int[10] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };        public string Rnum()
            {
                string str = "";
                for (int i = 0; i < 9; i++)
                {
                    for (int j = 8; j >= i; j--)
                    {
                        if (num[j + 1] <= num[j])
                        {
                            int usenum = num[j + 1];
                            num[j + 1] = num[j];
                            num[j] = usenum;
                            usenum = check[j+1];
                            check[j+1] = check[j];
                            check[j] = usenum;
                            if (num[j + 1] == num[j])
                            {
                                check[j] += check[j + 1];
                                check[j + 1] = 0;
                            }
                        }
                        if (j == i && j > 0 && num[j - 1] == num[j])
                        {
                            check[j] = check[j - 1];
                        }
                    }
                }
                for (int i = 0; i < 10; i++)
                {
                    str += num[i] + ";" + check[i] + "\n";
                }
                return str;
            }
    这个是直接输出..
      

  12.   

    这个是测试10W条记录的.2秒就可以输出了.using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Net;
    using System.Text;
    using System.Collections;
    using System.Text.RegularExpressions;
    using System.Windows.Forms;namespace GetIP
    {
        public partial class Form1 : Form
        {
            int[] T1 = new int[100000];
            int[] T2 = new int[100000];
            int[,] Result = new int[10000,2];
            System.Threading.Thread n;
            public Form1()
            {
                InitializeComponent();
            }        private void button1_Click(object sender, EventArgs e)
            {
                n.Abort();
                CountData();
                ShowResult();
            }
     /*       public void GetIP()
            {
                WebClient client = new WebClient();
                byte[] bytRecv = client.DownloadData("http://www.ip138.com/"); //下載數據
                richTextBox1.Text = Encoding.ASCII.GetString(bytRecv);
                string str = System.Text.Encoding.GetEncoding("gb2312").GetString(bytRecv);
                string r = @"(((\d{1,3})|(1\d{2})|(2[0-4]\d)|(25[0-5]))\.){3}((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5]))";
                string ip = Regex.Match(str, r).ToString();    //提取信息
                MessageBox.Show(ip);
                //return IPAddress.Parse(ip);
            }*/
            public void FillData()
            {
                int temp = 0;
                for (int i = 0; i < 100000; i++)
                {
                    if (i % 23 == 3||i % 23 == 2)
                    {
                        temp = temp-1;
                    }
                    T1[i] = temp;
                    temp++;
                }
                T2 = T1;
                
            }
            public void CheckT2()//测试并查看数据
            {
                
                /*for (int k = 0; k < T2.GetLength(0); k++)
                {
                    richTextBox1.Text += T2[k].ToString()+ "次\n";
                }*/
                richTextBox1.Text += T2.GetLongLength(0).ToString();
            }        public void CountData()
            {
                T2 = T1;
                //int i = 0;
                int j = 1;
                for(int a = 0;a<T2.GetLength(0)-1;a++)
                {
                    if (T2[a + 1].ToString()!=null)
                    {
                        if (T2[a + 1] <= T1[a])
                        {
                            if (Result[j - 1, 0] == T2[a + 1])//判断当前要进入的编号是否已存在
                            {
                                Result[j-1, 1]++;             //如果存在,只需在原来基础上+1;
                                                         //把J--以便下个记录紧接着当前记录;
                            }
                            else
                            {
                                
                                Result[j, 0] = T2[a];        //如果当前要进入的记录不存在,则添加.
                                Result[j, 1] = 2;
                                j++;
                            }
                        }
                        
                        
                    }
                }
                
            }
            /// <summary>
            /// 创建一个线程去算.
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void Form1_Load(object sender, EventArgs e)
            {
                n = new System.Threading.Thread(new System.Threading.ThreadStart(FillData));
                n.Start();
            }
            private void ShowResult()
            {
                string temp2 ="";
                for (int k = 1; k < Result.GetUpperBound(0); k++)//打印出来看结果
                {
                    temp2 += Result[k, 0].ToString() + " 重复" + Result[k, 1] + "次\n";
                }
                richTextBox1.Text = temp2;
            }    }
    }
      

  13.   


    //代码如下:
    //1、先随机生成1000000行货单号,并写到文件list.txt中。
    //2、将生成的list.txt读入hashtable中,我用货单号当作Hashtable的key,该货单号的个数作为value,
    //如果是第一次读到某个货单号将该货单号的个数置为1,如果已存在该货单号,则将货单号个数加1.
    //3、最后将统计结果输出到res.txt中,格式为:货单号,个数。
    //100万条记录从创建文件到统计出结果,并将结果写入文件总共也只需4秒,其中通过hashtable进行查找由系统提供应该是比较快的。using System;
    using System.Collections.Generic;
    using System.Text;
    using System.IO;
    using System.Collections;
    namespace ConsoleApp
    {
        class Program
        {
            static void Main(string[] args)
            {
                DateTime startTime = DateTime.Now;
                Console.WriteLine("开始时间:" + startTime);
                Random rd = new Random();
                Byte[] b = new Byte[6];
                using (StreamWriter sw = new StreamWriter("list.txt"))
                {
                    for (int i = 1; i <= 1000000; i++)
                    {
                        sw.WriteLine(rd.Next(10000,99999));
                    }
                }            Hashtable ht = new Hashtable();
                using (StreamReader sr = new StreamReader("list.txt"))
                {
                    while (!sr.EndOfStream)
                    {
                        string line = sr.ReadLine();
                        if (ht[line] == null)
                        {
                            ht.Add(line, 1);
                        }
                        else
                        {
                            ht[line] = int.Parse(ht[line].ToString()) + 1;
                        }
                    }
                }            using (StreamWriter sw = new StreamWriter("res.txt"))
                {
                    //ICollection keys = ht.Keys;
                    foreach (DictionaryEntry de in ht)
                    {
                        sw.WriteLine("{0},{1}",de.Key,de.Value);
                    }
                }
                DateTime endTime = DateTime.Now;
                TimeSpan ts1 = new TimeSpan(startTime.Ticks);
                TimeSpan ts2 = new TimeSpan(endTime.Ticks);
                
                Console.WriteLine("结束时间:" + endTime);
                Console.WriteLine("共历时:"+ts2.Subtract(ts1).Seconds+"秒");
                Console.ReadKey();
            }
        }
    }
      

  14.   

    本人计算机配置 Celeron 1.5G  RAM 256+512M
      

  15.   

    5楼说的没错,取每个字符串的HASH值,毕竟是32位数字,比较起来比字符串快多了,如果两个HASH值相等,再比较两个字符串是否相等就行了,如果有现成的字典类可用就更快了,可以进一步用空间换时间。
      

  16.   

    eversammi 大哥,你能把代码写完整吗?
    我运行不了,控件我也加了````````