有这样一个TXT文件,文件名为DATA.TXT,TXT里是一个用空格分离的数组数据,具体入如下:758 766 775 786 798 810
727 733 742 753 -999 780
697 703 712 723 737 752
675 -999 689 701 715 730
660 667 676 687 699 713
652 659 -999 677 688 700
-999 655 663 672 682 692
646 654 -999 670 679 689
645 652 659 666 674 683
652 -999 666 671 -999 684
677 687 694 698 701 704
711 721 727 730 731 732
742 748 752 -999 755 757读取数据,当遇到-999这个数值的时候,求-999上下左右数据的平均值,并将此值覆盖-999,然后输出到一个新的TXT文件中。
如何实现?小弟是C#新手,望高手指点!!非常感谢!!!
727 733 742 753 -999 780
697 703 712 723 737 752
675 -999 689 701 715 730
660 667 676 687 699 713
652 659 -999 677 688 700
-999 655 663 672 682 692
646 654 -999 670 679 689
645 652 659 666 674 683
652 -999 666 671 -999 684
677 687 694 698 701 704
711 721 727 730 731 732
742 748 752 -999 755 757读取数据,当遇到-999这个数值的时候,求-999上下左右数据的平均值,并将此值覆盖-999,然后输出到一个新的TXT文件中。
如何实现?小弟是C#新手,望高手指点!!非常感谢!!!
然后遍历就OK了
1.声明string model[,]数组2.引用IO包,实例FileStream fs(=new FileStream(path,FileModel.Open))
3.实例StreamReader sr(=new StreamReader(fs))4.(while sr.peek()!=-1) sr.ReadLine(); split方法用" "分解字符串,赋给model[0],第二行赋给model[1],依次类推.
5.嵌套循环遍历数组(i表示行,j表示列),
if(model[i][j].Equals("-999"))
{
model[i][j]=""+( (model[i-1][j] as int) + (model[i+1][j] as int)+(model[i][j-1] as int)+(model[i][j+1] as int) )/4;6.实例StreamWriter sw(=new StreamWriter(fs))
7.嵌套循环每行写入 sw.WriteLine("line");8关闭资源sw.Close(),sr.Close(),fs.Close();
strconn += filepath; //filepath, for example: c:\
strconn += ";extensions=asc,csv,tab,txt;" ;
OdbcConnection objconn = new OdbcConnection(strconn);
DataSet dscsv = new DataSet();
try
{
string strsql = "select * from " + filename; //filename, for example: 1.csv
OdbcDataAdapter odbccsvdataadapter = new OdbcDataAdapter(strsql,objconn);
odbccsvdataadapter.Fill(dscsv);
return dscsv;
}
catch(Exception ex)
{
throw ex;
}
} 呵呵,你首先明白你的文件实际是个csv文件,然后你知道csv文件是可以用oledb方式直接读到dataset滴,最后你知道dataset是可以用sum,Aver等函数滴
ok,代码不详细写了,你明白要干啥了,自己写吧!做程序员还是不用太偷懒滴好
循环,找到-999 就把[i-i][j], [i+1][j],[i][j+1],[i][j-1] (如果存在的话) 相加/4 最后在写回文件.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;namespace AverageFile
{
class Program
{
static void Main(string[] args)
{
List<int[]> datas = new List<int[]>();
using (StreamReader sr = File.OpenText(@"E:\desktop\dt.txt"))
{
#region 读入数据 while (true)
{
string currentLine = sr.ReadLine();
if (currentLine == null) break;
string[] strDatas = currentLine.Split(' '); List<int> intDatas = new List<int>();
foreach (var s in strDatas)
{
int cd;
if (Int32.TryParse(s, out cd))
{
intDatas.Add(cd);
}
}
datas.Add(intDatas.ToArray());
} #endregion for (int i = 0; i < datas.Count; i++)
{
int[] lineData = datas[i];
for (int j = 0; j < lineData.Length; j++)
{
if (lineData[j] == -999)
{
#region 求平均值
int up, down, left, right;
if (i <= 0)
{
up = 0; //第一行无上边值
}
else
{
up = datas[i - 1][j];
} if (i >= datas.Count - 1)
{
down = 0; //最后一行无下边值
}
else
{
down = datas[i + 1][j];
} if (j <= 0)
{
left = 0;
}
else
{
left = lineData[j - 1];
} if (j >= lineData.Length - 1)
{
right = 0;
}
else
{
right = lineData[j + 1];
} lineData[j] = (up + down + left + right) / 4; #endregion
}
}
} output(datas);
Console.ReadKey();
} } static void output(List<int[]> datas)
{
using (StreamWriter wr = File.CreateText(@"E:\desktop\dt2.txt"))
{
for (int i = 0; i < datas.Count; i++)
{
int[] lineData = datas[i];
for (int j = 0; j < lineData.Length; j++)
{
wr.Write(lineData[j] + " ");
Console.Write(lineData[j] + " ");
}
wr.Write("\n");
Console.Write("\n");
}
}
}
}
}
1:算法没有经过优化,如果:
*你需要经常计算这个结果
*文件特别长
则你肯定需要再次优化,我只是勉强得出结果。
2:算法还有一个问题,这个问题与你的定义不完整有关。
如果在它的上下左右这4个方向又出现了-999应当如何处理?
我目前的处理方法是以从上到下,从左到右的优先顺序处理的,即先处理先遇到的-999,而把后面的-999当成一个正常数据处理,而再次处理到这个-999时,则它可以读取上面的数据了。3:程序至少没有对一种可能产生的异常进行处理。
即如果每一行的数据个数不相等,不管是由于何种原因产生的,并且在多出来的位置上有-999则会有错误,例如:
1 2 3
4 5 6 -999
当读取到这个-999时,会由于读取不到3后面那个位置的up数据,会产生IndexOutOfRange这样的异常,你可以自行处理。
strconn += filepath; //filepath, for example: c:\
strconn += ";extensions=asc,csv,tab,txt;" ;
OdbcConnection objconn = new OdbcConnection(strconn);
DataSet dscsv = new DataSet();
try
{
string strsql = "select * from " + filename; //filename, for example: 1.csv
OdbcDataAdapter odbccsvdataadapter = new OdbcDataAdapter(strsql,objconn);
odbccsvdataadapter.Fill(dscsv);
return dscsv;
}
catch(Exception ex)
{
throw ex;
}
}
定义为int[][]因为赋值方便
我简单的
string[] line = File.ReadAllLines("e:\\data.txt");
int[][] data = new int[line.Length][];
for (int i = 0; i < line.Length; i++) data[i] = Array.ConvertAll<string, int>(line[i].Trim().Split(' '), Convert.ToInt32); //从文件中读取数据并放到数组中
就把文件转成数组了.你定义为 int[,]的如何写代码赋值?
不规则的出现?那么这个计算方法应该是由你定义啊?别人怎么知道你的逻辑是什么样的呢。至于如何处理这个还是比较简单的,你在搜索-999时不进行替换,只是把位置信息(X,Y)坐标记录到另外一个LIST当中,然后根据你的处理规则(说穿 了就是按什么顺序处理)处理这些LIST里的平均值填入即可。另外如果你的处理逻辑比较简单,你也可以修改循环,改变遍历的顺序。比如:我的是按从上到下从左路至右的顺序,如果你是要反过来的,你就可以修改一下循环实现,省去记录后再处理这么麻烦。
在做一个等值线绘制图像~GIS的东西~