本人帮朋友写个小程序,我有一个朋友用的软件可以生成文本文件
文本文件格式如下货单编号1
货单编号2
货单编号3
....也就是在文本文件txt里,一行一条货单编号
他要我写个程序帮他分析出货单编号有相同的数据
我已经实现该功能,但是代码效率极低,上1万条数据就开始非常慢了,要是需要处理10万条数据以上,也许根本读不出来!
所以在这里跪求高手解决,最好是帮帮我改改代码,谢谢以下是我写的代码
代码编写环境是vs2003,再次谢谢``````````!
文本文件格式如下货单编号1
货单编号2
货单编号3
....也就是在文本文件txt里,一行一条货单编号
他要我写个程序帮他分析出货单编号有相同的数据
我已经实现该功能,但是代码效率极低,上1万条数据就开始非常慢了,要是需要处理10万条数据以上,也许根本读不出来!
所以在这里跪求高手解决,最好是帮帮我改改代码,谢谢以下是我写的代码
代码编写环境是vs2003,再次谢谢``````````!
Select 票号 From Table_Name Group By 票号 Having Count(*) > 1
写txt的话
我想我会用 冒泡法进行循环处理
int[] ss=new int[500000];
for( 每一行)
{
int i= 该行编号;
ss[i]++;
if(ss[i]>1) i的编号有ss[i]个;
}
据我的理解,一般做法应该是一行一行的读出来,然后与一个集合中已保存的数据比较,看看是否重复,重复的就进行标记。
这里的瓶颈应该在数据的读取和比较上,就我所了解的,用Hashtable来进行比较是否重复是一个不错的选择。
复制帐单的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次.
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次.
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控件保存
然后以上是三个按纽的操作```
我怕到时候也会很慢
,
冒泡算法,用来排序,但是用来对比数据,还没用过
nealbox
大哥可以帮我写写吗?
eversammi
是没有从小到大的规律的
bruesz
Hashtable这种办法怎么实现呢?再次谢过所以回贴的大哥`````````
小弟在这里感谢了```````````````
但是那个做法除了一开时用了大数值循环插入数据外.
在真正比较的时候才一个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";
}
} }
}
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;
}
这个是直接输出..
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;
} }
}
//代码如下:
//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();
}
}
}
我运行不了,控件我也加了````````