我刚刚开始学习递归,所以如果有人能试着帮助我,我将非常感激。
我有以下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