【华为OD题库-049】评论转换输出-java

题目

在一个博客网站上,每篇博客都有评论。每一条评论都是一个非空英文字母字符串。评论具有树状结构,除了根评论外,每个评论都有一个父评论。
当评论保存时,使用以下格式:
首先是评论的内容;
然后是回复当前评论的数量。
最后是当前评论的所有子评论。(子评论使用相同的格式嵌套存储)
例如:
第—条评论是"hello,2,ok,0,bye,0" ,
第二条评论是"test,0" ,
第三条评论是"one,1 ,two,1,a,0"
所有评论被保存成"hello,2,ok,0,bye,0,test,0,one,1,two,1,a,0"。对于上述格式的评论,请以另外—种格式打印:
首先打印评论嵌套的最大深度。
然后是打印n行,第(1<=i<=n)行对应于嵌套级别为i的评论(根评论的嵌套级别为1)。按照它们出现的顺序打印,用空格分隔开。
输入描述:
1行评论。由英文字母、数字和英文逗号组成。保证每个评论都是由英文字符组成的非空字符串。每个评论的数量都是整数(至少由一个数字组成)。整个字符串的长度不超过106.给定的评论结构保证是合法的。
输出描述
按照给定的格式打印评论。对于每一级嵌套,评论应该按照输入中的顺序打印
示例1
输入:
hello,2,ok,0,bye,0,test,0,one,1,two,1,a,0
输出:
3
hello test one
ok bye two
a
说明:
如下图所示,最大嵌套级别为3。嵌套级别为1的评论是"hello test one”,嵌套级别为2的评论是"ok bye two",嵌套级别为3的评论为"a"。
在这里插入图片描述
示例2
输入:
A,5,A,0,a,0,A,0,a,0,A,0
输出:
2
A
A a A a A
说明:
如下图所示,最大嵌套级别为2,嵌套级别为1的评论是"A",嵌套级别为2的评论是"A a A a A"
在这里插入图片描述
示例3
输入:
A,3,B,2,C,0,D,1,E,0,F,1,G,0,H,1,I,1,J,0,K,1,L,0,M,2,N,0,O,1,P,0
输出:
4
A K M
B F H L N O
C D G I P
E J
说明: 如下图所示。
在这里插入图片描述
在这里插入图片描述

思路

这道题还是有难度,对递归不太好想

  1. 首先将字符串以逗号分割,得到字符数组arrs,
  2. 将arrs转为两个子数组,分别存放字符串和数字,以chars,nums表示
  3. 考虑设计递归函数,从题目中可以提取两个关键变量:遍历arrs的索引idx(和chars,nums中的idx/2位置对应),以及当前层级level。其中索引是从0到arrs.length-1,level可能在回溯中会在0,1,2,3,4…这些数反复出现,所以可以将level设计到递归函数里面,将idx放到最外层的静态变量。即,递归函数的形式为:dfs(level,chars,nums)
  4. 对于dfs里面,应该先将当前位置的值chars[idx/2]存入当前level的结果中,然后根据nums[idx/2]判断当前有几个子评论,循环调用dfs函数,这时的level应该是当前level+1,即:dfs(level+1,chars,nums)。如果nums[idx/2]=0,那么就是递归调用0次,也就结束了当前递归
  5. 每次确定存放了一个level的结果后,idx要加2,即idx始终会变大,判断子评论数量用的是nums[idx/2],为了避免idx变大对子评论数量的影响,应该先将值存下来用于for循环,再将idx增大。
  6. 最后将结果存入List < String > res中即可,level为0则存放0位置,level为1则存放1位置。因为根据实际,肯定是先有0位置,才有1位置(输入是先有父评论,再有子评论),比如res中已经存放了2级评论,当出现3级评论时,此时在res中找不到2的索引,但是res的size一定为2(已经存放过1级和2级评论),因此可以直接把此时结果存入res,存入后res最后一位的索引就为2,即代表3级评论。

题解

package hwod;

import java.util.*;

public class CommentInput {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        List<String> res = commentInput(str);
        System.out.println(res.size());
        for (int i = 0; i < res.size(); i++) {
            System.out.println(res.get(i));
        }

    }

    private static List<String> res = new ArrayList<>();

    private static int idx = 0;

    private static List<String> commentInput(String str) {
        //将字符串分割为字符串和数字两部分
        String[] arrs = str.split(",");
        String[] chars = new String[arrs.length / 2];
        int[] nums = new int[arrs.length / 2];
        for (int i = 0; i < chars.length; i++) {
            chars[i] = arrs[i * 2];
            nums[i] = Integer.parseInt(arrs[2 * i + 1]);
        }
        int level = 0;
        while (idx != arrs.length) {
            dfs(level, chars, nums);
        }
        return res;
    }

    private static void dfs(int level, String[] chars, int[] nums) {
        if (res.size() > level) {
            res.set(level, res.get(level) + " " + chars[idx / 2]);
        } else {
            res.add(chars[idx / 2]);
        }
        int num = nums[idx / 2];
        idx += 2;
        for (int i = 0; i < num; i++) {
            dfs(level + 1, chars, nums);
        }

    }
}

推荐

如果你对本系列的其他题目感兴趣,可以参考华为OD机试真题及题解(JAVA),查看当前专栏更新的所有题目。

说明

本专栏所有文章均为原创,欢迎转载,请注明文章出处:https://blog.csdn.net/qq_31076523/article/details/134176793。百度和各类采集站皆不可信,搜索请谨慎鉴别。技术类文章一般都有时效性,本人习惯不定期对自己的博文进行修正和更新,因此请访问出处以查看本文的最新版本。

  • 23
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
华为od机试中,新学校选址问题是一个关于使用Java语言解决的问题。在解决这个问题时,我们可以通过以下步骤来完成。 首先,我们需要理解问题的要求和限制条件。新学校选址的目标是在一个给定的地图上找到一个合适的位置来建设新学校。这个位置应满足一定的条件,比如与周围的住宅区距离不宜过远,应尽可能靠近居民区。限制条件可能还包括学校面积和周边环境等。 接下来,我们需要获取地图的数据。可以通过读取一个地图文件或者从数据库中查询地图数据来获得地图的信息。地图数据的存储方式可以灵活选择,比如使用二维数组或者邻接矩阵。 然后,我们需要编写一个Java程序来实现新学校选址算法。可以使用图的遍历算法,比如深度优先搜索(DFS)或广度优先搜索(BFS)来实现。算法的核心是通过递归或循环遍历地图上的每一个位置,并根据选址条件进行判断和筛选。 最后,我们需要输出选址结果。可以将选定的位置以某种方式标记在地图上,比如输出一个新的地图文件或者在图形界面中显示。同时,还可以输出选址的具体坐标和其他相关信息,以便后续的学校建设工作。 总之,通过使用Java语言,我们可以通过一个新学校选址问题来展示我们在算法设计和编程方面的能力。相信在华为od机试中,通过合理的数据处理和算法实现,我们可以解决这个问题并得出满意的选址结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值