2016-05-11 32 views
0

我在考虑以下问题。垂直分割一个数组,所以我们得到最小分割

我可以有一个字符串像

Col1 Col2 Col3 Col4 
aa  aa  aa  aa 
aaa aaa  aaaaa aaa 
aaaa aaaaaaa aa  a 
........................... 

数组其实这是CSV文件。我应该找到一种方法将它垂直分割成一个或多个文件。分裂的条件是没有一个文件不包含超过某些字节的行。为简单起见,我们可以重写数组的长度:

Col1 Col2 Col3 Col4 
2  2  2  2 
3  3  5  3 
4  7  2  1 
........................... 

而且我们说的限值是10,即如果> 9我们应该分开。所以如果我们分成两个文件[Col1, Col2, Col3][Col4]这将不会满足条件,因为第一行文件的第二行将包含3 + 3 + 5 > 9,第三行包含4 + 7 + 2 > 9。如果我们分成[Col1, Col2][Col3, Col4]这将不会满足条件,因为第一个文件将包含第三行中的4 + 7 > 9。所以我们把它分成3个文件,如[Col1],[Col2, Col3][Col4]。现在每个文件是正确的,看起来像:

File1 | File2   | File3 
------------------------------ 
Col1 | Col2 Col3 | Col4 
2  | 2  2  | 2  
3  | 3  5  | 3  
4  | 7  2  | 1  
............................... 

所以应该拆分从左至右给出的最大列数尽量向左文件。问题是这个文件可能很大,我不想将它读入内存,所以我们逐行读取最初的文件,并以某种方式确定一组要分割的索引。如果这是可能的呢?我希望我能很好地描述这个问题,这样你就能理解它。

+0

列可以交换? –

+0

有多少列和行? –

+0

最多2,500列,最多10,000行。将来可能会更多。列不能交换,移动等。 –

回答

0

通常awk在处理大型csv文件方面非常出色。

您可以尝试类似this的方法来检索每列的最大长度,然后决定如何拆分。

比方说,file.txt的包含

Col1;Col2;Col3;Col4 
aa;aa;aa;aa 
aaa;aaa;aaaaa;aaa 
aaaa;aaaaaaa;aa;a 

(假设windows风格引号)运行以下:

> awk -F";" "NR>1{for (i=1; i<=NF; i++) max[i]=(length($i)>max[i]?length($i):max[i])} END {for (i=1; i<=NF; i++) printf \"%d%s\", max[i], (i==NF?RS:FS)}" file.txt 

将输出:

4;7;5;3 

难道你试试这个你的真实数据集?

+0

只有每列的最大值不能找到最佳解决方案。 –

+0

这是什么给我?我不能从'4; 7; 5; 3'做出决定,我可以吗? –

+0

4; 7; 5; 3告诉你,你可以合并列1和3,因为'4 + 5 <= 9' 然后你解决9; 7; 3你不能根据你的规则减少所以三个文件:(1 ; 3)(2)(4)。 – hoang