自学内容网 自学内容网

(仓颉) Cangjie 刷力扣基础语法小结

🧓官方资料

三方在线 IDE

(个人测试下来该三方比官方的在线 ide 好用,但是目前编译器的版本比较落后)

本文编写时间的仓颉版公测版本为:Cangjie 0.53.13 Beta

叠甲:笔者并非专门研究仓颉,本文中仅是对于使用仓颉在力扣刷题的一些基础总结。

文中难免有些错误,且仓颉正在快速发展中,可能过段时间有些东西就不对了。请自我甄别。

🧓力扣经典前 3 题

本文编写时间的力扣的仓颉版本为:Cangjie 0.53.11

在这里插入图片描述

且目前力扣还未所有题目都支持仓颉,当然应该会慢慢补全的,大家等等期待吧。

下面直接以实际 ac 代码进行讲解。不考虑包。

因为都是典中典的题目,就不放题意和思路了。

🕷️1. 两数之和 - 力扣(LeetCode)

class Solution {
    func twoSum(nums: Array<Int64>, target: Int64): Array<Int64> {
        let ans = [0, 0]

        for (i in 0..nums.size) {
            for (j in (i + 1)..nums.size) {
                if (nums[i] + nums[j] == target) {
                    ans[0] = i
                    ans[1] = j
                    return ans
                }
            }
        }

        []
    }
}
  • 数据类型

    • 值类型,如:基础数据类型,struct
    • 引用类型,如:class, Array
  • 变量声明关键字

    • var 表示可变
    • let 表示不可变(若是引用类型,仅表示应用关系不可变)
  • structclass

    • 虽然一些简单情况看起来差不多,但这两个有很大不同
    • struct 值类型,this 是值
    • class 应用类型,this 是应用
    • class 可继承
    • 等等(不展开说了)
  • 函数

    • 返回值以尾缀返回的形式表示
    • 函数参数不得修改
  • 字面量

    • 普通数字的字面量默认是 Int64
  • 表达式

    • 凡是可求值的语言元素都是表达式
    • 因此函数的最后可以不写 return,直接写要返回的内容,比如上方代码中的 [],会正确匹配到返回值: Array<Int64>
  • 循环

    • for in 循环,仓颉中的没有三段式的for,只有范围for

    • 想自由控制循环用while

    • 0..nums.size区间类型的简写

      •   // [0, 10]
          for (i in 0..=10) 
          // [0, 10)
          for (i in 0..10)
        
  • 数组

    • 数组长度不可变

    • 可变数组可用 ArrayList

    • 数组长度通过size获取,是属性不是函数

    • 数组字面量用中括号表示,如[0, 1, 2] 表示长度为 3 内是 1, 2, 3 的数组

    • [1, 2, 3] 等效于 Array<Int64>(3, {i => i})

    • Array两种常见的初始化方式

      •   // 空初始化
          let a = Array<Int64>()
          // 拷贝
          let b = Array<Int64>(a)
          // item:<内容> 
          // 注意,这个方式初始化是`引用`初始化
          let c = Array<Int64>(3, item: 0)
          // 使用 lambda 初始化
          let d = Array<Int64>(3, {i => i + 1})
        
class Solution {
    func twoSum(nums: Array<Int64>, target: Int64): Array<Int64> {
        let mp = HashMap<Int64, Int64>()
        for (i in 0..nums.size) {
            let d = target - nums[i]
            if (mp.contains(d)) {
                return [mp[d], i]
            }
            mp.put(nums[i], i)
        }

        return [-1, -1]
    }
}

std.collection 包

public class HashMap<K, V> <: Map<K, V> where K <: Hashable & Equatable<K> {
    public init()
    public init(elements: Collection<(K, V)>)
    public init(elements: Array<(K, V)>)
    public init(capacity: Int64)
    public init(size: Int64, initElement: (Int64) -> (K, V))
}

HashMap 是基础的Collection类型,是类不是结构体

  • 常用函数
    • contains
    • put
    • putAll
    • remove
    • get
    • keys
    • values
  • 有重载的 operator[]
  • 若直接取未存储的键,则报异常

🕷️2. 两数相加 - 力扣(LeetCode)

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     public var val: Int64
 *     public var next: ?ListNode
 *     public init() {
 *         val = 0
 *         next = None
 *     }
 *     public init(val: Int64) {
 *         this.val = val
 *         next = None
 *     }
 * }
 */

class Solution {
    func addTwoNumbers(l1: ?ListNode, l2: ?ListNode): ?ListNode {
        var (p1, p2) = (l1, l2)
        var head = ListNode()
        var dummy = head

        var carry = 0
        var val = 0
        while (p1.isSome() || p2.isSome()) {
            var x = 0
            if (p2.isNone()) {
                x = carry + p1.getOrThrow().val
                p1 = p1.getOrThrow().next
            } else if (p1.isNone()) {
                x = carry + p2.getOrThrow().val
                p2 = p2.getOrThrow().next
            } else {
                x = carry + (p1.getOrThrow().val) + (p2?.val ?? 0)
                p1 = p1.getOrThrow().next
                p2 = p2?.next ?? None
            }

            carry = x / 10
            var node = ListNode(x % 10)
            dummy.next = node
            dummy = node
        }

        if (carry != 0) {
            dummy.next = ListNode(carry)
        }
        return head.next
    }
}

这里抛出仓颉一个非常重要的内容,Option<T>

在这里插入图片描述

Option<T> 是一个非常重要的类型。

充斥着仓颉的各个地方,因为可以使用 Option<T> 来避免空指针。

  • 可以使用运算符?来表示类型
  • 可以用??语法糖来取值,如:p ?? None
  • 可以使用?.语法糖来取值, 如:p?.next ?? None

🕷️3. 无重复字符的最长子串 - 力扣(LeetCode)

class Solution {
    func lengthOfLongestSubstring(s: String): Int64 {
        let n = s.size

        var ans = 0
        var vis = HashSet<Rune>()
        for (i in 0..n) {
            // expected 'Rune', found 'UInt8'
            let ch = Rune(s[i])
            while (vis.contains(ch)) {
                let pre = Rune(s[i - vis.size])
                vis.remove(pre)
            }
            vis.put(ch)

            ans = max(ans, vis.size)
        }
        return ans
    }
}

struct String

public struct String <: Collection<Byte> & Equatable<String> & Comparable<String> & Hashable & ToString {
    public static const empty: String
    public const init()
    public init(value: Array<Rune>)
    public init(value: Collection<Rune>)
}

仓颉本身具有字符类型,Rune

Stringutf-8 的类型

  • 字符串不得修改

  • opertor[] 返回的类型是 Bytepublic type Byte = UInt8

  • 可以转为字符数组等形式进行操作

    •   public func toArray(): Array<Byte>
        public func toRuneArray(): Array<Rune>
      
  • RuneUInt8不能直接进行运算,建议统一转化为UInt32进行操作

⭐END

🌟交流方式

关注我,学习更多C/C++,python,算法,软件工程,计算机知识!

⭐交流方式⭐ |C/C++|算法|设计模式|软件架构-CSDN社区

B站

👨‍💻主页:天赐细莲 bilibili


原文地址:https://blog.csdn.net/CUBE_lotus/article/details/144408136

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!