写spring项目中发现的算法问题

算法的重要性(地位)

  • 最近几天在做一个遗留的大创项目-校园论坛,在github上搜了一个雏形,进行代码的研究,Idea下Spring,Mavem,JPA数据库,Thymeleafui, elements Fragmets写前端。

  • 由于种种原因,剩下二十多天要结项了,几乎处于启动阶段,我不想浪费掉这次机会,所以叫上另一个小伙伴一起在这二十多天里,想要做出一个满意的项目上交审核,之前是相当于看过一遍spring mvc 和 mybatis的视频,有了一定的了解(做了笔记)。只写过登录注册。

  • 今天我们对一个小雏形进行附加功能的同时,突然间想起来可以对密码进行加密存储处理,通过搜索大概使用的是MD5等的封装好的加密算法,使用后有比较多的bug,所以我们自己写了一个加密算法,大概用两个维度进行加密处理,成功了。

  • 由于雏形中已经有了评论的树形结构显示,因此我对这个树形结构的出现的原因十分好奇(这也是我们必须要知道他是怎么样的原理),因此开始分析代码。

  • 实际上,不仅是分析代码而已,数据库的设计也关注了,因为里面有一个字段叫做parent_comment_id,再加上评论的时候的图像显示的树形结构,我不禁想起来一个算法中使用的数据结构-树状数组。因此我的直觉是这个必定是与树状数组有关。
    在这里插入图片描述
    若id为数组下标,parent_comment_id为下标对应的值,是不是就相当于一个树状数组。
    parent_comment_id不为空则记录他的父节点(父评论),若为空,则说明是一棵树的父节点。

在这里插入图片描述
这里的图看得出来整棵树最多两层(一开始我还以为是n层的,最后发现一般的评论也是2层,如果太多层的话屏幕都显示不完,第3层开始使用的是@sb 在第二层中显示)。

上一下代码:

调用commentRepository.findByBlogIdAndParentCommentNull(blogId,sort);
获取父节点集合(就是评论博主发布的内容的所有评论)

@Autowired
    private CommentRepository commentRepository;

    @Override
    public List<Comment> listCommentByBlogId(Long blogId) {
        Sort sort = new Sort("createTime");

        //commentRepository 继承JpaRepository JPA的方法操作数据库
        //get父结点集合
        List<Comment> comments = commentRepository.findByBlogIdAndParentCommentNull(blogId,sort);

        return eachComment(comments);
    }

上面方法继续调用eachComment(comments),我暂时看不出来有什么用,感觉都一样,还是获取了一个父节点集合

 private List<Comment> eachComment(List<Comment> comments) {
        List<Comment> commentsView = new ArrayList<>();
        //感觉没用下面这句 拷贝 然后加入 commentsView

        for (Comment comment : comments) {
            Comment c = new Comment();

            BeanUtils.copyProperties(comment,c);
            commentsView.add(c);
        }
        //commentsView 存储的还是所有父节点
        //合并评论的各层子代到第一级子代集合中
        combineChildren(commentsView);
        return commentsView;
    }

上述方法中最后调用combineChildren方法
获取每一个父节点的所有孩子,通过递归调用xxx方法

private void combineChildren(List<Comment> comments) {
        for (Comment comment : comments) {
            //把父节点一个个拿出来, 把当前父节点的每一个reply存入relys1集合中
            List<Comment> replys1 = comment.getReplyComments();
            for(Comment reply1 : replys1) {
                //循环迭代,找出子代,存放在tempReplys中
                recursively(reply1);

            }
            //每一个父节点的回复 设置为 tmpreplys
            comment.setReplyComments(tempReplys);
            //清除临时存放区
            tempReplys = new ArrayList<>();
        }
    }
 private void recursively(Comment comment) {
        tempReplys.add(comment);//顶节点添加到临时存放集合
        if (comment.getReplyComments().size()>0) {
            List<Comment> replys = comment.getReplyComments();
            for (Comment reply : replys) {
                tempReplys.add(reply);
                if (reply.getReplyComments().size()>0) {
                    recursively(reply);
                }
            }
        }
    }

一个父节点的子孙通过DFS的递归顺序不断的add到tmp中,
然后返回到combineChildren方法中 ,对父节点使用set方法传入子孙集合。循环往复,遍把所有的父节点都set了子孙评论。
然后通过model设置var返回前端使用。

以下是本人的拙见。
以下是我的感悟:
一年前,大二上学期刚开始我还是个超级萌新,(写个C语言一段代码可能bug都调不好),听说有个算法比赛叫做蓝桥杯,还在学校选拔,然后我就抱着试试看的态度,(当时连算法是什么都不知道,学了数据结构,所以就当复习了以下数据结构的内容)当时就想,如果做不出来,就在里面摸索,敲代码当作练习。
结果,考完出来,闰年都记错了。。但是还是被选上了,然后我就珍惜了这次的机会,疯狂的学习数据结构和STL的使用,然后去了比赛感觉就没啥用到(因为这是算法比赛,。。我裂开,不过还是搞了几题出来,大概一半左右),最后混了个省三C/C++组。
第二年,就是今年,我又选上了,然后我学了好多的算法(也算是皮毛,板子题)

  • 数学问题,GCD,欧筛,唉筛
  • 贪心
  • DP
  • DFS
  • BFS
  • 背包(背包九讲是在yxc北大大佬讲的,男人八题没来得及看)
  • 并查集
    除此之外还看了STL的容器 适配器 和 关联容器的使用,算法和一些仿函数一元谓词的使用,后来看了侯捷大师的STL源码剖析,颇有感触。

因为准备考研,和准备比赛,所以我先复习了专业课数据结构,最近两周前已经写完了天勤的小册子。对数据结构的模板代码和一些操作是比较了解的了。

不仅有些疑问,为什么要学这些数据结构DS和算法algorithm呢?如果是做网页的话感觉没怎么用到这么高级的东西,都是封装好的,不需要去理解这么深入,也用不到什么算法的这些东西。那么为什么还说这些重要呢?
我想今天,这个评论的分级显示处理给了我答案,如果我没学过数据结构的树状数组(在最小生成树中kruscal算法中会使用到),如果没有我这一年来的沉淀,那么我对于这个评论分级算法的理解,肯定是难于上青天,更可能根本看不懂而且还不想看。因此我才认识到,仅仅一个评论就有涵盖了这么多的算法内容,可见如果是一个大程序大工程,那么算法是在多么重要的地位。

以上是本人的拙见。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值