with one click
cangjie-algorithm
仓颉语言算法与数据结构实现参考——排序、搜索、动态规划、图算法、字符串处理、集合操作的惯用写法和模板代码
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
仓颉语言算法与数据结构实现参考——排序、搜索、动态规划、图算法、字符串处理、集合操作的惯用写法和模板代码
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
通用算法与数据结构实现参考——排序、搜索、动态规划、图算法、字符串处理的多语言惯用写法和模板代码(Python/C++/Java/Go/Cangjie)
仓颉编程语言基本概念和规则,当需要了解关键字、标识符、程序结构、变量定义(let/var/const)、值类型与引用类型、作用域规则、表达式(if/while/for-in/break/continue)、函数等基本概念时,应使用此 Skill
仓颉语言基本数据类型。当需要了解仓颉语言的整数、浮点、布尔、字符(Rune)、字符串(String)、Unit、Nothing、元组(Tuple)、数组(Array/VArray)、区间(Range)类型以及基本运算符的语法和规则时,应使用此 Skill。
仓颉程序与C程序互操作指导,包括foreign声明、CFunc、inout参数、unsafe块、调用约定、类型映射(基础类型/结构体/CPointer/VArray/CString)、C回调仓颉、内存管理等特性时,应使用此 Skill
仓颉语言类。当需要了解仓颉语言的类定义、抽象类、构造函数(init/主构造函数)、终结器(~init)、继承(单继承/sealed)、重写(override)、重定义(redef)、成员变量、成员函数、属性(prop)、访问修饰符、This类型、对象创建等特性时,应使用此 Skill。
提供仓颉集合数据类型使用文档,包括Array/ArrayList/HashMap/HashSet
| name | cangjie-algorithm |
| description | 仓颉语言算法与数据结构实现参考——排序、搜索、动态规划、图算法、字符串处理、集合操作的惯用写法和模板代码 |
| mode | cangjie |
import std.collection.*
import std.sort.*
// Array 排序(原地)
var arr: Array<Int64> = [5, 3, 1, 4, 2]
arr.sortBy { a, b => a - b } // 升序
arr.sortBy { a, b => b - a } // 降序
import std.collection.*
let list = ArrayList<Int64>([3, 1, 4, 1, 5])
// 转为 Array 排序后使用
var arr = list.toArray()
arr.sortBy { a, b => a - b }
import std.collection.*
import std.sort.*
struct Student {
let name: String
let score: Int64
}
var students = [Student("Alice", 90), Student("Bob", 85)]
students.sortBy { a, b => b.score - a.score } // 按分数降序
class Point <: Comparable<Point> & Equatable<Point> {
let x: Int64
let y: Int64
public init(x: Int64, y: Int64) {
this.x = x
this.y = y
}
public func compareTo(other: Point): Int64 {
if (this.x != other.x) { return this.x - other.x }
return this.y - other.y
}
public operator func ==(other: Point): Bool {
this.x == other.x && this.y == other.y
}
public operator func !=(other: Point): Bool {
!(this == other)
}
}
func binarySearch(arr: Array<Int64>, target: Int64): Int64 {
var lo: Int64 = 0
var hi: Int64 = arr.size - 1
while (lo <= hi) {
let mid = lo + (hi - lo) / 2
if (arr[mid] == target) { return mid }
if (arr[mid] < target) { lo = mid + 1 } else { hi = mid - 1 }
}
return -1 // 未找到
}
func lowerBound(arr: Array<Int64>, target: Int64): Int64 {
var lo: Int64 = 0
var hi: Int64 = arr.size
while (lo < hi) {
let mid = lo + (hi - lo) / 2
if (arr[mid] < target) { lo = mid + 1 } else { hi = mid }
}
return lo
}
import std.collection.*
let map = HashMap<String, Int64>()
map.put("apple", 3)
let count = map.get("apple") ?? 0 // 不存在时返回默认值 0
func climbStairs(n: Int64): Int64 {
if (n <= 2) { return n }
var prev2: Int64 = 1
var prev1: Int64 = 2
for (_ in 3..=n) {
let cur = prev1 + prev2
prev2 = prev1
prev1 = cur
}
return prev1
}
func lcs(a: String, b: String): Int64 {
let m = a.size
let n = b.size
let runesA = a.toRuneArray()
let runesB = b.toRuneArray()
// dp[i][j] = LCS length of a[0..i) and b[0..j)
var dp = Array<Array<Int64>>(m + 1, { _ => Array<Int64>(n + 1, { _ => 0 }) })
for (i in 1..=m) {
for (j in 1..=n) {
if (runesA[i - 1] == runesB[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + 1
} else {
dp[i][j] = if (dp[i - 1][j] > dp[i][j - 1]) { dp[i - 1][j] } else { dp[i][j - 1] }
}
}
}
return dp[m][n]
}
func knapsack(weights: Array<Int64>, values: Array<Int64>, capacity: Int64): Int64 {
let n = weights.size
var dp = Array<Int64>(capacity + 1, { _ => 0 })
for (i in 0..n) {
for (w in (weights[i]..=capacity).step(-1)) {
let candidate = dp[w - weights[i]] + values[i]
if (candidate > dp[w]) { dp[w] = candidate }
}
}
return dp[capacity]
}
class ListNode {
var value: Int64
var next: ?ListNode
public init(value: Int64) {
this.value = value
this.next = None
}
}
// 遍历链表
func traverse(head: ?ListNode): Unit {
var cur = head
while (true) {
match (cur) {
case Some(node) =>
println("${node.value}")
cur = node.next
case None => break
}
}
}
class TreeNode {
var value: Int64
var left: ?TreeNode
var right: ?TreeNode
public init(value: Int64) {
this.value = value
this.left = None
this.right = None
}
}
// 中序遍历
func inorder(node: ?TreeNode): Unit {
match (node) {
case Some(n) =>
inorder(n.left)
println("${n.value}")
inorder(n.right)
case None => ()
}
}
// 树的最大深度
func maxDepth(node: ?TreeNode): Int64 {
match (node) {
case None => 0
case Some(n) =>
let l = maxDepth(n.left)
let r = maxDepth(n.right)
1 + (if (l > r) { l } else { r })
}
}
import std.collection.*
// 图用 HashMap<Int64, ArrayList<Int64>> 表示邻接表
func buildGraph(edges: Array<(Int64, Int64)>): HashMap<Int64, ArrayList<Int64>> {
let graph = HashMap<Int64, ArrayList<Int64>>()
for ((u, v) in edges) {
if (graph.get(u) == None) { graph.put(u, ArrayList<Int64>()) }
if (graph.get(v) == None) { graph.put(v, ArrayList<Int64>()) }
(graph.get(u) ?? ArrayList<Int64>()).append(v)
(graph.get(v) ?? ArrayList<Int64>()).append(u) // 无向图
}
return graph
}
import std.collection.*
func bfs(graph: HashMap<Int64, ArrayList<Int64>>, start: Int64): ArrayList<Int64> {
let visited = HashSet<Int64>()
let queue = ArrayList<Int64>()
let result = ArrayList<Int64>()
queue.append(start)
visited.put(start)
while (queue.size > 0) {
let node = queue[0]
queue.remove(0)
result.append(node)
let neighbors = graph.get(node) ?? ArrayList<Int64>()
for (next in neighbors) {
if (!visited.contains(next)) {
visited.put(next)
queue.append(next)
}
}
}
return result
}
import std.collection.*
func dfs(graph: HashMap<Int64, ArrayList<Int64>>, start: Int64): ArrayList<Int64> {
let visited = HashSet<Int64>()
let result = ArrayList<Int64>()
func visit(node: Int64): Unit {
if (visited.contains(node)) { return }
visited.put(node)
result.append(node)
let neighbors = graph.get(node) ?? ArrayList<Int64>()
for (next in neighbors) {
visit(next)
}
}
visit(start)
return result
}
let s = "hello world"
let len = s.size // 长度
let sub = s[0..5] // 子串 "hello" (左闭右开)
let upper = s.toAsciiUpper() // 转大写
let parts = s.split(" ") // 分割为 Array<String>
let contains = s.contains("world") // 是否包含
let idx = s.indexOf("world") // 查找位置,返回 ?Int64
let s = "hello"
// 按 Rune 遍历
for (ch in s) {
println("${ch}")
}
// 转为 Rune 数组后按索引操作
let runes = s.toRuneArray()
let first = runes[0] // 'h'
// 频繁拼接场景使用 StringBuilder
import std.io.*
let sb = StringBuilder()
for (i in 0..10) {
sb.append("${i} ")
}
let result = sb.toString()
| 算法模式 | 仓颉惯用写法 |
|---|---|
| 交换两个变量 | var a = 1; var b = 2; let tmp = a; a = b; b = tmp |
| 取最大/最小值 | let mx = if (a > b) { a } else { b } |
| 绝对值 | let abs = if (x >= 0) { x } else { -x } |
| 整数除法向下取整 | 仓颉整数除法默认截断(同 C),向下取整自然满足 |
| 取模 | a % b(结果符号与被除数相同) |
| 幂运算 | import std.math.*; let p = pow(2.0, 10.0) (Float64) |
| 无穷大 | import std.math.*; let INF = Int64.Max |
| 二维数组初始化 | Array<Array<Int64>>(m, { _ => Array<Int64>(n, { _ => 0 }) }) |
| 数组复制 | let copy = Array<Int64>(arr.size, { i => arr[i] }) |
| 字符转数字 | let digit = (ch.toInt64()) - ('0'.toInt64()) |
| 数字转字符串 | "${number}" 或 number.toString() |
Array<T> 固定长度,访问 O(1),不能增删元素;ArrayList<T> 动态长度,尾部 append O(1) 摊还,头部 insert/remove O(n)+/${},避免 O(n^2) 复杂度0..n Range 迭代是零分配的,优先使用