Flutter 之 InheritedWidget
InheritedWidget
是 Flutter 框架中的一个重要类,用于在 Widget 树中共享数据。它是 Flutter 中数据传递和状态管理的基础之一。通过 InheritedWidget
,你可以让子 Widget 在不需要显式传递数据的情况下,访问祖先 Widget 中的数据。这种机制对于跨多个层次的 Widget 共享状态非常有效。
目录
- 一、 为什么会有 `InheritedWidget`?
- 二、`InheritedWidget` 的基本工作原理
- 三、`InheritedWidget` 的解决问题
- 四、 `InheritedWidget` 的使用例子
- 五、 `InheritedWidget` 和性能
- 六、疑问
- 1、InheritedWidget只能是父组件状态传递到子组件不能子组件传递到父组件吗
- 1、父组件到子组件的数据传递
- 2、为什么不支持子组件传递到父组件?
- 2、子组件的数据如何传递给父组件
- 1. 回调函数(Callback)
- 2. 状态提升(Lift State Up)
- 总结
- 3、兄弟组件如何共享数据
- 1. 通过父组件传递数据
- 示例代码:
- 2. 使用 `InheritedWidget` 或 `InheritedModel`
- 使用 `InheritedWidget` 共享数据:
- 3. 使用 `Provider` 包
- 七、总结
一、 为什么会有 InheritedWidget
?
在 Flutter 中,Widget 树是单向的,意味着数据从上层(父 Widget)流向下层(子 Widget)。而 Flutter 中的 Widget 是不可变的,也就是说,你不能直接修改它们的状态。因此,当需要跨多个 Widget 层次传递状态或共享数据时,通常会遇到两类问题:
- **属性传递:**如果需要共享的数据传递层级过多,父 Widget 必须将数据一层一层地传递给子 Widget,直到最需要这个数据的 Widget。这个过程会导致代码变得冗长,维护困难。
- 数据共享: 在某些情况下,多个子 Widget 可能需要访问同一个数据源,这种情况下,直接通过构造函数传递数据显得非常不方便,尤其是在较深的 Widget 树中。
InheritedWidget
的出现正是为了解决这两个问题,它让 Widget 树中的任何子 Widget 可以便捷地访问到祖先 Widget 提供的数据,而不必显式地传递给每一个子 Widget。
二、InheritedWidget
的基本工作原理
InheritedWidget
是一个可以在 Widget 树中传播数据的 Widget。它通过实现 updateShouldNotify
方法来通知下层的 Widget,当数据发生变化时,这些 Widget 会重新构建(rebuild),从而获取新的数据。
- 当
InheritedWidget
发生变化时,它会通过notifyClients
方法通知所有依赖于它的 Widget。 - 在 Widget 树中的下层 Widget 可以通过
of
方法获取到祖先 Widget 提供的状态(数据)。
三、InheritedWidget
的解决问题
- 跨越多层 Widget 树传递数据: 在 Widget 树的上层将数据放入
InheritedWidget
中后,所有的子 Widget 可以访问到该数据,而不需要通过构造函数一层一层地传递。 - 避免重复构建: 当
InheritedWidget
的数据发生变化时,只有依赖该数据的 Widget 会重新构建。其他不依赖该数据的 Widget 会保持不变,优化了性能。 - 简化状态管理:
InheritedWidget
是许多状态管理解决方案(如Provider
、Riverpod
等)的基础,提供了一个简单且高效的方式来管理和共享状态。
四、 InheritedWidget
的使用例子
import 'package:flutter/material.dart';// 创建一个自定义的 InheritedWidget
class MyInheritedWidget extends InheritedWidget {final int counter;MyInheritedWidget({required Widget child, required this.counter}) : super(child: child);// 判断是否需要通知下层 Widget 更新 bool updateShouldNotify(MyInheritedWidget oldWidget) {return counter != oldWidget.counter;}// 提供获取数据的方法static MyInheritedWidget? of(BuildContext context) {return context.dependOnInheritedWidgetOfExactType<MyInheritedWidget>();}
}// 一个使用 InheritedWidget 的子 Widget
class CounterDisplay extends StatelessWidget {Widget build(BuildContext context) {final inheritedWidget = MyInheritedWidget.of(context);return Text('Counter: ${inheritedWidget?.counter ?? 0}');}
}void main() {runApp(MyApp());
}class MyApp extends StatelessWidget {int counter = 0;Widget build(BuildContext context) {return MaterialApp(home: Scaffold(appBar: AppBar(title: Text('InheritedWidget Example')),body: MyInheritedWidget(counter: counter,child: Column(mainAxisAlignment: MainAxisAlignment.center,children: [CounterDisplay(),ElevatedButton(onPressed: () {counter++;// 由于 counter 变化,MyInheritedWidget 会通知子 Widget 更新},child: Text('Increment Counter'),),],),),),);}
}
在上面的代码中:
MyInheritedWidget
包含了一个counter
变量,它可以被下层的子 Widget 访问。CounterDisplay
使用MyInheritedWidget.of(context)
来获取并显示counter
的值。- 当按钮点击时,
counter
值增加并重新构建整个 Widget 树。
五、 InheritedWidget
和性能
虽然 InheritedWidget
可以帮助我们轻松共享数据,但它也有一些限制,尤其是在性能上:
- 仅依赖
InheritedWidget
的子 Widget 会重新构建,但这个重新构建的范围可能是你未预料到的。因此,要谨慎使用,避免不必要的性能损耗。 - 对于复杂的应用,可能会更倾向于使用一些更强大的状态管理工具(如
Provider
、Riverpod
)来简化使用和提升性能。
六、疑问
1、InheritedWidget只能是父组件状态传递到子组件不能子组件传递到父组件吗
是的,InheritedWidget
的设计原则是从父组件向下传递数据,而不是从子组件向父组件传递数据。它主要用于共享 不可变的数据,或者是一些全局状态(如主题、语言、配置等),并使得在 InheritedWidget
树下的子 Widget 可以访问这些数据。
1、父组件到子组件的数据传递
InheritedWidget
允许父组件通过它传递数据到子组件。子组件通过 of
方法获取父组件(或祖先组件)中提供的状态或数据。例如,你可以通过一个 InheritedWidget
在树的上层传递一些数据(如计数器值),然后让树下的任何子组件获取该数据。
2、为什么不支持子组件传递到父组件?
InheritedWidget
是单向数据流的模型,它不支持反向传递(即子组件直接通知父组件更新)。这是因为 InheritedWidget
主要用于 数据共享,而不是 数据修改。其主要目的是提供一种高效的方式来向下共享数据,而不涉及子组件控制父组件的行为。
2、子组件的数据如何传递给父组件
要从子组件传递数据回父组件,通常有两种方式:
1. 回调函数(Callback)
子组件通过调用父组件传入的回调函数将数据或事件传递给父组件。父组件可以在回调函数中处理数据,并更新状态。
import 'package:flutter/material.dart';class ParentWidget extends StatefulWidget { _ParentWidgetState createState() => _ParentWidgetState();
}class _ParentWidgetState extends State<ParentWidget> {int counter = 0;void _incrementCounter() {setState(() {counter++;});}Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('Parent to Child Example')),body: Column(children: [Text('Counter: $counter'),ChildWidget(onPressed: _incrementCounter), // 传递回调函数],),);}
}class ChildWidget extends StatelessWidget {final VoidCallback onPressed; // 回调函数ChildWidget({required this.onPressed});Widget build(BuildContext context) {return ElevatedButton(onPressed: onPressed, // 触发父组件传递的回调child: Text('Increment Counter'),);}
}void main() {runApp(MaterialApp(home: ParentWidget()));
}
在这个例子中:
ParentWidget
通过onPressed
回调函数传递给ChildWidget
。ChildWidget
点击按钮时会调用onPressed
回调,通知父组件更新counter
。
2. 状态提升(Lift State Up)
如果需要共享和修改状态,可以将状态提升到最近的共同祖先组件,父组件和子组件都可以通过该祖先组件来管理和更新状态。通常,这种方式也与回调函数一起使用。
import 'package:flutter/material.dart';class ParentWidget extends StatefulWidget { _ParentWidgetState createState() => _ParentWidgetState();
}class _ParentWidgetState extends State<ParentWidget> {int counter = 0;void _updateCounter(int value) {setState(() {counter = value;});}Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('State Lifting Example')),body: Column(children: [Text('Counter: $counter'),ChildWidget(onCounterChanged: _updateCounter), // 状态提升],),);}
}class ChildWidget extends StatelessWidget {final Function(int) onCounterChanged; // 传递回调ChildWidget({required this.onCounterChanged});Widget build(BuildContext context) {return ElevatedButton(onPressed: () {onCounterChanged(5); // 修改父组件的状态},child: Text('Update Counter to 5'),);}
}void main() {runApp(MaterialApp(home: ParentWidget()));
}
总结
InheritedWidget
:主要用于将数据从父组件传递到子组件,子组件无法直接修改父组件的状态。- 回调函数和状态提升:是从子组件向父组件传递数据或修改父组件状态的常用方法。
3、兄弟组件如何共享数据
在 Flutter 中,兄弟组件(即同一个父组件下的不同子组件)之间共享数据通常有几种方式。以下是几种常见的实现方法:
1. 通过父组件传递数据
最简单的方式是通过父组件来协调兄弟组件之间的通信。父组件将共享数据传递给它的子组件,然后子组件通过回调函数将数据发送回父组件,父组件再将数据传递给另一个子组件。这样可以保持数据流的单向性。
示例代码:
import 'package:flutter/material.dart';class ParentWidget extends StatefulWidget { _ParentWidgetState createState() => _ParentWidgetState();
}class _ParentWidgetState extends State<ParentWidget> {int sharedData = 0;// 更新数据并通知所有子组件void updateSharedData(int newValue) {setState(() {sharedData = newValue;});}Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('Shared Data Between Siblings')),body: Column(children: [Text('Shared Data: $sharedData'),// 传递数据到子组件ChildWidget1(onDataChanged: updateSharedData),ChildWidget2(sharedData: sharedData),],),);}
}class ChildWidget1 extends StatelessWidget {final Function(int) onDataChanged;ChildWidget1({required this.onDataChanged});Widget build(BuildContext context) {return ElevatedButton(onPressed: () => onDataChanged(42), // 通过回调通知父组件更新数据child: Text('Update Data to 42'),);}
}class ChildWidget2 extends StatelessWidget {final int sharedData;ChildWidget2({required this.sharedData});Widget build(BuildContext context) {return Text('Child 2 sees Shared Data: $sharedData');}
}void main() {runApp(MaterialApp(home: ParentWidget()));
}
在这个例子中:
ParentWidget
维护了sharedData
,并通过updateSharedData
方法更新它。ChildWidget1
通过回调向父组件发送数据变更请求,父组件接收到数据后更新sharedData
。ChildWidget2
获取sharedData
,并显示它。
2. 使用 InheritedWidget
或 InheritedModel
如果你希望在多个兄弟组件之间共享数据,且不希望通过父组件直接传递数据,可以使用 InheritedWidget
或 InheritedModel
来共享数据。这两者能够在 Widget
树中向下传递数据,使得同一父级的多个子组件都可以访问这些数据。
使用 InheritedWidget
共享数据:
import 'package:flutter/material.dart';// 创建一个 InheritedWidget
class SharedData extends InheritedWidget {final int data;SharedData({required this.data, required Widget child}) : super(child: child);// 获取数据的静态方法static SharedData? of(BuildContext context) {return context.dependOnInheritedWidgetOfExactType<SharedData>();} bool updateShouldNotify(SharedData oldWidget) {return oldWidget.data != data;}
}class ParentWidget extends StatelessWidget {Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('Shared Data Using InheritedWidget')),body: SharedData(data: 100, // 共享数据child: Column(children: [ChildWidget1(),ChildWidget2(),],),),);}
}class ChildWidget1 extends StatelessWidget {Widget build(BuildContext context) {final sharedData = SharedData.of(context)?.data;return Text('Child 1 sees Shared Data: $sharedData');}
}class ChildWidget2 extends StatelessWidget {Widget build(BuildContext context) {final sharedData = SharedData.of(context)?.data;return Text('Child 2 sees Shared Data: $sharedData');}
}void main() {runApp(MaterialApp(home: ParentWidget()));
}
在这个例子中:
SharedData
继承自InheritedWidget
,用于在树下的多个子组件之间共享数据。ChildWidget1
和ChildWidget2
都可以通过SharedData.of(context)
获取共享的data
。
3. 使用 Provider
包
如果需要跨多个页面或者复杂的共享数据,可以使用 Flutter 的状态管理框架,如 Provider
。Provider
是一种比 InheritedWidget
更加简洁和灵活的解决方案。
七、总结
InheritedWidget
是 Flutter 中处理跨层次数据共享的基础工具。它能有效避免 “prop drilling” 问题,使得子 Widget 可以轻松访问祖先 Widget 的数据。它常常用作状态管理的基础,并且在 Flutter 中的许多第三方库和框架(如 Provider
)中都有广泛应用。
相关文章:
Flutter 之 InheritedWidget
InheritedWidget 是 Flutter 框架中的一个重要类,用于在 Widget 树中共享数据。它是 Flutter 中数据传递和状态管理的基础之一。通过 InheritedWidget,你可以让子 Widget 在不需要显式传递数据的情况下,访问祖先 Widget 中的数据。这种机制对…...
AI 助力开发新篇章:云开发 Copilot 深度体验与技术解析
本文 一、引言:技术浪潮中的个人视角1.1 AI 和低代码的崛起1.2 为什么选择云开发 Copilot? 二、云开发 Copilot 的核心功能解析2.1 自然语言驱动的低代码开发2.1.1 自然语言输入示例2.1.2 代码生成的模块化支持 2.2 实时预览与调整2.2.1 实时预览窗口功能…...
MyBatis-Plus介绍及基本使用
文章目录 概述介绍MyBatis-Plus 常用配置分页插件配置类注解配置 快速入门maven 依赖编写配置文件编写启动类编写 MybatisPlus 配置类 代码生成器:MybatisPlusGeneratormaven依赖代码生成器核心类 概述 介绍 MyBatis-Plus(简称 MP)是一个 M…...
SpringBoot 整合 Avro 与 Kafka
优质博文:IT-BLOG-CN 【需求】:生产者发送数据至 kafka 序列化使用 Avro,消费者通过 Avro 进行反序列化,并将数据通过 MyBatisPlus 存入数据库。 一、环境介绍 【1】Apache Avro 1.8;【2】Spring Kafka 1.2…...
支持JT1078和GB28181的流媒体服务器-LKM启动配置文件参数说明
流媒体服务器地址:https://github.com/lkmio/lkm GB28181信令,模拟多个国标设备工具:https://github.com/lkmio/gb-cms 文章目录 gop_cachegop_buffer_sizeprobe_timeoutwrite_timeoutmw_latencylisten_ippublic_ipidle_timeoutreceive_timeo…...
什么是隐式类型转换?隐式类型转换可能带来哪些问题? 显式类型转换(如强制类型转换)有哪些风险?
C 中的隐式类型转换 定义:在 C 中,隐式类型转换是指由编译器自动执行的类型转换,不需要程序员显式地进行操作。这种转换在很多情况下会自动发生,比如在表达式求值、函数调用传参等过程中。常见场景 算术运算中的转换:…...
量化交易新利器:阿布量化(AbuQuant)——金融研究者的得力助手
🚀 量化交易新利器:阿布量化(AbuQuant)——金融研究者的得力助手 🚀 文章目录 🚀 量化交易新利器:阿布量化(AbuQuant)——金融研究者的得力助手 🚀dz…...
UI设计从入门到进阶,全能实战课
课程内容: ├── 【宣导片】从入门到进阶!你的第一门UI必修课!.mp4 ├── 第0课:UI知识体系梳理 学习路径.mp4 ├── 第1课:IOS设计规范——基础规范与切图.mp4 ├── 第2课:IOS新趋势解析——模块规范与设计原则(上).mp4…...
Uniapp自动调整元素高度
获取设备的像素 如果你想让元素的高度相对于整个屏幕的高度占用一定的比例,可以通过获取屏幕的高度,然后计算出你想要的比例来设置元素的高度。以下是如何实现的示例: <script setup> import { ref, onMounted } from vue;// 定义一个…...
软考高项经验分享:我的备考之路与实战心得
软考,尤其是信息系统项目管理师(高项)考试,对于众多追求职业提升与专业认可的人士来说,是一场充满挑战与机遇的征程。我在当年参加软考高项的经历,可谓是一波三折,其中既有成功的喜悦࿰…...
安全关系型数据库查询新选择:Rust 语言的 rust-query 库深度解析
在当今这个数据驱动的时代,数据库作为信息存储和检索的核心组件,其重要性不言而喻。然而,对于开发者而言,如何在保证数据安全的前提下,高效地进行数据库操作却是一项挑战。传统的 SQL 查询虽然强大,但存在诸…...
《C++ 模型训练之早停法:有效预防过拟合的关键策略》
在 C 模型开发的复杂世界里,过拟合犹如一个潜藏的陷阱,常常使我们精心构建的模型在实际应用中表现大打折扣。而早停法(Early Stopping)作为一种行之有效的策略,能够帮助我们及时察觉模型训练过程中的异常,避…...
5.11【数据库】第一次实验
民宿预定,至少有不同的民宿,民宿下面有不同的房间(面积,房间编号) 房间类型,单价, 可预订以及不可预订 游客信息 订单信息 公司有很多课程, 学生,课程 每位学生每期…...
【CSS in Depth 2 精译_062】第 10 章 CSS 中的容器查询(@container)概述 + 10.1 容器查询的一个简单示例
当前内容所在位置(可进入专栏查看其他译好的章节内容) 【第十章 CSS 容器查询】 ✔️ 10.1 容器查询的一个简单示例 ✔️ 10.1.1 容器尺寸查询的用法 ✔️ 10.2 深入理解容器10.3 与容器相关的单位10.4 容器样式查询的用法10.5 本章小结 文章目录 第 10…...
蓝桥杯每日真题 - 第23天
题目:(直线) 题目描述(12届 C&C B组C题) 解题思路: 题目理解: 在平面直角坐标系中,从给定的点集中确定唯一的直线。 两点确定一条直线,判断两条直线是否相同,可通过…...
# Vue 入门级教程三
在前两篇 Vue 入门教程中,我们已经熟悉了 Vue 的基础语法、数据绑定、指令以及组件化开发等核心概念。在本教程中,我们将进一步探索 Vue 的高级特性,包括过滤器、自定义指令、过渡效果以及 Vue 与后端数据交互等内容,让你能够构建…...
hint: Updates were rejected because the tip of your current branch is behind!
问题 本地仓库往远段仓库推代码时候提示: error: failed to push some refs to 192.168.2.1:java-base/java-cloud.git hint: Updates were rejected because the tip of your current branch is behind! refs/heads/master:refs/heads/master [rejected] (…...
PHP 方头像转为圆图
业务需要把创建海报上的用户头像由方形转为圆形,前端的样式设置不能用。 故采用GD的函数来对方图进行裁剪处理为圆图。 目录 裁剪函数 本地图片 远程图片 效果 参考文章 总结 裁剪函数 从网上找的一个裁剪图片的函数。 代码如下: /* * 将图片切…...
centos 7 离线安装postgis插件
前一段时间记录了下如何在centos7中离线安装postgresql,因为工作需要,我不仅要安装postgresql,还需要安装postgis插件,这篇文章记录下postgis插件的安装过程。 1. 安装前的参考 如下的链接都是官网上的链接,对你安装p…...
pyinstaller打包的时候将ffmpeg也加进包中(包括打包文件夹的方法)
在使用 PyInstaller 打包包含 pydub 的 Python 应用程序时,由于 pydub 需要依赖 ffmpeg,你需要确保 ffmpeg 被正确包含进打包后的程序。以下是操作步骤: 1. 准备 ffmpeg 首先,确保你已经下载并安装了 ffmpeg。可以通过以下方式获取…...
JVM面试知识点1
内存结构(掌握内存结构划分、熟知各区域结构功能) 经典的JVM内存结构: 按照线程是否共享来划分: Heap (堆区) 1. 堆区的介绍 堆是 OOM 故障最主要的发生区域。它是内存区域中最大的一块区域,被所有线程共…...
wordpress
2024年自己建网站的步骤,新手自学建站教程 – 奶爸建站笔记 超详细图解:从 0 搭建一个个人网站,也太简单了吧 - 王一白 - 博客园 如何使用插件或者自定义页面创建一个WordPress着陆页 - 闪电博...
Day33 动态规划part02
62.不同路径 本题大家掌握动态规划的方法就可以。 数论方法 有点非主流,很难想到。 代码随想录 视频讲解:动态规划中如何初始化很重要!| LeetCode:62.不同路径_哔哩哔哩_bilibili class Solution {public int uniquePaths(int m, int n) {int dp[][] = new int[m][n];//初…...
渗透测试之Web基础之Linux病毒编写——泷羽sec
声明: 学习视频来自B站UP主泷羽sec,如涉及侵权马上删除文章。本文只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负 泷羽sec的个人空间-泷羽sec个人主页-哔哩哔哩视频 (bilibili.com)https://space.bilibili.com/350329294 导读: 时刻…...
jmeter基础07_组件的层级
课程大纲 1. 优先级/执行顺序(一般情况) 同级组件:按组件先后顺序执行。如:同一层的线程组、同一层的http请求。 上下级组件:先执行外层(上级),再执行内层(下级ÿ…...
Nginx反向代理和负载均衡配置
一、疑问 在苍穹外卖里,浏览器发送的请求,比如登录,其url为http://localhost/api/employee/login, 而后端的路径是http://localhost:8080/admin/employee/login 两者不一致,数据是如何准确传输的呢? 二、…...
【379】基于springboot的防疫物资管理信息系统
摘 要 传统办法管理信息首先需要花费的时间比较多,其次数据出错率比较高,而且对错误的数据进行更改也比较困难,最后,检索数据费事费力。因此,在计算机上安装防疫物资管理信息系统软件来发挥其高效地信息处理的作用&am…...
Linux 各个目录作用
刚毕业的时候学习Linux基础知识,发现了一份特别好的文档快乐的 Linux 命令行,翻译者是happypeter,作者当年也在慕课录制了react等前端相关的视频,通俗易懂,十分推荐 关于Linux的目录,多数博客已有详细介绍…...
【Linux】文件操作的艺术——从基础到精通
🎬 个人主页:谁在夜里看海. 📖 个人专栏:《C系列》《Linux系列》《算法系列》 ⛰️ 道阻且长,行则将至 目录 📚前言:一切皆文件 📚一、C语言的文件接口 📖1.文件打…...
java中的运算符
大家好,今天来看看java中运算符的一些知识点,理解好运算符是我们在写代码的一大重点,那么我们就来看看吧。 运算符:对操作数进行操作时的符号.,不同运算筹操作的含义不同. 一、算术算片. 1、基本四则运算符:加减乘除模(一*/%) 注意:都是二元…...
特价做网站/深圳短视频推广
原来...类模板 与 模板类 1.类模板与模板类的概念 ⑴ 什么是类模板 一个类模板(也称为类属类或类生成类)允许用户为类定义一种模式,使得类中的某些数据成员、默写成员函数的参数、某些成员函数的返回值,能够取任意类型(…...
深圳整装装修公司排名/seo推广编辑
每一个网站都有自己的导航菜单,如:头部导航菜单,底部导航菜单,侧边栏导航菜单,wordpress网站也不例外。那么,在wordpress网站主题模板开发中,我们怎样给wordpress网站添加前台的导航菜单呢&…...
亚马逊电子商务网站的建设/如何去推广一个app
强化学习有三个组成部分:演员,环境和奖励函数, 演员是我们的智能体,环境就是对手,奖励就是没走出一步环境给我们的reward,环境和奖励是我们无法控制的,但是我们可以调整演员的策略,…...
手机wordpress上传失败/网站制作费用
常见web框架中Struts2和SpringMVC独占鳌头,SpringMVC和Struts有什么不同? 我们可以从各个方面进行对比: 一:框架的思想设计上 SpringMVC控制器是基于方法上拦截,是单例的. Struts2控制器是基于类上拦截,是多例的,多例会带来一定内存消耗. 二:配置文件上执行流程 Struts2是通过…...
佛山新网站制作渠道/郑州seo竞价
程序开头需要加上#include<math.h> 1.fabs(double x) 对double型变量取绝对值 2.floor(double x)和ceil(double x) 对double型变量向下取整和向上取整,返回类型为double类型 3.pow(double r,double p) 返回r的p次方 4.sqrt(double x) 返回double型变量…...
锦州网站建设预订/网页设计个人主页
一个整数总能够拆分为2的幂的和。比如: 7124 71222 71114 711122 7111112 71111111 总共同拥有6种不同的拆分方式。 再比方:4能够拆分成:4 4,4 1 1 1 1,4 2 2,4112。用f(n)表示n的不同拆分的种…...