表格局部排序

发布时间 2023-12-18 16:13:11作者: 易先讯
题目描述

小E需要对表格的选定矩形区域进行排序:

  • 给定选定区域内的某些列作为排序条件 sortCols;排序时选定区域内的行数据联动,选定区域外不联动
  • 排序规则:
    • 排序条件可能是多列,按输入顺序,优先级依次降低。
    • 对于每个排序条件,按值的大小进行升序排序;若值相同,则保持原有行的相对顺序不变。

请编写一个程序帮助他完成该任务,并输出排序后的完整表格。

解答要求时间限制:1000ms, 内存限制:256MB
输入

第一个参数是二维数组 grid,1 <= grid.length, grid[0].length <= 100, 0 <= grid[i][j] <= 100
第二个参数是一维数组 area,1 <= area[i] <= 100, area[2] >= area[0], area[3] >= area[1]
第三个参数是一维数组 sortCols,1 <= sortCols[i] <= area[3] - rea[1] + 1

输出

排序后的完整表格

样例

输入样例 1 复制

[[1, 2, 2, 3, 4], [1, 2, 3, 7, 5], [1, 1, 3, 5, 6], [1, 4, 1, 6, 7]]
[2, 3, 4, 5]
[1, 2]

输出样例 1

[[1, 2, 2, 3, 4],
[1, 2, 1, 6, 7],
[1, 1, 3, 5, 6],
[1, 4, 3, 7, 5]]
提示样例 1

对选定矩形区域(蓝色)内的数据进行排序,类似于excel选定区域的多列排序,且为稳定排序,示意如下:

排序条件有两列,依次为选定区域的第1列、第2列
优先按第1列的值进行升序排序,行数据 [1, 6, 7] 排在最上
再按第2列的值进行升序排序,[3, 7, 5] 排在 [3, 5, 6] 下面



输入样例 2 复制

[[80, 59, 7, 25],
[81, 59, 7, 25],
[80, 56, 7, 12],
[13, 21, 97, 53]]
[1, 1, 3, 3]
[3, 1]

输出样例 2

[[80, 59, 7, 25],
[80, 56, 7, 25],
[81, 59, 7, 12],
[13, 21, 97, 53]]
提示样例 2

选中区域的排序条件按优先级依次为第3列、第1列。
第1行、第3行在两个排序条件上的值都相等,保持原有相对顺序。

 
 
排序模板的应用:
科目一: 设计题常用排序模板

// 用到这个模板的两个场景
// 脑袋混沌时,凭借肌肉记忆写这个学生排序模板然后在main里调几下就出结果
// 追求手速可以提炼出自己快捷操作来快速结束编码的鸡肋部分。一些东西都可以省缺着写。


package main

import (
    "fmt"
    "sort"
)

type Stu struct {
    id   int
    age  int
    name string
}

func main() {
    sortlist := []Stu{
        {id: 2, age: 10, name: "aaa"},
        {id: 1, age: 12, name: "bbb"},
    }

    // 临场记不得升序降序的调整下两个学生的信息,然后执行下改改就行了,
    // 注意点1 记得要把学生信息调整的和你想要的顺序相反!
    sort.Slice(sortlist, func(i, j int) bool {
        if sortlist[i].id != sortlist[j].id {
            return sortlist[i].id < sortlist[j].id //升序
        }
        if sortlist[i].age != sortlist[j].age {
            return sortlist[i].age > sortlist[j].age //降序
        }
        return sortlist[i].name < sortlist[j].name //字典序
    })

    fmt.Println(sortlist)
}

### 建议默写100次

模板二: 给出条件的,循环比较

package main

import (
    "fmt"
    "sort"
    "strings"
)

type Stu struct {
    id   int
    name string
    age  int
}

var stus []Stu

func main() {
    stus = []Stu{
        {id: 1, name: "Alice", age: 20},
        {id: 2, name: "Bob", age: 22},
        {id: 3, name: "Charlie", age: 18},
    }

    // 注意点2 提交通过后 记得把sorted里的Comparator拿出来
    sortRules := []string{"id", "age"}
    comparator := getComparator(sortRules)
    sort.Slice(stus, comparator)

    fmt.Println("Sorted by", sortRules)
    for _, stu := range stus {
        fmt.Printf("Stu{id: %d, name: %s, age: %d}\n", stu.id, stu.name, stu.age)
    }
}

// 注意点3 如果排序规则是动态的,比如传个sortRules给你,那你生成一个循环比较一盘就行了
func getComparator(sortRules []string) func(i, j int) bool {
    return func(i, j int) bool {
        for _, rule := range sortRules {
            switch rule {
            case "id":
                if stus[i].id != stus[j].id {
                    return stus[i].id < stus[j].id //升序
                }
            case "age":
                if stus[i].age != stus[j].age {
                    return stus[i].age > stus[j].age //降序
                }
            default:
                return strings.Compare(stus[i].name, stus[j].name) < 0 //字典序
            }
        }
        return strings.Compare(stus[i].name, stus[j].name) < 0 //字典序
    }
}
View Code

 

 

AC:

/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2019-2023. All rights reserved.
 * Description: 上机编程认证
 * Note: 缺省代码仅供参考,可自行决定使用、修改或删除
 * 只能import Go标准库
 */
package main

import (
    "bufio"
    "encoding/json"
    "fmt"
    "io"
    "os"
    "regexp"
    "strings"
    "sort"
)

// 待实现函数,在此函数中填入答题代码
func sortTable(grid [][]int, area []int, sortCols []int) [][]int {
    // 取出要排序的二维数组
    var preSortArr = [][]int{}
    for i := area[0] - 1; i < area[2]; i++ {
        preRow := []int{}
        for j := area[1] - 1; j < area[3]; j++ {
            preRow = append(preRow, grid[i][j])
        }
        preSortArr = append(preSortArr, preRow)
    }
    // sort 排序
    sort.Slice(preSortArr, func(i, j int) bool { 
         if len(sortCols) < 2 {
            return preSortArr[i][sortCols[0]-1] < preSortArr[j][sortCols[0]-1]
         }
         if preSortArr[i][sortCols[0]-1] != preSortArr[j][sortCols[0]-1] {
                return preSortArr[i][sortCols[0]-1] < preSortArr[j][sortCols[0]-1]
         }  
         return preSortArr[i][sortCols[1]-1] < preSortArr[j][sortCols[1]-1] 
    })
    // 还原数组
    for i := area[0] - 1; i < area[2]; i++ {
        for j := area[1] - 1; j < area[3]; j++ {
            grid[i][j] = preSortArr[i-area[0]+1][j-area[1]+1]
        }
    }
    return grid
}

// 以下为考题输入输出框架,此部分代码不建议改动
func main() {
    reader := bufio.NewReader(os.Stdin)
    matrixStr := readMatrixString(reader)
    areaStr := readInputString(reader)
    sortColsStr := readInputString(reader)

    grid := parse2DIntArrayFromJson(matrixStr)
    area := parseIntArrayFromJson(areaStr)
    sortCols := parseIntArrayFromJson(sortColsStr)
    result := sortTable(grid, area, sortCols)
    printResult(result)
}

func printResult(result [][]int) {
    // 将数组转换为 JSON 字符串
    bytes, err := json.Marshal(result)
    if err != nil {
        return
    }
    str := string(bytes)
    re := regexp.MustCompile(`(\d),`)
    str = re.ReplaceAllString(str, `$1, `) // 在逗号右边加空格
    str = strings.ReplaceAll(str, "],", "],\n")
    fmt.Println(str)
}

func readMatrixString(reader *bufio.Reader) string {
    var inputs string
    for {
        inputs += readInputString(reader)
        if strings.Count(inputs, "]]") >= 1 {
            break
        }
    }
    return inputs
}

// 解析JSON字符串为一维整型数组
func parseIntArrayFromJson(jsonStr string) []int {
    var arr []int
    err := json.Unmarshal([]byte(jsonStr), &arr)
    if err != nil {
        fmt.Println("error! Invalid input.")
    }
    return arr
}

// 解析JSON字符串为二维整型数组
func parse2DIntArrayFromJson(jsonStr string) [][]int {
    var arr [][]int
    err := json.Unmarshal([]byte(jsonStr), &arr)
    if err != nil {
        fmt.Println("error! Invalid input.")
    }
    return arr
}

func readInputString(reader *bufio.Reader) string {
    lineBuf, err := reader.ReadString('\n')
    if err != nil && err != io.EOF {
        return "nil"
    }
    lineBuf = strings.TrimRight(lineBuf, "\r\n")
    lineBuf = strings.TrimSpace(lineBuf)
    return lineBuf
}
View Code