每個不會編程的科研人員上輩子都是那啥的天使
上週五的時候小蛇蛇青在GT里淚流滿面表示他老闆要他處理一份包含了一萬五千條數據的表格,需要把每一條數據和整個表格其他所有數據進行比對。我驚異地問:你就打算這麼肉眼篩選么……!他默默表示是這樣的。我在OTZ的同時決定幫他寫一個篩選器。
其實這是一個無比簡單的程序,就是獲取Excel文件,獲取需要比較的Columns,然後再遍歷一次Excel,排除當前行進行一一對比,然後把符合條件的數據存到DataTable中。青需要的篩選條件如下:當D單元格和N單元格的差值不等於500的時候,比較D和D(i),以及N和N(i)。當兩個數據的差值都小於500的時候,即是符合條件的數據。
初期我算法如下:
for (int i = 0; i < sheet.Rows.Count - 1; i++) for (int j = 0; j < sheet.Rows.Count - 1; j++) int D = Math.Abs(D2 - D1); if (D < 500 && N < 500 && Math.Abs(D1 - N1) != 500)
{
int D1 = int.Parse(sheet[i + 1, 3].Value.ToString());
int N1 = int.Parse(sheet[i + 1, 13].Value.ToString());
{
int D2 = int.Parse(sheet[j + 1, 3].Value.ToString());
int N2 = int.Parse(sheet[j + 1, 13].Value.ToString());
int N = Math.Abs(N2 - N1);
{
DataRow dr = dt.NewRow();
//寫入該行的數據
dt.Rows.Add(dr);
}
}
}
可以看到,這段代碼絕對是很坑爹的。首先就是i和j都遍歷了整個Excel,但是沒有排除i=j的情況,那麼必然存在D-N!=500,然後因為i=j所以Di-Dj=0,Ni-Nj=0。接著就輸出數據了這樣坑爹的結果……
最後執行這個程序,運算出來的結果大概是200萬條……無限坑爹……於是青淚流滿面地去肉眼篩選去了。
第二天我們繼續討論這段代碼。我設計了一個逆序遍歷的思路,也就是加了這一句:
可是這樣的算法還是有問題,j拋棄(0-i)這一段,不符合要求,放棄。
我向青描述了我的算法構思,描述的過程中突然醒悟:之前設計的代碼,只要符合篩選條件,就會輸出一行i的數據。但是在Excel中,數據並不是唯一匹配的。所以無怪乎之前會輸出200萬條數據了。
因此,在執行i和j比較的循環的時候,只要有符合條件的輸出執行一次之後,應該立刻break這個循環,開始下一條循環。這時候青表示之前的篩選條件說漏了。他需要的篩選條件是:當C的值相當,也就是屬於同一條染色體的時候,才進行數據篩選。這時候首先進行Di-Ni!=500的判斷。然後進行ABS(Di-Dj)<500 && ABS(Ni-Nj)<500的篩選。之後,再追加一次ABS(Di-Nj)<500 && ABS(Ni-Dj)<500的篩選。
最終算法代碼如下:
{
string C1 = sheet[i + 1, 2].Value.ToString();
int D1 = Math.Abs(int.Parse(sheet[i + 1, 3].Value.ToString()));
int N1 = Math.Abs(int.Parse(sheet[i + 1, 13].Value.ToString()));
if (Math.Abs(D1 - N1) != 500)
{
//for (int j = sheet.Rows.Count; (i + 2) < j; j--)
for (int j = 0; j < sheet.Rows.Count - 1; j++)
{
if (i != j)
{
string C2 = sheet[j + 1, 2].Value.ToString();
int D2 = Math.Abs(int.Parse(sheet[j + 1, 3].Value.ToString()));
int N2 = Math.Abs(int.Parse(sheet[j + 1, 13].Value.ToString()));
int D = Math.Abs(D2 - D1);
int N = Math.Abs(N2 - N1);
int A = Math.Abs(D2 - N1);
int B = Math.Abs(N2 - D1);
if (C1 == C2)
{
if (D < 500 && N < 500)
{
DataRow dr = dt.NewRow();
//輸出
dt.Rows.Add(dr);
break;
}
else
{
if (A < 500 && B < 500)
{
DataRow dr = dt.NewRow();
//輸出
dt.Rows.Add(dr);
break;
}
}
}
}
}
}
}
最後篩選了9000多條數據出來,經過青的肉眼檢查唔錯。他淚目表示:看著順眼多了……
哎,不會編程的科研人員上輩子都是那啥的天使……這種實驗對於青來說要做多少次……這數據要處理多少條……據他說他老闆一直是肉眼處理數據的……這,這得有多強大的耐心才能搞定啊OTZ!
順帶表示,我覺得我這個算法效率太低了,我相信一定有更佳的算法,希望高手能指教我一下XD。
看来学点编程还是很有用的嗯嗯= =
要是肉眼筛选的话我该有什么感想啊= =要不螃蟹你还是把这个程序留着我相信可以帮助很多这样受苦的那啥天使嗯嗯.
不过我表示我仍然不怎么看得懂你的新程序
这程序以后也可以给天使青用,嗯。我拿来练手XD。
不过我觉得这个程序不难啊- -纯属展示算法而已……就是两个for,然后if判断
默默围观西皮共同努力,向夕阳奔跑神马的太萌了TUT
顺便15000条居然还能拣出9000多条……这数据量也太OX了吧OTZ
另,蕾蕾你在技术宅的康庄大道上越跑越远了口牙~拍肩!
咝咝说数据没啥问题- -咝咝才是最强的,肉眼处理了7000条数据……
是15000条,因为我最后把所有数据都肉眼过了一遍……
顺带表示,最强的是老板啊,肉眼几十万条数据啊!
你们都太强了,服气了……
肉眼滤真是太囧了= =这纯粹就是锻炼眼力和耐心的综合方法= =
不愧是真!科学怪蛇及科学怪蛇!师傅……深深地觉得我真是个实诚的平凡人啊TUT
= =明明是煽情文艺神出鬼没概
所以才是那啥的天使的嘛
嗯,还是谢谢你的程序……不过我决定以后还是用excel来计算好了= =
一个是因为调试过程太OTZ了,感觉比我肉眼筛还累……坑爹啊!
还有一个就是,我想了一个excel算法来做,这样做起来还蛮方便的,我花了一个下午就把这堆数据搞定了,包括程序结果里不能包含的数据归类部分= =,感觉效率还不错……
肉眼滤什么的太恐怖了……
要不怎么说就是学程序的呢。
?不明……
不一样的天使
不要告诉我你不会 嘿嘿 下次帮我也练下手
其实我周六还是周日有想mark你来讨论一下这个东西的……结果被无情拒绝了T T
拒绝? 无情的拒绝 从何说起了 我有点糊涂了
你留言用的是QQ邮箱嘛,邮箱本身就是QQ号……恩,那啥……
默默问下雷叔,这是拿什么写的?C么?貌似又不大像……有点点像VB,但显然绝对不是。DynamicC?
c#