【问题标题】:Vertically divide an array so we get minimum splits垂直分割一个数组,这样我们得到最小的分割
【发布时间】:2016-05-11 18:13:29
【问题描述】:

我正在考虑以下问题。

我可以有一个字符串数组,比如

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    
...............................

所以它应该从左到右拆分,为左侧文件提供尽可能多的列。问题是这个文件可能很大,我不想将它读入内存,所以我们逐行读取初始文件,我应该以某种方式确定一组要拆分的索引。如果这有可能吗?我希望我把问题描述得很好,所以你能理解它。

【问题讨论】:

  • 列可以交换吗?
  • 有多少列,多少行?
  • 最多 2,500 列和最多 10,000 行。未来可能会更多。列不能交换、移动等。

标签: algorithm


【解决方案1】:

通常 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

你能在你的真实数据集上试试这个吗?

【讨论】:

  • 只有每列的最大值才能找到最佳解决方案。
  • 这给了我什么?我无法通过4;7;5;3 做出决定,可以吗?
  • 4;7;5;3 告诉您可以合并第 1 列和第 3 列,因为 4+5&lt;=9 然后您解决了 9;7;3 问题,您无法根据您的规则减少三个文件:( 1;3)(2)(4).
  • 知道您可以使用 awk 拆分文件:awk "{print $1 $3}" file_1.txt; awk "{print $2}" file_2.txt; awk "{print $4}" file_3.txt
  • 在OP示例中,每列的最大值不在同一行,他的解决方案实际上是不同的。
猜你喜欢
  • 1970-01-01
  • 2017-01-21
  • 1970-01-01
  • 2017-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-26
  • 1970-01-01
相关资源
最近更新 更多