当前位置: 首页 > news >正文

分享一个项目中遇到的一个算法题

需求背景:

需求是用户要创建一个任务计划在未来执行,要求在创建任务计划的时候判断选择的时间是否符合要求,否则不允许创建,创建的任务类型有两种,一种是单次,任务只执行一次;另一种是周期,从周一到周日,任务可以重复执行。如果选择单次执行,在选择时间的时候要判断选择的时间是否大于当前时间,如果小于当前时间那么当前任务将不在当天执行而是第二天的同一时间执行,反之是在当天执行。确定好哪一天执行之后还要判断那一天是否有已经创建的任务,如果有再判断同一天的两个时间点是否相差15分钟,如果在15分钟以内则时间发生碰撞不允许创建。如果选择周期执行,也要和已经创建的单次任务或者周期任务进行时间检查,另外两个任务如果不在同一天执行,还要判断在跨天时间点上是否相差15分钟,比如周一晚上23:55和周二凌晨00:05相差10分钟,也是属于时间冲突,那么基于这个需求写一下时间冲突的逻辑判断。

最终调用函数获取结果代码:

 val checkResult = mViewModel.checkTime(
            DateUtil.convertTimeToMinutes(startTimeStr),
            StringUtil.convertStringToList(cycleDay),
            vehReservationStandListBean,
            mPreBean?.keyId,
        )

        if (!checkResult.first) {
            "任务时间冲突,任务名称: ${checkResult.second}, 请重新选择时间点".showToast()
            return false
        }

具体检查时间冲突逻辑:

(入参格式:newStartTime="11:30" --> 11*60+30,代表字符串格式hh:mm转成分钟数 

  newCycleDay = 0,1,2,3,4,5,6,7的list集合,list代表一个已经创建的任务数据体集合)


    /**
     * 时间和周期是否允许创建 
     */
    fun checkTime(
        newStartTime: Int?,
        newCycleDay: List<Int>?,
        list: List<ReservationStandSetOperationBean>?,
    ): Pair<Boolean, String?> {
        if (newStartTime == null || newCycleDay == null) {
            return Pair(false, "")
        }

        // 获取新任务的时间段
        val newTimeSlots = DateUtil.getTimeSlots(newCycleDay, newStartTime)


        for (model in list ?: emptyList()) {

            val existingStartTime = DateUtil.convertTimeToMinutes(model.carReadyTime)
            val existingCycleDay = StringUtil.convertStringToList(model.cycleDay)

            if (existingStartTime == null || existingCycleDay == null) {
                continue
            }

            // 获取已存在任务的时间段
            val existingTimeSlots = DateUtil.getTimeSlots(existingCycleDay, existingStartTime)

            // 检查时间段是否重叠
            for (newSlot in newTimeSlots) {
                for (existingSlot in existingTimeSlots) {
                    if (DateUtil.isTimeOverlap(newSlot, existingSlot)) {
                        return Pair(false, model.planName)
                    }
                }
            }
        }
        return Pair(true, "")
    }

 返回需要执行时间碰撞的数据集合:


        // 获取任务的执行日期和时间段
        fun getTimeSlots(days: List<Int>, startTime: Int): List<Triple<Int, Int, Int>> {
            val result = mutableListOf<Triple<Int, Int, Int>>()
            val minutesInDay = 24 * 60
            val calendar = Calendar.getInstance()
            val now = Date()
            val currentTime =
                calendar.get(Calendar.HOUR_OF_DAY) * 60 + calendar.get(Calendar.MINUTE)
            val weekday = calendar.get(Calendar.DAY_OF_WEEK)
            val today = if (weekday == Calendar.SUNDAY) 7 else weekday - 1

            for (day in days) {
                //任务执行的日期
                var adjustedDay = day

                // 如果是单次任务 需要判断是否需要加一天
                if (days == listOf(0)) {
                    // 如果任务的开始时间小于当前时间,推迟到明天
                    if (startTime <= currentTime) {
                        adjustedDay = if (today == 7) 1 else today + 1
                    } else {
                        adjustedDay = today
                    }
                }

                val endTime = startTime + 15

                // 如果任务跨天
                if (endTime >= minutesInDay) {
                    // 当天的时间段  日期,起始时间,终止时间
                    result.add(Triple(adjustedDay, startTime, minutesInDay))
                    // 第二天的时间段 日期,起始时间,终止时间
                    result.add(
                        Triple(
                            if (adjustedDay == 7) 1 else adjustedDay + 1,
                            0,
                            endTime - minutesInDay
                        )
                    )
                } else {
                    // 不跨天的时间段  日期,起始时间,终止时间
                    result.add(Triple(adjustedDay, startTime, endTime))
                }
            }
            return result
        }

判断两个数据集合是否时间段有重叠: 

  // 检查时间段是否重叠
        fun isTimeOverlap(slot1: Triple<Int, Int, Int>, slot2: Triple<Int, Int, Int>): Boolean {
            // 如果日期不同,则不重叠
            if (slot1.first != slot2.first) {
                return false
            }

            // 检查时间段是否重叠
            return slot1.second < slot2.third && slot2.second < slot1.third
        }

结语:实际项目中用到的算法逻辑大多不复杂,这种需要动态计算任务执行时间,还要考虑跨天的逻辑比较少见,这里做个记录方便以后有类似逻辑可以做个代码参考。


文章转载自:
http://automark.elldm.cn
http://astrolatry.elldm.cn
http://caramelise.elldm.cn
http://archean.elldm.cn
http://backwater.elldm.cn
http://careworn.elldm.cn
http://bronchiole.elldm.cn
http://arian.elldm.cn
http://billhook.elldm.cn
http://belt.elldm.cn
http://asterisk.elldm.cn
http://broadax.elldm.cn
http://bedgown.elldm.cn
http://antisocialist.elldm.cn
http://ablush.elldm.cn
http://aviation.elldm.cn
http://bureau.elldm.cn
http://bars.elldm.cn
http://archipelagic.elldm.cn
http://balladmonger.elldm.cn
http://bend.elldm.cn
http://agree.elldm.cn
http://carpenter.elldm.cn
http://barabbas.elldm.cn
http://apotropaion.elldm.cn
http://apogeotropic.elldm.cn
http://caprifig.elldm.cn
http://anhydro.elldm.cn
http://ambiguity.elldm.cn
http://biostratigraphic.elldm.cn
http://www.dtcms.com/a/75938.html

相关文章:

  • SPI 总线协议
  • Pytest项目_day01(HTTP接口)
  • 微服务即时通信系统---(五)框架学习
  • 【Spring】第四弹:基于XML文件注入Bean对象
  • IDEA2022自动构建注册表没有compiler.automake.allow.when.app.running选项解决方法
  • 【HarmonyOS Next】常见的字节转换
  • 激光slam学习笔记10---ubuntu2004部署运行fastlivo2踩坑记录
  • Web 小项目: 网页版图书管理系统
  • 速盾:如何利用CDN静态加速匹配尾缀提升网站性能?
  • 判断是不是完全二叉树(C++)
  • 【小白调试电路板】
  • 剑指 Offer II 109. 开密码锁
  • SpringBoot-MVC配置类与 Controller 的扫描
  • keepalived应用
  • Day19:把数字翻译成字符串
  • 蓝桥杯每日五题第一日
  • 计算机网络的框架结构
  • 每日一题--计算机网络
  • Maven常见问题汇总
  • 【C++内存管理】
  • 教材与课程的协同-以计算机网络专业为例
  • CopyOnWriteArrayList 和 CopyOnWriteArraySet对比
  • rclone工具迁移minio数据
  • 【JAVA】】深入浅出了解cookie、session、jwt
  • Lora微LLAMA模型实战
  • 相机光学(四十七)——相纸材质
  • 博客迁移----宝塔面板一键迁移遇到问题
  • CSV加密代码分析
  • 函数凹凸性
  • matlab 正态分布