5属性和下标

本文深入探讨Swift中的各种属性类型,包括存储属性、延迟加载属性、计算属性等,解析其工作原理及应用场景,帮助开发者更好地理解和使用Swift语言。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

import UIKit

var str = "Hello, playground"

// 1 存储属性
// 分为 常量属性  和 变量属性

// 延迟加载属性
class Employee1{
    var no:Int = 0;
    lazy var depart:Depart1 = Depart1();
    
}

struct Depart1{
    var name:String = "";
}

// 以下代码在创建Employee1 的时候,会同时实例化Depart1部门
// 所以可以加一个var 修饰 使用延时加载,只在调用的时候进行加载访问
let e = Employee1();
e.depart.name;

// 属性观察者
// willset 在设置属性之前调用
// didset 在设置属性之后调用


// 2 计算属性
// 本事不存储数据 是从存储属性中计算得到数据
// getter 取值访问器  setter 设置访问器
class Employee2{
    
    var firstName:String = "Alex";
    var secondName:String = "Yeah";
    var fullName:String{
        // get
        get {
            return firstName + "." + secondName;
        }
        // set
        set(newName){
            var name = newName.components(separatedBy: ".");
            firstName = name[0];
            secondName = name[1];
        }
    }
}

let e2 = Employee2();
// 调用get
e2.fullName;
// 调用set
e2.fullName = "Tom.Dog";


// 计算属性
// 类中不能定义静态属性

// 3 下标
<think>根据用户的问题,我们需要构造哈夫曼树,并填写表格。题目中要求输出第5第6行(下标56)的答案。我们首先需要理解哈夫曼树的构造过程。已知4个叶子结点的权重分别为0.1、0.21、0.33、0.36。为了方便计算,我们通常将权重扩大为整数(这里乘以100),即权重为10,21,33,36。哈夫曼树构造过程:1.初始有4个结点(叶子结点),我们给它们编号为1,2,3,4,权重分别为10,21,33,36。2.每次从森林中选取两个权值最小的结点(若权值相等,则按下标小的在左子树),构造一棵新树,新树的根结点权值为两个子结点权值之。3.重复上述过程,直到森林中只剩一棵树。步骤:第一步:选取最小的两个权重:1021(下标12),合并得到新结点,权值为10+21=31,这个新结点的下标5(因为初始有4个,所以新结点从5开始)。此时,结点5的左孩子是权值小的(10)对应的下标(即1),右孩子是21对应的下标(即2)。注意:题目要求权值小的放在左子树,这里10<21,所以左孩子是1(权重10),右孩子是2(权重21)。第二步:现在剩下的结点有:31(下标5)、33(下标3)、36(下标4)。选取最小的两个权重:3133(下标53),合并得到新结点,权值为31+33=64,下标为6。这里,31<33,所以左孩子是5(权重31),右孩子是3(权重33)。第三步:剩下的结点有:64(下标6)36(下标4)。合并得到新结点,权值为64+36=100,下标为7(但题目要求到下标6,所以这一步我们不需要7)。但是,题目要求填写下表,并且第5、6行分别输出3个整数。根据提示,我们输出的是每个结点的左孩子、右孩子父结点?还是其他?注意题目没有给出表格的具体格式,但根据输出示例(第1行:500)以及问题描述,我们推测表格的每一行对应一个结点,输出该结点的左孩子、右孩子父结点的下标(如果没有则为0)。然而,题目要求输出第5第6行(下标56)的结点信息。我们重新组织一下结点信息(使用数组存储,下标从1开始):初始:结点1:权重10,左孩子=0,右孩子=0,父结点=0->但随后在第一步中,结点1的父结点被设置为5。结点2:权重21,左孩子=0,右孩子=0,父结点=0->随后父结点设置为5。结点3:权重33,左孩子=0,右孩子=0,父结点=0->随后在第二步中,父结点设置为6。结点4:权重36,左孩子=0,右孩子=0,父结点=0->暂时没有父结点,直到第三步(但第三步产生结点7,题目可能只要求到6,所以结点4的父结点在第三步才设置,但这里我们只关注56)。第一步后产生结点5:结点5:权重31,左孩子=1(因为权值10<21,所以左孩子是1),右孩子=2,父结点=0(暂时没有,但第二步后结点5的父结点被设置为6)。第二步后产生结点6:结点6:权重64,左孩子=5(因为权值31<33,所以左孩子是5),右孩子=3(权重33),父结点=0(因为第三步还没进行,所以暂时没有父结点)。注意:题目要求输出的是在构造过程中,结点5结点6的信息。根据题目要求,输出3个整数,相邻整数之间用空格隔开。那么,对于结点5下标5),我们需要输出什么?根据示例第1行输出(500)可能是输出该结点的下标、左孩子、右孩子?但示例输出500,而我们的结点5有左孩子1右孩子2。所以这里可能不是输出左孩子右孩子。重新审题:题目要求“填写下表(第5、6行分别用一条输出语句输出3个整数)”,并且给出了示例输出格式(如第1行:500)。但是,示例输出第1行是500,而我们的结点1,2,3,4,5,6,那么第1行应该对应结点1?但示例输出500,这显然不是结点1。实际上,题目没有明确说明表格每一行代表什么,但根据构造过程,我们推测可能是输出每个结点的左孩子、右孩子父结点?但是示例第1行输出500,如果这是结点1的信息,那么结点1的左孩子是5?这显然不对。另一种可能:题目要求输出的是在合并过程中新生成的结点(即非叶子结点)的信息。而初始的叶子结点可能不需要输出?题目要求第5、6行输出,说明表格有6行?但题目只提到4个叶子结点,然后合并产生两个新结点(56),所以表格应该是6行(结点1~6)。我们假设表格的每一行对应一个结点,输出该结点的三个属性:左孩子下标、右孩子下标、父结点下标。初始时,叶子结点都没有孩子,父结点也为0。然后每一步合并后更新。第一步合并后(产生结点5):结点1:左孩子0,右孩子0,父结点5结点2:左孩子0,右孩子0,父结点5结点5:左孩子1,右孩子2,父结点0(因为还没有被合并)第二步合并后(产生结点6):结点5:父结点变为6(因为结点5被合并到结点6了)结点3:父结点变为6结点6:左孩子5,右孩子3,父结点0第三步合并结点6结点4(产生结点7,但题目没有要求,所以可能不输出结点7的信息)。因此,在构造完结点5结点6后(即第二步完成后),所有结点的状态如下:1:lch=0,rch=0,parent=52:lch=0,rch=0,parent=53:lch=0,rch=0,parent=64:lch=0,rch=0,parent=0(因为第三步还没做,所以4还没有被合并)5:lch=1,rch=2,parent=66:lch=5,rch=3,parent=0题目要求输出第5第6行,那么:第5行对应结点5:输出其左孩子、右孩子、父结点->126第6行对应结点6:输出其左孩子、右孩子、父结点->530但是,题目示例第1行输出“500”,如果第1行对应结点1,那么应该是005(因为结点1的父结点是5)?所以这里可能表格的行号对应的是结点的下标?即第1行输出结点1的信息,第2行输出结点2的信息,...,第5行输出结点5的信息,第6行输出结点6的信息。因此,我们输出:第1行(结点1):左孩子0,右孩子0,父结点5->输出:005第2行(结点2):005第3行(结点3):006第4行(结点4):000(因为此时还没有父结点,第三步才会设置)第5行(结点5):左孩子1,右孩子2,父结点6->输出:126第6行(结点6):左孩子5,右孩子3,父结点0(因为结点6是根结点,还没有父结点)->输出:530但是题目要求第5、6行分别用一条输出语句输出3个整数。所以,在代码中,我们需要输出6行,但是题目只要求我们填写第5、6行?然而,用户提供的代码框架中只输出两行(两个下划线行)。所以我们需要明确:题目要求输出的表格是哪几行?重新阅读题目:“填写下表(第5、6行分别用一条输出语句输出3个整数)”,并且提示“第1行:500”。这里第1行输出500,与我们的结点1输出005不一致。所以可能是另一种解释:表格的行号代表的是构造步骤中新建的结点?而第1行对应的是第一个合并的结点(即结点5)?那么第2行对应的是结点6?如果是这样:第1行(结点5):120(因为刚创建时,它的父结点还是0,因为还没有被合并)?但题目示例第1行输出500,这显然不是。或者,表格的每一行输出的是:新结点的下标、左孩子下标、右孩子下标?那么:第一步合并:产生结点5,左孩子1,右孩子2->输出:512第二步合并:产生结点6,左孩子5,右孩子3->输出:653但是题目示例第1行输出“500”,这又不符合。另一种可能:题目要求输出的是每个结点的父结点、左孩子、右孩子?但示例第1行输出500,如果这是结点1的信息,那么表示结点1的父结点是5,左孩子0,右孩子0?这符合我们的设置。因此,我们按照每个结点的属性(父结点、左孩子、右孩子)来输出,并且按照结点下标1~6输出6行。但是题目只要求输出第5第6行(即结点5结点6的信息)?然而,用户提供的代码框架中只有两个输出语句(两个printf),所以我们只需要输出两行:第5第6行。所以,我们只需要输出:第5行:结点5的父结点、左孩子、右孩子?还是左孩子、右孩子、父结点?题目没有明确顺序。注意:题目示例第1行输出“500”,如果第1行对应结点1,那么输出的是父结点5,然后左孩子0,右孩子0?因为结点1是叶子结点,没有孩子,所以左孩子右孩子都是0,而父结点是5。因此,我们推断,每一行输出:父结点下标、左孩子下标、右孩子下标。那么:结点5:父结点是6,左孩子是1,右孩子是2->输出:612结点6:父结点是0(因为它是当前的根结点),左孩子是5,右孩子是3->输出:053但是,题目要求第5行输出结点5,第6行输出结点6。所以:第5行:612第6行:053但是,题目示例第1行输出“500”,即结点1:父结点5,左孩子0,右孩子0。然而,题目要求输出的是第5第6行,所以我们的代码只需要输出这两行。因此,我们在代码中:第5行输出:612第6行输出:053但是,在构造过程中,我们还没有进行第三步(合并46),所以结点6的父结点确实是0。而结点5的父结点是6。所以,最终代码:第一行printf输出第5行的内容:612第二行printf输出第6行的内容:053注意:题目要求相邻整数之间用空格隔开。因此,修改代码:#include<stdio.h>intmain(void){printf("612\n");//第5行:结点5的父结点、左孩子、右孩子:612printf("053");//第6行:结点6的父结点、左孩子、右孩子:053return0;}但是,这里有一个问题:题目要求“第5、6行分别用一条输出语句输出3个整数”,所以用两个printf分别输出。然而,我们构造的过程是否一定保证结点5的左孩子是1,右孩子是2?结点6的左孩子是5,右孩子是3?因为题目要求:权值小的放在左子树,权值相等时下标小的放左子树。我们第一步合并1021,10<21,所以10(下标1)作为左孩子,21(下标2)作为右孩子。第二步合并31(结点533(结点3),31<33,所以结点5(权31)作为左孩子,结点3(权33)作为右孩子。所以,这个顺序是正确的。但是,我们输出的是每个结点的父结点、左孩子、右孩子吗?题目没有明确,但根据示例第1行输出500,我们推测是输出父结点、左孩子、右孩子。因此,我们按照这个顺序输出。注意:结点4还没有被合并,所以不需要考虑。所以,最终代码:</think>根据哈夫曼树构造过程给定的权重(0.1, 0.21, 0.33, 0.36),我们首先将权重转换为整数(10, 21, 33, 36)以避免浮点运算问题。以下是完整的构造过程下标5、6对应的答案: ### 哈夫曼树构造过程 1. **初始结点(下标1-4)**: - 结点1:权重=10(0.1),左子=0,右子=0,父=0 - 结点2:权重=21(0.21),左子=0,右子=0,父=0 - 结点3:权重=33(0.33),左子=0,右子=0,父=0 - 结点4:权重=36(0.36),左子=0,右子=0,父=0 2. **第一步合并(生成下标5)**: - 选择最小权重结点1(10)结点2(21) - 新结点5:权重=10+21=31 - 左子=1(较小权重),右子=2(较大权重) - 更新结点1/2的父=5 3. **第二步合并(生成下标6)**: - 选择最小权重结点5(31)结点3(33) - 新结点6:权重=31+33=64 - 左子=5(较小权重),右子=3(较大权重) - 更新结点5/3的父=6 4. **最终合并(生成下标7)**: - 选择结点6(64)结点4(36) - 新结点7:权重=64+36=100(根节点) ### 下标56的答案 | 结点下标 | 权重 | 父结点 | 左子结点 | 右子结点 | 输出格式(父 左子 右子) | |---------|------|-------|---------|---------|------------------------| | 5 | 31 | 6 | 1 | 2 | **6 1 2** | | 6 | 64 | 7 | 5 | 3 | **7 5 3** | ```c #include <stdio.h> int main(void) { printf("6 1 2\n"); // 下标5的结点:父=6, 左子=1, 右子=2 printf("7 5 3"); // 下标6的结点:父=7, 左子=5, 右子=3 return 0; } ``` ### 输出说明 - **第5行输出**:`6 1 2` 表示下标5的结点:父结点是6,左子结点是1,右子结点是2 - **第6行输出**:`7 5 3` 表示下标6的结点:父结点是7,左子结点是5,右子结点是3 ### 树结构验证 ``` 根节点100(7) / \ 64(6) 36(4) / \ 31(5) 33(3) / \ 10(1) 21(2) ``` ### 哈夫曼编码结果 | 原始权重 | 编码 | |---------|------| | 0.10 | 000 | | 0.21 | 001 | | 0.33 | 01 | | 0.36 | 1 | 此构造遵循哈夫曼算法规则:权值小的放左子树,权值大的放右子树,相等时下标小的放左子树[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值