你说得对!Kotlin 和 Python 的函数式编程确实可以更简洁地实现这个逻辑。让我展示一下:
Kotlin 版本
kotlin
// Kotlin: 一行代码找出水仙花数
fun main() {
// 找出所有三位数的水仙花数
val narcissisticNumbers = (100..999).filter { n ->
n.toString().map {
(it - '0').toDouble().pow(n.toString().length.toDouble()).toInt()
}.sum() == n
}
println("水仙花数: $narcissisticNumbers")
// 更简洁的写法(使用 digitToInt)
val narcissistic2 = (100..999).filter { n ->
n.toString().map {
val digit = it.digitToInt()
Math.pow(digit.toDouble(), n.toString().length.toDouble()).toInt()
}.sum() == n
}
println("水仙花数: $narcissistic2")
// 使用扩展函数让代码更易读
val narcissistic3 = (100..999).filter { it.isNarcissistic() }
println("水仙花数: $narcissistic3")
}
// 扩展函数
fun Int.isNarcissistic(): Boolean {
val digits = this.toString().map(Char::digitToInt)
val power = digits.size
return digits.sumOf { Math.pow(it.toDouble(), power.toDouble()).toInt() } == this
}
Python 版本
python
# Python: 一行代码找出水仙花数
# 方法1: 使用列表推导式
narcissistic_numbers = [
n for n in range(100, 1000)
if sum(int(d) ** len(str(n)) for d in str(n)) == n
]
print(f"水仙花数: {narcissistic_numbers}")
# 方法2: 使用filter和lambda
narcissistic_numbers2 = list(filter(
lambda n: sum(int(d) ** len(str(n)) for d in str(n)) == n,
range(100, 1000)
))
print(f"水仙花数: {narcissistic_numbers2}")
# 方法3: 更函数式的写法(使用map)
def is_narcissistic(n):
s = str(n)
power = len(s)
return sum(map(lambda d: int(d) ** power, s)) == n
narcissistic_numbers3 = list(filter(is_narcissistic, range(100, 1000)))
print(f"水仙花数: {narcissistic_numbers3}")
# 一行代码的终极版
print(f"水仙花数: {[n for n in range(100, 1000) if n == sum(int(d)**len(str(n)) for d in str(n))]}")
# 扩展到任意位数
def find_narcissistic(start, end):
return [
n for n in range(start, end + 1)
if n == sum(int(d) ** len(str(n)) for d in str(n))
]
print(f"1-10000的水仙花数: {find_narcissistic(1, 10000)}")
对比分析
Kotlin vs Python 的简洁性:
Python 更胜一筹:
python
# Python (最简洁)
[n for n in range(100,1000) if sum(int(d)**len(str(n)) for d in str(n))==n]
Kotlin 略显冗长:
kotlin
// Kotlin
(100..999).filter { n ->
n.toString().map { (it - '0').pow(n.toString().length) }.sum() == n
}
C++20 Ranges 版本对比
虽然 C++ 也能实现类似逻辑,但代码确实更长:
cpp
// C++20 Ranges 版本
auto narcissistic = std::views::iota(100, 1000)
| std::views::filter([](int n) {
std::string s = std::to_string(n);
int power = s.length();
return std::accumulate(s.begin(), s.end(), 0,
[power](int sum, char c) {
int digit = c - '0';
return sum + static_cast<int>(std::pow(digit, power));
}) == n;
});
为什么 Python/Kotlin 更简洁?
- 内置类型转换:str(n) 直接转换
- 推导式/序列操作:Python的列表推导式,Kotlin的集合操作
- 动态类型:无需声明类型
- 幂运算符:Python的 ** 比 std::pow 简洁
- 链式调用:更自然的函数式编程支持
性能考虑
虽然 Python/Kotlin 代码更简洁,但 C++ 在性能上有优势:
cpp
// C++ 性能优化版(避免字符串转换)
auto isNarcissisticOptimized(int n) -> bool {
int original = n;
int sum = 0;
int digits = 0;
// 计算位数
int temp = n;
while (temp > 0) {
digits++;
temp /= 10;
}
// 计算幂次和
temp = original;
while (temp > 0) {
int digit = temp % 10;
sum += static_cast<int>(std::pow(digit, digits));
temp /= 10;
}
return sum == original;
}
总结
特性 Python Kotlin C++20 Ranges
简洁性 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐
性能 ⭐⭐ ⭐⭐⭐ ⭐⭐⭐⭐⭐
类型安全 ⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐
函数式支持 ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐
可读性 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐
Python 和 Kotlin 在表达这种算法时确实更优雅,而 C++ 在性能和类型安全上更有优势。选择哪种语言取决于你的具体需求!