如何使用递归来解析组内组在Java?



我刚刚开始学习递归,所以如果有人能试着帮助我,我将非常感激。

我有以下String:

field1: typeA
field2: typeA
field3: typeB
group1:
fieldA: typeA
fieldB: typeB
subGroup1:
fieldX: typeB
fieldY: typeB
fieldC: typeC
field4: typeA
group2:
fieldA: typeB
subGroup1:
fieldX: typeA
fieldY: typeA
fieldB: typeA
fieldC: typeC
field5: typeC
field6: typeD

注意,我可以在组(子组)中有组。我也可以在组内组内组,所以据我所知递归是强制性的。

请注意,每行开头的间距决定该字段是否属于该组。

我想在Java中写一个方法,将返回一个LinkedHashMap<String, Object>,其中对象映射值可以是一个String表示这是一个字段(不是一个组)或另一个LinkedHashMap<String, Object>表示这是一个组(不是一个字段)。

我试过了,但失败了。递归目前对我来说太难了,但我正在研究它。

帮助想要帮助的人,在代码下面:

public static void main(String[] args) {

String text = String.join("n",

"field1: typeA",
"field2: typeA",
"field3: typeB",
"group1:",
"    fieldA: typeA",
"    fieldB: typeB",
"    subGroup1:",
"        fieldX: typeB",
"        fieldY: typeB",
"    fieldC: typeC",
"field4: typeA",
"group2:",
"    fieldA: typeB",
"    subGroup1:",
"        fieldX: typeA",
"        fieldY: typeA",
"    fieldB: typeA",
"    fieldC: typeC",
"field5: typeC",
"field6: typeD",

"");

Map<String, Object> solution = doIt(text);
System.out.println(solution);
}

private static LinkedHashMap<String, Object> doIt(String text) {
// solution goes here...
return null;
}
}

下面是正确的输出:

public static void main(String[] args) {
Map<String, Object> map = new LinkedHashMap<String, Object>();

map.put("field1", "typeA");
map.put("field2", "typeA");
map.put("field3", "typeB");

Map<String, Object> map2 = new LinkedHashMap<String, Object>();
map2.put("fieldA", "typeA");
map2.put("fieldB", "typeB");

Map<String, Object> map3 = new LinkedHashMap<String, Object>();
map3.put("fieldX", "typeB");
map3.put("fieldY", "typeB");
map2.put("subGroup1", map3);

map2.put("fieldC", "typeC");

map.put("group1", map2);

map.put("field4", "typeA");

Map<String, Object> map4 = new LinkedHashMap<String, Object>();
map4.put("fieldA", "typeB");

Map<String, Object> map5 = new LinkedHashMap<String, Object>();
map5.put("fieldX", "typeA");
map5.put("fieldY", "typeA");
map4.put("subGroup1", map5);

map4.put("fieldB", "typeA");
map4.put("fieldC", "typeC");

map.put("group2", map4);

map.put("field5", "typeC");
map.put("field6", "typeD");

System.out.println(map);
}

输出:

{field1=typeA, field2=typeA, field3=typeB, group1={fieldA=typeA, fieldB=typeB, subGroup1={fieldX=typeB, fieldY=typeB}, fieldC=typeC}, field4=typeA, group2={fieldA=typeB, subGroup1={fieldX=typeA, fieldY=typeA}, fieldB=typeA, fieldC=typeC}, field5=typeC, field6=typeD}

我会建立一个Queue来容纳你的文本行。该队列由函数使用,每次检测到新组时递归。使用队列允许您在每行执行peek,因此当您通过检查缩进级别找到当前组的末尾时,您可以返回并让前一个调用处理其余字段。

static String INDENT = "    ";
static LinkedHashMap<String, Object> doIt(Queue<String> q, String ind) 
{
LinkedHashMap<String, Object> map = new LinkedHashMap<>();

while(!q.isEmpty())
{
String line = q.peek();

if(!line.startsWith(ind)) break;

q.poll();

int idx = line.indexOf(":");
String name = line.substring(ind.length(), idx);
String value = line.substring(idx+1).trim();

if(!value.isEmpty())
map.put(name, value);
else
map.put(name, doIt(q, ind + INDENT));
}

return map;
}

测试:

String text = String.join("n",

"field1: typeA",
"field2: typeA",
"field3: typeB",
"group1:",
"    fieldA: typeA",
"    fieldB: typeB",
"    subGroup1:",
"        fieldX: typeB",
"        fieldY: typeB",
"    fieldC: typeC",
"field4: typeA",
"group2:",
"    fieldA: typeB",
"    subGroup1:",
"        fieldX: typeA",
"        fieldY: typeA",
"    fieldB: typeA",
"    fieldC: typeC",
"field5: typeC",
"field6: typeD",

"");
Map<String, Object> solution = doIt(new LinkedList<String>(Arrays.asList(text.split("n"))), "");
print(solution, "");

其中print方法看起来像这样(注意,由于不安全的强制转换,我们必须抑制警告):

@SuppressWarnings("unchecked")
static void print(Map<String, Object> map, String ind)
{
for(String name : map.keySet())
{
Object value = map.get(name);
if(value instanceof String)
System.out.println(ind + name + ": " + value);
else
{
System.out.println(ind + name + ":");
print((Map<String, Object>)value, ind + INDENT);
}           
}
}

输出:

field1: typeA
field2: typeA
field3: typeB
group1:
fieldA: typeA
fieldB: typeB
subGroup1:
fieldX: typeB
fieldY: typeB
fieldC: typeC
field4: typeA
group2:
fieldA: typeB
subGroup1:
fieldX: typeA
fieldY: typeA
fieldB: typeA
fieldC: typeC
field5: typeC
field6: typeD

最新更新