题目描述
小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 //字典序 } }
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 }