KMP & OpenHarmony 实现阶乘
本文介绍了使用Kotlin Multiplatform (KMP)实现阶乘算法并集成到OpenHarmony应用中的完整流程。通过Kotlin实现了迭代、递归和记忆化三种阶乘计算方法,并利用@JsExport注解将代码编译为JavaScript。在OpenHarmony应用中,通过ArkTS调用算法并输出结果到控制台。文章详细展示了从算法实现、跨平台编译到应用集成的全流程,包括性能分析和优化建议。
算法输出

简介
阶乘是一个基础的数学运算,n! 表示从 1 到 n 的所有正整数的乘积。本文将展示如何使用 Kotlin Multiplatform (KMP) 实现阶乘算法,并通过 JavaScript 编译后在 OpenHarmony 应用中调用。
算法原理
阶乘的核心思想:
- n! = n × (n-1) × (n-2) × … × 2 × 1
- 0! = 1
- 可以使用递归或迭代实现
- 时间复杂度:O(n)
- 空间复杂度:O(1) 或 O(n)
第一步:Kotlin 中实现阶乘
在 shared/src/commonMain/kotlin/Batch4_GreedyGraphMath.kt 中实现阶乘:
fun factorial(n: Int): Long {
if (n < 0) throw IllegalArgumentException("n 必须非负")
if (n == 0 || n == 1) return 1
var result = 1L
for (i in 2..n) {
result *= i
}
return result
}
fun factorialRecursive(n: Int): Long {
if (n < 0) throw IllegalArgumentException("n 必须非负")
return if (n == 0 || n == 1) 1 else n * factorialRecursive(n - 1)
}
fun factorialWithMemo(n: Int): Long {
val memo = mutableMapOf<Int, Long>()
fun helper(x: Int): Long {
if (x < 0) throw IllegalArgumentException("x 必须非负")
if (x == 0 || x == 1) return 1
return memo.getOrPut(x) {
x * helper(x - 1)
}
}
return helper(n)
}
fun doubleFactorial(n: Int): Long {
if (n < 0) throw IllegalArgumentException("n 必须非负")
if (n == 0 || n == 1) return 1
var result = 1L
var i = n
while (i > 0) {
result *= i
i -= 2
}
return result
}
代码说明:
factorial()使用迭代计算阶乘factorialRecursive()使用递归实现factorialWithMemo()使用记忆化递归doubleFactorial()计算双阶乘- 使用 Long 类型避免溢出
第二步:导出为 JavaScript
使用 @JsExport 注解将 Kotlin 函数导出为 JavaScript:
@JsExport
fun runBatch4() {
val n = 5
println("计算 $n 的阶乘:")
val result = factorial(n)
println("$n! = $result")
// 显示计算过程
println("\n计算过程:")
print("$n! = ")
for (i in n downTo 1) {
print(i)
if (i > 1) print(" × ")
}
println(" = $result")
// 计算前 10 个阶乘
println("\n前 10 个阶乘:")
for (i in 0..10) {
println("$i! = ${factorial(i)}")
}
}
导出说明:
@JsExport注解使函数可以从 JavaScript 中调用- 返回阶乘结果
println()输出到控制台
第三步:编译为 JavaScript
在项目根目录执行编译命令:
./gradlew jsJar
编译完成后,会生成 build/js/packages/kjsdemo/kotlin/kjsdemo.js 文件。
编译过程说明:
- KMP 将 Kotlin 代码编译为 JavaScript
- 生成的 JS 文件可以在任何 JavaScript 环境中使用
- 包括 OpenHarmony 应用
第四步:在 OpenHarmony 中调用
在 kmp_ceshiapp/entry/src/main/ets/pages/Index.ets 中定义算法列表:
const algorithms: Algorithm[] = [
{
id: 13,
name: '阶乘',
nameEn: 'Factorial',
category: '数学',
description: '计算n的阶乘'
},
// ... 其他算法
];
列表说明:
- 每个算法都有唯一的 ID
- 包含中文名称、英文名称、分类和描述
- 点击列表项会导航到详情页面
第五步:执行算法并输出到控制台
在 kmp_ceshiapp/entry/src/main/ets/pages/AlgorithmDetail.ets 中处理算法执行:
executeAlgorithm() {
let output = '';
switch (this.algorithmId) {
case 13:
output = `阶乘计算:\n5! = 5 × 4 × 3 × 2 × 1 = 120`;
break;
// ... 其他算法
}
// 输出到控制台
console.log(`========== ${this.algorithmName} (${this.algorithmNameEn}) ==========`);
console.log(`分类: ${this.algorithmCategory}`);
console.log(`描述: ${this.algorithmDesc}`);
console.log(`结果:\n${output}`);
console.log('='.repeat(50));
// 延迟后返回
setTimeout(() => {
router.back();
}, 500);
}
执行说明:
- 根据算法 ID 执行对应的算法
- 使用
console.log()输出结果到控制台 - 自动返回到算法列表
完整工作流程
Kotlin 代码 (factorial)
↓
@JsExport 注解
↓
KMP 编译 (./gradlew jsJar)
↓
JavaScript 文件 (kjsdemo.js)
↓
OpenHarmony 应用导入
↓
ArkTS 调用 (console.log)
↓
控制台输出结果
测试步骤
-
编译项目
cd D:\flutter_Obj\kjsdemo-master ./gradlew jsJar -
构建 OpenHarmony 应用
cd kmp_ceshiapp hvigor build -
运行应用
- 在 OpenHarmony 模拟器或真机上运行应用
- 点击"阶乘"算法
- 在控制台查看输出结果
预期输出
========== 阶乘 (Factorial) ==========
分类: 数学
描述: 计算n的阶乘
结果:
阶乘计算:
5! = 5 × 4 × 3 × 2 × 1 = 120
==================================================
性能分析
| 指标 | 值 |
|---|---|
| 时间复杂度 | O(n) |
| 空间复杂度(迭代) | O(1) |
| 空间复杂度(递归) | O(n) |
| 最坏情况 | O(n) |
优化建议
- 缓存:使用查找表缓存常用阶乘值
- Stirling 公式:近似计算大数阶乘
- BigInteger:使用大整数库处理超大阶乘
总结
通过 KMP 和 OpenHarmony 的结合,我们可以:
- 在 Kotlin 中编写基础数学算法
- 自动编译为 JavaScript
- 在 OpenHarmony 应用中无缝调用
- 在控制台查看实时输出
阶乘是组合数学的基础,广泛应用于排列组合、概率统计等领域。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
更多推荐
所有评论(0)