为了账号安全,请及时绑定邮箱和手机立即绑定

从逗号分隔整数的字符串数组映射的连续天数

从逗号分隔整数的字符串数组映射的连续天数

慕尼黑8549860 2023-10-19 21:08:39
我收到了多个以逗号分隔的字符串整数作为输入,例如以下字符串:“5,6,0”“0,1,2”“1,2,3,4”这些整数中的每一个都代表一周中的一天0 = 星期日 1 = 星期一 2 = 星期二 3 = 星期三 4 = 星期四 5 = 星期五 6 = 星期六对于第一个字符串,这意味着星期四到星期日 第二个字符串的有效期是星期日到星期二 第三个字符串的有效期是星期一到星期四目前,我正在使用以下  private fun mapOfDays(validDays: String): LinkedHashMap<Int, String>    {        if (!validDays.isBlank())        {            val daysArray = validDays.split("\\s*,\\s*") as Array<String>            var mapDays = LinkedHashMap<Int, String>()            var mapDay = LinkedHashMap<Int, String>()            mapDays[0] = "SUNDAY"            mapDays[1] = "MONDAY"            mapDays[2] = "TUESDAY"            mapDays[3] = "WEDNESDAY"            mapDays[4] = "THURSDAY"            mapDays[5] = "FRIDAY"            mapDays[6] = "SATURDAY"            for (day in daysArray)            {                if (mapDays.containsKey(day.toInt()))                {                    mapDay[day.toInt()] = mapDays[day.toInt()]!!                }            }            return mapDay        }        return LinkedHashMap()    }    private fun mappedDays(mapOfDays: LinkedHashMap<Int, String>?): String    {        if (!mapOfDays.isNullOrEmpty())        {            val mapSize = mapOfDays.size            if (mapSize > 6) return "All Day"            if (mapSize > 5) return sixDayString(mapOfDays)            if (mapSize > 4) return fiveDayString(mapOfDays)            if (mapSize > 3) return fourDayString(mapOfDays)            if (mapSize > 2) return threeDayString(mapOfDays)            if (mapSize > 1) return twoDayString(mapOfDays)            if (mapSize > 0) return oneDayString(mapOfDays)        }        return ""    }但是,我当前的实现能够告诉我包含哪些天,但无法绘制出天数组,例如:如果我得到“0,1,3,4,5,6”我想要的最终字符串输出如下:星期三到星期一或者“0,1,3,4,5”将导致以下结果:Sunday , Monday , Wednesday to Friday。
查看完整描述

2 回答

?
Qyouu

TA贡献1786条经验 获得超11个赞

package days


import java.lang.IllegalArgumentException



class DaysFactory {

    fun dayFromInt(index: Int): Day {

        return when (index) {

            0 -> Day.Sunday

            1 -> Day.Monday

            2 -> Day.Tuesday

            3 -> Day.Wednesday

            4 -> Day.Thursday

            5 -> Day.Friday

            6 -> Day.Saturday

            else -> throw IllegalArgumentException("illigal index :$index")

        }

    }


    enum class Day(val index: Int) {

        Sunday(0), Monday(1), Tuesday(2), Wednesday(3), Thursday(4), Friday(5), Saturday(6)

    }

}



class DaysRange(val seed: String) {


    var stringFormat = ""


    private fun getTomorrow(dayIndex: Int): Int {

        if (dayIndex != 6) return dayIndex + 1

        return 0

    }


    override fun toString(): String =stringFormat



    init {

        if (isValidInput(seed)) {

            val dayFactory = DaysFactory()

            val indexes = seed.split(",").map { it.toInt() }

            val days = indexes.map { dayFactory.dayFromInt(it) }

            val ranges = splitIndexesToRanges(indexes)

            ranges.forEach { range ->

                if (range.size > 2) {

                    stringFormat += "${dayFactory.dayFromInt(range.first())} to ${dayFactory.dayFromInt(range.last())},"

                } else

                    range.forEach {

                        stringFormat += "${dayFactory.dayFromInt(it)},"

                    }

            }

            stringFormat = stringFormat.dropLast(1)

        }

    }


    private fun splitIndexesToRanges(daysRange: List<Int>): ArrayList<List<Int>> {

        val result = ArrayList<List<Int>>()

        val slicePoint = ArrayList<Int>()

        for (i in 0 until daysRange.size - 1) {

            if (getTomorrow(daysRange[i]) != daysRange[i + 1]) {

                slicePoint.add(i)

            }

        }


        var start = 0

        slicePoint.forEach {

            result.add(daysRange.slice(start..it))

            start = it + 1

        }

        result.add(daysRange.slice(start until daysRange.size))

        return result


    }


}


private fun isValidInput(seed: String): Boolean = true



fun main(args: Array<String>) {


    val input = listOf(

        "0,1,2,4,5,6",

        "5,6,0",

        "1,2,3,4"

    )


    input.forEach {

        val dr = DaysRange(it)

        println(dr)

    }

}

示例输出:


周日至周二、周四至周六


周五至周日


周一至周四


查看完整回答
反对 回复 2023-10-19
?
哈士奇WWW

TA贡献1799条经验 获得超6个赞

如果可以的话,我会坚持使用给定的时间 API(例如,java.time如果您使用 Java 8 或 joda-time 等)。以下解决方案也适用于您的enum,但您需要对其进行一些调整(即DayOfWeek具有getDisplayName并且还允许添加单日并始终获得下一个连续天)。


我将工作分成 3 个独立的任务。


将输入读入以下列表DayOfWeek:


fun readInput(input : String) : List<DayOfWeek> = input.splitToSequence(",")

    .map(String::toInt)

    .map {

      /* your 0 is Sunday which is 7 for DayOfWeek; rest is the same */

      if (it == 0) 7 else it

    }

    .map(DayOfWeek::of)

    .toList()

也许您想添加.distinct().sorted()它或想事先验证输入...这取决于您真正想确保什么...


将星期几转换为连续天的列表:


fun List<DayOfWeek>.toDayRangeList() : List<DayRange> = fold(mutableListOf<DayRange>()) { consecutiveDaysList, day ->

  consecutiveDaysList.apply {

    lastOrNull()?.takeIf { it.to + 1 == day }?.apply {

      to = day

    } ?: add(DayRange(day))

  }

}

为此,我还引入了一个DateRange-class 以便轻松改变结束日期...您也可以使用不可变对象执行此操作,但我发现这种方式更容易。它还DateRange包括一些辅助方法,可以轻松获取所需形式的实际日期(在我的示例中FULL_STANDALONE):


data class DayRange(var from: DayOfWeek, var to: DayOfWeek = from) {

  private fun DayOfWeek.toFullString(locale : Locale) = getDisplayName(TextStyle.FULL_STANDALONE, locale)

  fun toString(locale : Locale) : String = when (from) {

    // TODO add missing locale specific strings!

    to -> from.toFullString(locale)

    to + 1 -> "All day"

    else -> "${from.toFullString(locale)} to ${to.toFullString(locale)}"

  }

  // just for convenience we use our custom toString-function:

  override fun toString() = toString(Locale.getDefault())

}

可选地“展平”列表,即如果最后一天和第一天是连续的,则将它们合并到一个范围中。当我们直接处理时,DayOfWeek我们可以简单地添加另一天并比较两天,无论其中一天是否是一周的最后一天:


fun List<DayRange>.flatten(): List<DayRange> {

  if (size > 1) {

    val first = first()

    val last = last()

    if (last.to + 1 == first.from)

      return dropLast(1).drop(1)

          .toMutableList()

          .apply {

            add(DayRange(last.from, first.to))

          }

  }

  return this

}

将它们放在一起/演示:


listOf("1", "1,2", "1,0", "1,2,3", "1,2,4,5", "1,2,4,5,0", "1,2,3,4,5,6,0", "2,3,4,5,6,0,1")

      .forEach { input ->

        print(input)

        readInput(input)

            .toDayRangeList()

            .flatten()

            .joinToString(", ")

            .also {

              println("-> $it")

            }

      }

打印以下内容:


1 -> Monday

1,2 -> Monday to Tuesday

1,0 -> Sunday to Monday

1,2,3 -> Monday to Wednesday

1,2,4,5 -> Monday to Tuesday, Thursday to Friday

1,2,4,5,0 -> Thursday to Friday, Sunday to Tuesday

1,2,3,4,5,6,0 -> All day

2,3,4,5,6,0,1 -> All day


查看完整回答
反对 回复 2023-10-19
  • 2 回答
  • 0 关注
  • 115 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信