吉首大学--23级题目讲解

news/2024/9/22 3:36:09 标签: 算法, 数据结构

7-1 单链表基本操作

在 C/C++ 中,.(点)和 ->(箭头)运算符用于访问结构体或类的成员,但它们的使用场景不同。

1. . 运算符

  • . 运算符用于访问结构体或类的成员,通过对象或结构体变量直接访问。

2. -> 运算符

  • -> 运算符用于访问指向结构体或类的指针的成员。它简化了通过指针访问成员的过程。
示例:
struct Point {
    int x,y;
};

Point p;         // 创建结构体变量 p
p.x = 10;       // 使用 . 访问成员 x
p.y = 20;       // 使用 . 访问成员 y
cout << "Point: (" << p.x << ", " << p.y << ")" << endl;  // 输出: Point: (10, 20)

Point* p1 = (Point*)malloc(sizeof(Point)); // 创建一个指向 Point 的指针
//Point* pPtr = new Point;  C++可以这么写
p1->x = 10;             // 使用 -> 访问成员 x
p1->y = 20;             // 使用 -> 访问成员 y
cout << "Point: (" << p1->x << ", " << p1->y << ")" << endl;  // 输出: Point: (10, 20)
free(p1);				// 释放内存
//delete p1;            C++可以这么写

3. 区分 &*

  • & 运算符

    • 主要用于获取变量的地址(取地址运算符)。
    • 例如:int* p = &a; 表示将变量 a 的地址赋给指针 p
  • * 运算符

    • 主要用于指针的声明和解引用(取值运算符)。
    • 在声明中,int* p 表示 p 是一个指向 int 类型的指针。
    • 在解引用时,*p 表示访问指针 p 所指向的内存地址中的值。
示例:
int a = 10;
int* p = &a;  // & 用于获取 a 的地址
cout << *p;   // * 用于解引用,输出 10
#include<bits/stdc++.h>
using namespace std;

// 定义节点结构体,包含一个整数和一个指向下一个节点的指针
struct node {
    int w;                 // 节点中存储的整数值
    struct node *next;     // 指向下一个节点的指针
};

typedef struct node Node;  // 为结构体 node 定义别名 Node

Node* head;               // 链表的头节点指针
Node* back;               // 链表的尾节点指针,用于快速在链表尾部插入
int len = 0;              // 链表的长度,动态记录节点数量

// 初始化链表,创建一个空的头节点
void ini() {
    head = (Node* )malloc(sizeof(Node));  // 分配内存给头节点
    back = head;                          // 初始化 back 指向头节点
    head->next = NULL;                    // 头节点的 next 设为 NULL,表明链表为空
}

// 根据位置 k 查找第 k 个节点
Node* find(int k) {
    Node* temp = head;                    // 从头节点开始遍历
    for (int i = 1; i <= k; i++) {        // 移动到第 k 个节点
        temp = temp->next;
    }
    return temp;                          // 返回第 k 个节点的指针
}

// 在节点 k 之后插入一个新节点,节点值为 x
void insert(Node* k, int x) {
    Node* temp = (Node* )malloc(sizeof(Node));  // 分配新节点的内存
    temp->w = x;                                // 将值 x 存入新节点
    temp->next = k->next;                       // 新节点的 next 指向 k 的下一个节点
    k->next = temp;                             // 将 k 的 next 指向新节点
    if (k == back) back = temp;                 // 如果插入的是最后一个节点,更新 back
}

// 删除节点 k 的下一个节点
void deleteNode(Node* k) {
    Node* temp = k->next;                // 暂存要删除的节点
    k->next = k->next->next;             // 跳过被删除的节点,直接链接到下一个节点
    free(temp);                          // 释放被删除节点的内存
}

int main() {
    int n;
    cin >> n;                            // 读取初始链表长度 n
    ini();                               // 初始化链表
    for (int i = 1; i <= n; i++) {
        int x;
        cin >> x;                        // 读取每个节点的值
        insert(back, x);                 // 在链表尾部插入节点
        len++;                           // 更新链表长度
    }

    int m;
    cin >> m;                            // 读取操作次数 m
    while (m--) {
        int op;
        cin >> op;                       // 读取操作类型
        if (op == 0) {                   // 插入操作
            int k, d;
            cin >> k >> d;               // 读取插入位置 k 和插入的值 d
            if (k <= 0 || k > len) continue;  // 边界条件检查,跳过非法位置
            insert(find(k), d);          // 在第 k 个节点之后插入值为 d 的新节点
            len++;                       // 更新链表长度
        } else {                         // 删除操作
            int k;
            cin >> k;                    // 读取删除位置 k
            if (k <= 0 || k > len) continue;  // 边界条件检查,跳过非法位置
            deleteNode(find(k - 1));     // 删除第 k 个节点
            len--;                       // 更新链表长度
        }
    }

    // 打印并释放链表中所有节点的内存
    while (head->next != NULL) {
        cout << head->next->w << " ";    // 打印当前节点的值
        Node* temp = head->next;         // 暂存当前节点的指针
        head->next = head->next->next;   // 跳过当前节点,指向下一个节点
        free(temp);                      // 释放当前节点的内存
    }
    
    return 0;
}

单链表——单链表的定义及基本操作(初始化、头插法尾插法建表、查找、插入、删除、判空等)_带头结点的单链表的元素的创建、查找、插入、删除等基本操作-CSDN博客

7-2矩阵运算

#include<bits/stdc++.h>
using namespace std;
bool check(int i,int j,int n){
    if(i+j==n+1) return 0;//副对角线
    if(j==n||i==n) return 0;//最后一列 最后一行
    return 1;
}
int main(){
    int n,ans=0;
    cin>>n;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            int x;
            cin>>x;
            if(check(i,j,n)){
                ans+=x;
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}

7-3 删除重复字符

注意!输入空格!!!

#include<bits/stdc++.h>
using namespace std;
int main(){
    vector<char> v;
    set<char> s;
    char c;
    while((c=getchar())!='\n'){
        if(!s.count(c)){//查看原集合中是否存在,即之前是否出现过
            s.insert(c);
            v.push_back(c);
        }
    }
    sort(v.begin(),v.end());//排序
    for(char i:v){
        cout<<i;
    }
    cout<<endl;
    return 0;
}

字符不会超过128(ASCII码),开桶

#include<bits/stdc++.h>
using namespace std;
int tong[200];
int main(){
    char c;
    memset(tong,0,sizeof(tong));
    while((c=getchar())!='\n'){
        tong[(int)c]++;
    }
    for(int i=0;i<128;i++){
        if(tong[i]){
            cout<<(char)(i);
        }
    }
    return 0;
}

C++常用STL

  1. vector 动态数组
  2. stack
  3. queue 队列
  4. deque 双端队列
  5. priority_queue 优先队列
  6. map 映射(键值对)
  7. set 集合

C++ STL详解超全总结(快速入门STL)-CSDN博客

7-4 统计字符出现次数

ASCII(American Standard Code for Information Interchange)码表是用于表示文本字符的标准编码系统。它为每个字符分配了一个唯一的整数值,以便计算机能够在不同设备之间交换文本数据。ASCII码表最初设计用于表示英文字符,但后来扩展了其他符号。

ASCII码表

一共有128个字符,开桶即可。

#include<bits/stdc++.h>
using namespace std;
int cnt[200];
int main(){
    char c;
    while((c=getchar())!='\n'){
        cnt[(int)c]++;
    }
    c=getchar();//小心空格,再次提醒
    cout<<cnt[(int)c]<<endl;
    return 0;
}

补录

    //getchar() 返回的是读取的字符的 ASCII 值
	while((c=getchar())!='\n'){
        cnt[(int)c]++;
    }
    //这样写是可以的
    while(scanf("%c", &c) && c != '\n') {
        cnt[(int)c]++;
    }
    //scanf("%c", &c) 返回的是读取成功的项数,而不是读取的字符值,因此直接将它与 '\n' 进行比较是错误的
    //故这样写是错误的ERROR
    //scanf和printf本身也是一个函数,可以自己去了解
    while(scanf("%c", &c) != '\n') {
    }
}

http://www.niftyadmin.cn/n/5669592.html

相关文章

银河麒麟桌面操作系统V10(SP1)离线升级SSH(OpenSSH)服务

目录 前言 准备工作 准备与目标服务器相同版本的操作系统 准备编译依赖包 下载OpenSSL源码包 下载OpenSSH源码包 升级OpenSSH服务 查看当前版本信息 安装编译依赖包 安装OpenSSL 安装OpenSSH 前言 OpenSSH是一个广泛使用的开源SSH(安全壳)协议的实现,它提供了安…

[Spring]Spring MVC 请求和响应及用到的注解

文章目录 一. Maven二. SpringBoot三. Spring MVC四. MVC注解1. RequestMapping2. RequestParam3. PathVariable4. RequestPart5. CookieValue6. SessionAttribute7. RequestHeader8. RestController9. ResponseBody 五. 请求六. 响应 一. Maven Maven是⼀个项⽬管理⼯具。基于…

READONLY You can‘t write against a read only replica

服务连接配置为哨兵模式&#xff0c;启动应用报下面的异常&#xff1a; org.springframework.data.redis.RedisSystemException: Error in executionat org.springframework.data.redis.connection.lettuce.LettuceExceptionConverter.convert(LettuceExceptionConverter.java…

ESP32 JTAG 调试

前言 个人邮箱&#xff1a;zhangyixu02gmail.com本人使用的是 Ubuntu 环境&#xff0c;采用 GDB 方式进行调试。对于新手&#xff0c;我个人还是建议参考ESP32S3学习笔记&#xff08;0&#xff09;—— Vscode IDF环境搭建及OpenOCD调试介绍进行图形化的方式调试。如果是希望在…

C++中string类的使用

目录 1.auto和范围for 1.1auto关键字 1.2范围for 2.string类常用接口说明 2.1默认成员函数 2.1.1构造函数(constructor) 2.1.2赋值运算符重载(operator()) 2.2string类对象的访问及遍历操作(Iterators and Element access) 2.3string类对象的容量操作(Capacity) 2.3.1…

基于ARM与FPGA的高速多轴嵌入式运动控制器设计流程

一、项目概述 本课题旨在设计一款具备良好扩展性和高速处理能力的嵌入式运动控制器&#xff0c;主要实现基本的伺服控制功能。针对双惯量谐振系统的速度控制&#xff0c;研究了相应的伺服控制算法。通过采用松下A5N驱动器&#xff0c;结合嵌入式架构以及网络通讯模式&#xff…

MATLAB在无线通信系统仿真中的应用:从理论到实践

无线通信技术是现代通信领域的核心&#xff0c;其发展推动了自动驾驶汽车、智能工厂和远程医疗等新技术的应用。MATLAB作为一种强大的数学软件&#xff0c;提供了一整套工具箱&#xff0c;使得工程师和研究人员能够高效地进行无线通信系统的建模、仿真、测试和优化。本文将详细…

iPhone 上丢失了重要的联系人?如何恢复已删除的 iPhone 联系人

丢失 iPhone 上的联系人可能会带来灾难。无论是一份很棒的新工作机会、潜在的恋爱对象&#xff0c;还是您一直想打电话的老朋友&#xff0c;如果您打开“联系人”应用时看到空白&#xff0c;这绝不是好事。不过&#xff0c;一切并非全无&#xff0c;仍然可以通过备份或专业软件…