大佬们,假设下面这个是已经排序过的关于时间的数组,现在需要添加到不同距离当前年份时间的数组,能用二分查找去实现吗?

2022-08-18 22:37:32 +08:00
 unregister

public void test(){ String time2 = "2022-08-31"; for(int i = 0; i<times.size();i++){ String time = times.get(i); if(betweenMonth(time,time2) < 12){ oneYearTimes.add(time); } else if(betweenMonth(time,time2) >= 12 && betweenMonth(time,time2) < 24 ){ one2twoYearTimes.add(time); } else if(betweenMonth(time,time2) >= 24 && betweenMonth(time,time2) < 36 ){ two2threeYearTimes.add(time); } else if(betweenMonth(time,time2) >= 36 && betweenMonth(time,time2) < 48 ){ three2fourYearTimes.add(time); } else if(betweenMonth(time,time2) >= 48 && betweenMonth(time,time2) < 48 ){ four2fiveYearTimes.add(time); } else if(betweenMonth(time,time2) >= 60 ){ moreThanFiveYearTimes.add(time); } } }

static Long betweenMonth(String time1, String time2){
    return ChronoUnit.MONTHS.between(parse(time1), parse(time2));
}

static LocalDate parse(String str){
    DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    return LocalDate.parse(str, df);
}
1287 次点击
所在节点    程序员
28 条回复
JasonLaw
2022-08-19 08:22:16 +08:00
@unregister #18 我不是大佬,我还是在一直学习。如果你想要更加理解代码的话,真的建议你学习一下算法和数据结构,https://neetcode.io/是个好地方,我也在使用这个网站,大家一起进步。
aguesuka
2022-08-19 09:30:33 +08:00
首先你的代码应该是这样, 也就是先把重复的代码抽离成方法.

public void test() {
String time2 = "2022-08-31";
for (int i = 0; i < times.size(); i++) {
String time = times.get(i);
var monthsBetween = betweenMonth(time, time2);
findTimeList(monthsBetween).add(time);
}
}

List<String> findTimeList(long monthsBetween){
// TODO
}
zmal
2022-08-19 11:34:53 +08:00
@JasonLaw
private int 返回入参时间距今几年(String time);
Map<Integer, List<String>> yearMap = list.stream().collect(Collectors.groupingBy(this::返回入参时间距今几年, TreeMap::new, Collectors.toList()));

treeMap 只是用来把年份做个排序,遍历的时候方便。不用也可以。
msg7086
2022-08-19 11:50:14 +08:00
你想把扫全表变成二分搜来做 grouping 是吗?

确实可以做的。

比如说 Ruby 里有 bsearch_index 可以通过条件在数组里做二分搜,返回第一个满足条件的项的下标。
假设 times 是时间数组,降序,time2 是比较日期
year2_date = time2 - 1.year
year2_idx = times.bsearch_index {|time| time < year2_date} #找到第一个 1 年以前的日期
year3_date = time2 - 2.year
year3_idx = times.bsearch_index {|time| time < year3_date} #找到第一个 2 年以前的日期
然后把 0-year2_idx 的和 year2_idx-year3_idx 等等的 slice 切出来放进不同数组就行了。
JasonLaw
2022-08-19 11:51:59 +08:00
@zmal #23 有一个疑问,使用 tree map 的话,时间复杂度是 O(nlgn),对吗?
zmal
2022-08-19 11:55:10 +08:00
@JasonLaw
??? treeMap 的 key 是 int 值的年份,总共才 5 个数,和时间集合的长度无关。
JasonLaw
2022-08-19 12:06:56 +08:00
@zmal #26 对,如果不包含所有年份差的话,就是只有 6 个 key 。
unregister
2022-08-20 20:40:52 +08:00
@JasonLaw Thank you,已经收藏啦
@aguesuka 学习了。
@msg7086 谢谢大佬的思路。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/873853

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX