Java(或Excel) – 如何alignment乱序的数据

我有以下数据:

abcdfghij abdefhij abcdefjkl abcdefghm 

我想输出它(例如Excel),如下所示:

  abcdefghij abdefhij abcdefjkl abcdefghm 

在excel方面,我想跨单元格移动,所以文本在列中匹配。

注意:为简单起见,我使用了字母顺序,但实际上并没有这样的顺序 – 但我需要保持原来的顺序。

更新示例:

  Original Data abcdfghijabdefhijabcd efjklabxdefghm Dougs Output abcdfghijabdefhijabcd efjklabdxefghm My Manual Output (Required) abcdfghijabdefhijabcd efjklabxdefghm 

上面的x出现在索引2处,但是d出现在索引2和3处,因此x应该在d之前。

我想我已经明白了。 这依赖于您不能将重复值添加到collection的事实。 诀窍是以正确的顺序parsing源数据。 我认为这是通过列中的每个单元格,然后到下一列。 然后集合包含在该search顺序中find的每个项目的第一个实例。

该代码需要两张纸,一张带有来源和一张目标纸以包含输出。 在这种情况下,我使用代码将wsSourcewsTarget设置为工作簿中的前两张,但是可以根据需要更改。

你可以改变rng的定义。 只要源表中没有其他内容,代码将确定数据的最后一行和最后一列。 这是通过在其中Find的行完成的:

 Sub Rearrange() Dim wsSource As Excel.Worksheet Dim rng As Excel.Range Dim i As Long, j As Long Dim cell As Excel.Range Dim coll As Collection Dim wsTarget As Excel.Worksheet Dim SourceLastRow As Long Dim SourceLastCol As Long Set wsSource = ThisWorkbook.Sheets(1) Set wsTarget = ThisWorkbook.Sheets(2) Set rng = wsSource.Range("A1:i4") 'change to suit Set coll = New Collection SourceLastRow = rng.Cells.Find("*", rng.Cells(1), xlValues, , xlByRows, xlPrevious).Row SourceLastCol = rng.Cells.Find("*", rng.Cells(1), xlValues, , xlByColumns, xlPrevious).Column 'cycle through the cells in the range down through each column from left to right For i = 1 To SourceLastCol For j = 1 To SourceLastRow Set cell = wsSource.Cells(j, i) If cell.Value <> "" Then On Error Resume Next 'can only add an item once - no duplicates coll.Add cell.Value, cell.Value On Error GoTo 0 End If Next j Next i 'Clear and re-load wsTarget wsTarget.Cells.Clear For i = 1 To coll.Count For j = 1 To SourceLastRow If Application.WorksheetFunction.CountIf(wsSource.Cells(j, 1).EntireRow, coll(i)) = 1 Then wsTarget.Cells(j, i) = coll(i) End If Next j Next i End Sub 

我用Java解决了它。 有一个自定义比较,它会查看每个值的最大和最小索引,并对其进行sorting。 然后我把它们打印出来。

**注意我的数据是在HashMap中,这里没有解释的原因,但它可以很容易地在一个简单的列表。

**请原谅我没有经验的编码做法。

@ Doug-Glancy如果你能在VB中做到这一点,那就太棒了!

ValueComparator.java

 import java.util.Comparator; import java.util.Map; public class ValueComparator implements Comparator<String> { private Map<String, Integer[]> base; public ValueComparator(Map<String, Integer[]> m) { this.base = m; } public int compare(String so1, String so2) { // get the max and min indices from each data peice Integer[] o1 = base.get(so1); Integer[] o2 = base.get(so2); // compare their min index first if (o1[0] < o2[0]) { return -1; } if (o1[0] == o2[0]) { //if they are the same if ( o1[1] < o2[1]) { // then look at the max index return -1; } else { return 1; } } else { return 1; } } } 

App.java

 import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import localhost.ValueComparator; public class App { public static void main( String[] args ) { // create a list to store our original data ArrayList<HashMap<String, String>> keyValuePairs = new ArrayList<HashMap<String,String>>(); // add the data to the list HashMap<String, String> a = new LinkedHashMap<String, String>(); a.put("a", "1"); a.put("b", "1"); a.put("c", "1"); a.put("d", "1"); a.put("f", "1"); a.put("g", "1"); a.put("h", "1"); a.put("i", "1"); a.put("j", "1"); keyValuePairs.add(a); HashMap<String, String> e = new LinkedHashMap<String, String>(); e.put("a", "1"); e.put("b", "1"); e.put("d", "1"); e.put("e", "1"); e.put("f", "1"); e.put("h", "1"); e.put("i", "1"); e.put("j", "1"); keyValuePairs.add(e); HashMap<String, String> b = new LinkedHashMap<String, String>(); b.put("a", "1"); b.put("b", "1"); b.put("c", "1"); b.put("d", "1"); b.put("e", "1"); b.put("f", "1"); b.put("j", "1"); b.put("k", "1"); b.put("l", "1"); keyValuePairs.add(b); HashMap<String, String> c = new LinkedHashMap<String, String>(); c.put("a", "1"); c.put("b", "1"); c.put("x", "1"); c.put("d", "1"); c.put("e", "1"); c.put("f", "1"); c.put("g", "1"); c.put("h", "1"); c.put("m", "1"); keyValuePairs.add(c); // create a map to store the max and min indices Map<String, Integer[]> m = new HashMap<String, Integer[]>(); Integer curpos = new Integer(0); // loop through the data and find the max and min indices of each data (key) for ( Map<String,String> s : keyValuePairs) { curpos = 0; for ( String t : s.keySet() ) { if ( !m.containsKey(t) ){ // if its the first time to see the data, just add its current index as max and min m.put(t,new Integer[] {curpos, curpos}); } else { // check if index is lower than existing minimum Integer[] i = m.get(t); if ( i[0] > curpos) { m.put(t, new Integer[] {curpos, i[1]}); } //check if index is greater than current maximum if ( curpos > i[1] ) { m.put(t, new Integer[] {i[0], curpos}); } } curpos++; } } System.out.println("The unsorted data"); for ( HashMap<String,String> h : keyValuePairs ) { for ( String s : h.keySet() ) { System.out.print(" " + s + " "); } System.out.println(); } System.out.println("\n"); // Sort the data using our custom comparator ValueComparator com = new ValueComparator(m); List<String> toSort = new LinkedList<String>(m.keySet()); Collections.sort(toSort, com); System.out.println("The sorted data"); for ( HashMap<String,String> h : keyValuePairs) { for ( String s : toSort ) { if ( h.containsKey(s) ) { System.out.print(s + " "); } else { System.out.print(" "); } } System.out.println(); } } }