森林与二叉树之间的转换以及可视化演示(C++实现)

2023-05-16

演示程序截图
在这里插入图片描述

基本要求

  • 构造并实现森林的ADT和二叉树ADT,森林ADT中应包括初始化、插入元素、删除元素,插入边,删除边,转换成二叉树,显示森林及对应的二叉树等基本操作,二叉树ADT中应包括初始化、插入根、插入指定元素的左孩子或右孩子,转换成森林,显示二叉树及对应的森林等基本操作。(基本操作可根据问题需要扩展)
  • 森林使用孩子链表表示,二叉树使用二叉链表表示,实现森林和二叉树结构。

问题分析

该程序所应实现的功能如下:
(1)二叉树与森林的初始化
(2)二叉树与森林的插入操作(二叉树插入结点、森林插入结点、插入边)
(3)二叉树指定根结点、森林插入根结点
(4)二叉树与森林的删除操作
(5)二叉树与森林的遍历操作
(6)二叉树与森林的相互转换
(7)二叉树与森林的可视化

程序结构设计

二叉树模块
(1)初始化:void Initialize(int n);
(2)查找指定元素所在的位置:binaryTreeNode* find(int element);
(3)插入结点:void InsertNode(int pos,int father,int node);
(4)删除结点:void erase(binaryTreeNode *t);
(5)改变根节点:void ChangeRoot(binaryTreeNode *t);
(6)前序遍历:int preOrder(binaryTreeNode *t);
(7)可视化:void Visualition();

二叉树与森林的转换模块
(1)树转二叉树
binaryTreeNode* ForestToBinaryTree(int root);
(2)森林转二叉树
void Transform(linkedBinaryTree& change1);
(3)二叉树转森林
void BiNodeToFNode(binaryTreeNode *t,Forest &f);
void BTreeToForest(Forest &t);

设计思路

二叉树模块

(1)初始化:void Initialize(int n);
首先指定二叉树初始状态结点的个数并指定根结点,然后申请一个二叉树结点数组用于后续的结点插入,最后输入结点信息并执行插入操作。
(2)查找指定元素所在的位置:binaryTreeNode* find(int element);
输入要查找的元素信息,然后从二叉树的根结点开始执行层次遍历,逐层查找指定元素,找到则返回对应的二叉树结点指针,找不到则返回空指针。
(3)插入结点:void InsertNode(int pos,int father,int node);
首先查找到father所对应的结点位置,然后根据pos和node中的信息来插入左/右孩子。
(4)删除结点:void erase(binaryTreeNode *t);
通过后序遍历来删除二叉树结点,首先递归删除左子树,然后递归删除右子树,最后释放父节点的空间。
(5)改变根节点(重置二叉树):void ChangeRoot(binaryTreeNode *t);
删除当前根节点,然后重置根节点为t。
(6)前序遍历:int preOrder(binaryTreeNode *t);
利用递归的思想,首先访问父节点t,然后前序遍历左子树,最后前序遍历右子树。
(7)可视化:void Visualition();
利用Graphviz扩展库,通过C++读写dot语言文件来实现可视化操作,具体操作是层次遍历二叉树并在遍历的同时申请dot结点,然后根据二叉树的结构来连接各dot结点,最后调用命令行编译dot文件生成图像。

森林模块

(1)初始化:void Initialize(int m,int n);
首先指定森林根节点的数目以及结点总数,然后输入并存储根节点,最后根据输入信息将各结点插入到对应的树中。
(2)插入结点:void InsertNode(int father,int node);
若插入的是根结点,则直接将node存入根结点数组即可,若插入的是子结点,则找到将node结点插入到father对应的链表中即可,注意插入操作要保证链表有序。
(3)插入边:int InsertEdge(int a,int b);
首先遍历森林的根结点数组,若a、b都存在,则在a所对应的链表中插入b并在根结点数组中删除b。
(4)删除结点:bool EraseNode(int father,int node);
将该结点所对应的链表元素全部设为根结点然后清空该链表,若删除的是根结点,则还要将该节点从根结点数组中删除。
(5)遍历树:int ShowLevel(int root);
利用层次遍历,从每棵树的根结点开始逐层扩展并访问树中各结点。
(6)遍历森林:void ShowForest();
首先将所有树的根节点按照从小到大的顺序排序,然后依次遍历森林中的每一棵树。
(7)可视化:void Visualition();
利用Graphviz扩展库,通过C++读写dot语言文件来实现可视化操作,具体操作是层次遍历二叉树并在遍历的同时申请dot结点,然后根据森林的结构来连接各dot结点,最后调用命令行编译dot文件生成图像。

二叉树与森林的转换模块
(1)树转二叉树
binaryTreeNode* ForestToBinaryTree(int root);
从根结点root开始,将与root相连的第一个元素作为root的左孩子,然后递归转换左子树,并将root左孩子的兄弟作为root的右子树,再对右子树进行递归转换。
(2)森林转二叉树
void Transform(linkedBinaryTree& change1);
首先对所有的根结点进行排序,然后对森林中的每一棵树进行转换并按照顺序连接即可。
(3)二叉树转树
void BiNodeToFNode(binaryTreeNode *t,Forest &f);
对于结点t,若结点t的左孩子存在,则将这个左孩子的右子树改为结点t的右子树,再对该右子树进行递归转换,右子树转换完毕后,将结点t向左移动再次进行相同操作,直至结点t指向的为空指针。
(4)二叉树转森林
void BTreeToForest(Forest &t);
从二叉树的根结点开始,沿着右孩子指针将二叉树分离即得到森林的根结点,再对分离后的根结点依次执行上述的二叉树转树操作,即可转换成森林。

代码实现

核心代码如下:

#ifndef FORESTANDBTREE_H
#define FORESTANDBTREE_H
#include <iostream>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;

//int转string
void AppendInt(string &s,int &a){
    char buf[10];
    itoa(a,buf,10);
    s+=buf;
}

//dot语言声明二叉树结点
string BNodeInfo(int e){
    string father="";
    string element="";
    AppendInt(element,e);
    father+=element;
    father+="[label=\"<f0>|<f1>";
    father+=element;
    father+="|<f2>\"]";
    return father;
}

//二叉树结点
struct binaryTreeNode
{
    //所存储元素
    int element;
    //左孩子、右孩子
    binaryTreeNode *leftChild,
                     *rightChild;
    //构造函数
    binaryTreeNode() {leftChild = rightChild = NULL;}
    binaryTreeNode(int& theElement):element(theElement)
    {
        leftChild = rightChild = NULL;
    }
    binaryTreeNode(int& theElement,
                  binaryTreeNode *theLeftChild,
                  binaryTreeNode *theRightChild)
                  :element(theElement)
    {
        leftChild = theLeftChild;
        rightChild = theRightChild;
    }
};

//森林结点
struct ForestNode
{
    //所存储元素
    int element;
    //指向孩子或兄弟的指针
    ForestNode *next;
    //构造函数
    ForestNode() {element=0;next=NULL;}
    ForestNode(int& theElement):element(theElement)
    {
        next=NULL;
    }
    ForestNode(int& theElement,ForestNode *thenext)
                  :element(theElement)
    {
        next=thenext;
    }
};

//链表类
class chain
{
    public:
        friend class Forest;
        //构造函数
        chain(){firstnode=NULL;csize=0;}
        //析构函数
        ~chain();
        //返回链表元素个数
        int size(){return csize;}
        //插入操作
        void insert(int key);
        //删除操作
        bool erase(int key);
    private:
        ForestNode* firstnode;//头节点
        int csize;//链表元素个数
};

//析构函数
chain::~chain()
{
    while(firstnode!=NULL)
    {
        ForestNode *p=firstnode->next;
        delete firstnode;
        firstnode=p;
    }
}
//插入操作
void chain::insert(int key)
{
    ForestNode *p=firstnode;
    ForestNode *q=NULL;
    //查找插入的位置
    //移动指针q,使得新元素可以插在q的后面
    while(p!=NULL&&p->element<key)
    {
        q=p;
        p=p->next;
    }
    //链表中存在所要插入的元素
    if(p!=NULL&&p->element==key){}
    //找到插入位置则在q之后插入新节点
    else
    {
        ForestNode *t=new ForestNode(key,p);
        //插入位置为头节点
        if(q==NULL)
            firstnode=t;
        //插入位置不在头节点
        else
            q->next=t;
        csize++;
    }
}
//删除操作
bool chain::erase(int key)
{
    ForestNode *p=firstnode;
    ForestNode *q=NULL;
    //搜索数据域为key的节点
    while(p!=NULL&&p->element<key)
    {
        q=p;
        p=p->next;
    }
    //找到匹配的节点
    if(p!=NULL&&p->element==key)
    {
        //删除头节点
        if(q==NULL)
            firstnode=p->next;
        //删除头节点之后的节点
        else
            q->next=p->next;
        delete p;
        csize--;
        return true;
    }
    //未找到要删除节点
    else{return false;}
}
class linkedBinaryTree;
//森林类
class Forest
{
    public:
        friend class linkedBinaryTree;
        //构造函数
        Forest(int n);
        Forest(){NodeSize=0;tree=new chain[5500];}
        //析构函数
        ~Forest(){}
        //初始化
        void Initialize(int m,int n);
        //插入结点
        void InsertNode(int father,int node);
        //插入边
        int InsertEdge(int a,int b);
        //删除结点
        bool EraseNode(int father,int node);
        //森林转二叉树
        binaryTreeNode* ForestToBinaryTree(int root);
        void Transform(linkedBinaryTree& change1);
        //显示森林(遍历森林元素)
        void ShowForest();
        int ShowLevel(int root);
        //森林可视化
        void Visualition();
    protected:
        //孩子链表
        chain *tree;
        //根节点
        vector<int> root;
        //森林结点个数
        int NodeSize;
};

class linkedBinaryTree
{
    public:
        friend class Forest;
        //构造函数
        linkedBinaryTree() {root = NULL;}
        ~linkedBinaryTree(){erase(root);root = NULL;};
        //判断是否为空
        bool empty() const {return root == NULL;}
        //前序遍历
        int preOrder(binaryTreeNode *t);
        //删除结点
        void erase(binaryTreeNode *t);
        //插入结点
        void InsertNode(int pos,int father,int node);
        //初始化
        void Initialize(int n);
        //查找指定元素所对应的位置
        binaryTreeNode* find(int element);
        //前序遍历
        int PreOrder(){return preOrder(root);}
        //层次遍历
        void levelorder(binaryTreeNode *t);
        void LevelOrder(){levelorder(root);cout<<endl;}
        //改变根结点
        void ChangeRoot(binaryTreeNode *t){erase(root);root=t;};
        //二叉树转森林
        void BiNodeToFNode(binaryTreeNode *t,Forest &f);
        void BTreeToForest(Forest &t);
        //二叉树可视化
        void Visualition();
    protected:
        //根结点
        binaryTreeNode *root;
};

void linkedBinaryTree::Visualition(){
    //重定向输出流到dot文件
    freopen("binarytree.dot","w",stdout);
    //dot语言作图
    cout<<"digraph G{"<<endl;
    cout<<"label=\"Binary Tree\";"<<endl;
    cout<<"node[shape=record];"<<endl;
    queue<binaryTreeNode *> q;
    binaryTreeNode *tmp=root;
    q.push(tmp);
    while(!q.empty()){
        binaryTreeNode *t=q.front();
        q.pop();
        string father=BNodeInfo(t->element);
        cout<<father<<";"<<endl;
        if(t->leftChild!=NULL){
            string left=BNodeInfo(t->leftChild->element);
            cout<<left<<";"<<endl;
            cout<<t->element<<":f0:sw->"<<t->leftChild->element<<":f1;"<<endl;
            q.push(t->leftChild);
        }
        if(t->rightChild!=NULL){
            string right=BNodeInfo(t->rightChild->element);
            cout<<right<<";"<<endl;
            cout<<t->element<<":f2:se->"<<t->rightChild->element<<":f1;"<<endl;
            q.push(t->rightChild);
        }
    }
    cout<<"}"<<endl;
    fclose(stdout);
    //命令行输出图片
    string s = "";
    s += "dot -Tpng ";
    s += "binarytree.dot";
    s += " -o ";
    s+="binarytree.png";
    const char* cmd = s.data();
    system(cmd);
    //重新开启屏幕输出流
    freopen("CON","w",stdout);
}
//二叉树层次遍历
void linkedBinaryTree::levelorder(binaryTreeNode *t){
    queue<binaryTreeNode *> q;
    q.push(t);
    while(!q.empty()){
        binaryTreeNode *p=q.front();
        cout<<p->element<<" ";
        q.pop();
        //扩展左子树
        if(p->leftChild!=NULL)
            q.push(p->leftChild);
        //扩展右子树
        if(p->rightChild!=NULL)
            q.push(p->rightChild);
    }
}
//查找指定元素所在的位置
binaryTreeNode* linkedBinaryTree::find(int element){
    queue<binaryTreeNode*> q;
    binaryTreeNode* tmp=root;
    q.push(tmp);
    while(!q.empty()){
        binaryTreeNode* t=q.front();
        q.pop();
        if(t->element==element)
            return t;
        //查找左子树
        if(t->leftChild!=NULL)
            q.push(t->leftChild);
        //查找右子树
        if(t->rightChild!=NULL)
            q.push(t->rightChild);
    }
    return NULL;
}
//二叉树初始化
void linkedBinaryTree::Initialize(int n){
    //指定根节点
    int rr;
    cin>>rr;
    binaryTreeNode* nodes[n+10];
    for(int i=1;i<=n;i++){
        nodes[i]=new binaryTreeNode(i);
    }
    int A,l,r;
    //输入结点信息并插入
    for(int i=0;i<n;i++){
        cin>>A>>l>>r;
        //插入左孩子
        if(l!=-1)
            nodes[A]->leftChild=nodes[l];
        //插入右孩子
        if(r!=-1)
            nodes[A]->rightChild=nodes[r];
    }
    root=nodes[rr];
}
//插入结点
void linkedBinaryTree::InsertNode(int pos,int father,int node){
    queue<binaryTreeNode*> q;
    binaryTreeNode* tmp=root;
    q.push(tmp);
    while(!q.empty()){
        binaryTreeNode* t=q.front();
        q.pop();
        //找到对应的位置
        if(t->element==father){
            //插入右孩子
            if(pos==0){
                t->rightChild=new binaryTreeNode(node);
            }
            //插入左孩子
            else{
                t->leftChild=new binaryTreeNode(node);
            }
            return;
        }
        //扩展查找子树
        if(t->leftChild!=NULL)
            q.push(t->leftChild);
        if(t->rightChild!=NULL)
            q.push(t->rightChild);
    }
}
//删除结点
void linkedBinaryTree::erase(binaryTreeNode *t)
{
    if (t != NULL)
    {
        //删除左子树
        erase(t->leftChild);
        //删除右子树
        erase(t->rightChild);
        //释放结点空间
        delete t;
    }
}
//前序遍历
int linkedBinaryTree::preOrder(binaryTreeNode *t)
{
    int sum=0;
    if (t != NULL)
    {
        //访问父结点
        sum^=t->element;
        //前序遍历左子树
        sum^=preOrder(t->leftChild);
        //前序遍历右子树
        sum^=preOrder(t->rightChild);
    }
    return sum;
}
//二叉树转树
void linkedBinaryTree::BiNodeToFNode(binaryTreeNode *t,Forest &f)
{
    binaryTreeNode* r=t;
    binaryTreeNode* p=r;
    //沿左孩子方向进行转换
    while(r!=NULL){
        int father=r->element;
        p=r->leftChild;
        while(p!=NULL){
            f.tree[father].insert(p->element);
            p=p->rightChild;
            //递归转换右子树
            BiNodeToFNode(p,f);
        }
        r=r->leftChild;
    }
}
//二叉树转森林
void linkedBinaryTree::BTreeToForest(Forest &t)
{
    vector<binaryTreeNode*> ROOT;
    binaryTreeNode *tmp=root;
    //分离根结点
    while(tmp!=NULL){
        binaryTreeNode *rroot=new binaryTreeNode(tmp->element);
        rroot->leftChild=tmp->leftChild;
        ROOT.push_back(rroot);
        tmp=tmp->rightChild;
    }
    int size=ROOT.size();
    //对分离后的根结点执行转换操作
    for(int i=0;i<size;i++){
        t.root.push_back(ROOT[i]->element);
        binaryTreeNode* r=ROOT[i];
        BiNodeToFNode(r,t);
    }
}

void Forest::Visualition(){
    //重定向输出流到dot文件
    freopen("forest.dot","w",stdout);
    //dot语言作图
    cout<<"digraph G{"<<endl;
    cout<<"label=\"Forest\";"<<endl;
    cout<<"node[shape=circle];"<<endl;
    sort(root.begin(),root.end());
    int size=root.size();
    for(int i=0;i<size;i++){
        queue<int> q;
        q.push(root[i]);
        cout<<root[i]<<";"<<endl;
        while(!q.empty()){
            int tmp=q.front();
            q.pop();
            ForestNode *p=tree[tmp].firstnode;
            while(p!=NULL){
                cout<<p->element<<";"<<endl;
                cout<<tmp<<"->"<<p->element<<";"<<endl;
                q.push(p->element);
                p=p->next;
            }
        }
    }
    cout<<"}"<<endl;
    fclose(stdout);
    //命令行输出图片
    string s = "";
    s += "dot -Tpng ";
    s += "forest.dot";
    s += " -o ";
    s+="forest.png";
    const char* cmd = s.data();
    system(cmd);
    //重新开启屏幕输出流
    freopen("CON","w",stdout);
}
//构造函数
Forest::Forest(int n){
    NodeSize=n;
    tree=new chain[n+200];
}
//森林初始化
void Forest::Initialize(int m,int n){
    int NodeElement;
    //输入根结点
    for(int i=1;i<=m;i++){
        int rootnode;
        cin>>rootnode;
        root.push_back(rootnode);
    }
    int father,num;
    //根据输入信息插入结点
    for(int i=1;i<=n;i++){
        cin>>father>>num;
        while(num--){
            cin>>NodeElement;
            tree[father].insert(NodeElement);
        }
    }
}
//层次遍历树
int Forest::ShowLevel(int root){
    int sum=0;
    queue<int> q;
    q.push(root);
    sum^=root;
    while(!q.empty()){
        int tmp=q.front();
        q.pop();
        ForestNode *p=tree[tmp].firstnode;
        //按层扩展
        while(p!=NULL){
            sum^=p->element;
            q.push(p->element);
            p=p->next;
        }
    }
    return sum;
}
//层次遍历森林
void Forest::ShowForest(){
    //对根结点从小到大排序
    sort(root.begin(),root.end());
    int size=root.size();
    //遍历森林中的每一颗树
    for(int i=0;i<size;i++)
        cout<<ShowLevel(root[i])<<" ";
    cout<<endl;
}
//插入结点
void Forest::InsertNode(int father,int node){
    //插入根节点
    if(father==-1){
        root.push_back(node);
    }
    //插入子结点
    else{
        tree[father].insert(node);
    }
    NodeSize++;
}
//删除结点
bool Forest::EraseNode(int father,int node){
    bool flag=false;
    //删除根结点
    if(father==-1){
        vector<int>::iterator iter=root.begin();
        while(iter!=root.end()){
            if(*iter==node){
                flag=true;
                root.erase(iter);
                break;
            }
            iter++;
        }
        ForestNode *p=tree[node].firstnode;
        while(p!=NULL){
            root.push_back(p->element);
            ForestNode *q=p->next;
            delete p;
            p=q;
        }
    }
    //删除的不是根结点
    else{
        flag=tree[father].erase(node);
        ForestNode *p=tree[node].firstnode;
        while(p!=NULL){
            root.push_back(p->element);
            ForestNode *q=p->next;
            delete p;
            p=q;
        }
    }
    NodeSize--;
    return flag;
}
//插入边
int Forest::InsertEdge(int a,int b){
    bool flaga=0;
    bool flagb=0;
    vector<int>::iterator iter=root.begin();
    //首先判断输入的a、b是否为根结点并将b从根结点数组中删除
    while(iter!=root.end()){
        if(*iter==a){
            flaga=true;
        }
        if(*iter==b){
            flagb=true;
            root.erase(iter);
        }
        iter++;
    }
    //a、b连接
    if(flaga&&flagb){
        tree[a].insert(b);
        return 0;
    }
    else if(flaga&&!flagb){
        return 2;
    }
    else if(!flaga&&flagb){
        return 1;
    }
    else
        return 3;
}
//树转二叉树
binaryTreeNode* Forest::ForestToBinaryTree(int root)
{
    binaryTreeNode* binaryRoot = new binaryTreeNode(root);
    if (tree[root].size()<=0){
        return binaryRoot;
    }
    //递归转换左子树
    binaryRoot->leftChild = ForestToBinaryTree(tree[root].firstnode->element);
    //兄弟结点变右子树
    binaryTreeNode *brotherChild = binaryRoot->leftChild;
    ForestNode *p=tree[root].firstnode->next;
    while(p!=NULL)
    {
        brotherChild->rightChild = ForestToBinaryTree(p->element);
        brotherChild = brotherChild->rightChild;
        p=p->next;
    }
    return binaryRoot;
}
//森林转二叉树
void Forest::Transform(linkedBinaryTree& change1){
    //对根结点进行排序
    sort(root.begin(),root.end());
    binaryTreeNode *t=ForestToBinaryTree(root[0]);
    binaryTreeNode* tmp=t;
    int size=root.size();
    //对森林中的每颗树进行转换并连接
    for(int i=1;i<size;i++){
        tmp->rightChild=ForestToBinaryTree(root[i]);
        tmp=tmp->rightChild;
    }
    change1.ChangeRoot(t);
}

#endif // FORESTANDBTREE_H
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

森林与二叉树之间的转换以及可视化演示(C++实现) 的相关文章

  • [week15] B - ZJM与生日礼物(选做)—— 字典树

    文章目录 题意InputOutput输入样例输出样例提示 分析总结代码 题意 ZJM 收到了 Q老师 送来的生日礼物 xff0c 但是被 Q老师 加密了 只有 ZJM 能够回答对 Q老师 的问题 xff0c Q老师 才会把密码告诉 ZJM
  • [week15] C - ZJM与纸条(选做)—— KMP算法

    文章目录 题意InputOutput输入样例输出样例提示 分析总结代码 题意 ZJM 的女朋友是一个书法家 xff0c 喜欢写一些好看的英文书法 有一天 ZJM 拿到了她写的纸条 xff0c 纸条上的字暗示了 ZJM 的女朋友 想给 ZJM
  • 51按键外部中断控制流水灯

    实验二 外部按键输入 一 实验目的 1 了解单片机检测口方法 2 了解单片机外部中断原理 3 了解按键输入原理 二 实验内容 1 完成按键扫描控制流水灯 2 完成按键外部中断控制流水灯 三 实验原理 四 实验电路与程序 1 软件实验一 xf
  • 树莓派4B构建debian镜像UEFI启动

    树莓派4B构建debian镜像UEFI启动 前言 今天按照大佬的博客树莓派俱乐部官方 Debian 系统镜像 支持UEFI跑了遍 完整的UEFI镜像构建过程 包括镜像分区 挂载 xff0c 根文件系统的制作 xff0c 内核的移植 xff0
  • Linux修改主机名问题

    记一次修改主机名不成功原因 场景 虽然使用hostname命令可以修改主机名 xff0c 但如果重启主机之后主机名还会变为之前的 xff0c 所以需要把修改的主机名称写到配置文件中 假设修改后的主机名为 new hostname 1 修改配
  • mybatisPlus分页插件报错,sql后面拼接多了一个limit。

    原本 用的mybatisPlus版本为3 1 0 xff0c 后来升级到3 4 2了 xff0c 使用分页的时候报错 解决 xff1a mybatisPlus 3 1 0 所用到的分页插件为 而mybatisPlus 3 4 2版本pagi
  • Deep Knowledge Tracing (深度知识追踪)

    boss又让我看这块的内容了 xff0c 刚开学 xff0c 还不太适应实验室的学习生活 xff0c 假期闲散惯了操 目录 1 概述2 表示3 1 DKT的优势3 2 DKT的不足4 模型5 序列的输入和输出输入输出 6 优化及应用7 三个
  • C程序代码

    一 C语言概述有算法 1 输出一行信息 span class token macro property span class token directive hash span span class token directive keyw
  • 【C语言-10】.求10 个整数中最大值。 (数组定义法和函数调用法)

    数组定义法 首先定义一个一维数组存放输入的数字 xff0c 然后将键盘输入的数字依次存入一维数组 xff1b 假定数组中某一元素为最大值 xff0c 将其与其他元素逐一比较 xff0c 得到最大的数为max值 xff1b 最后得到的max为
  • 【工程实践】解决 nvcc: command not found

    1 nvcc nvcc 是The main wrapper for the NVIDIA CUDA Compiler suite Used to compile and link both host and gpu code NVIDIA
  • hdu 5119(dp题)

    题目链接 xff1a http acm hdu edu cn showproblem php pid 61 5119 题目 xff1a Matt has N friends They are playing a game together
  • word(doc/docx)转markdown:使用Typora的插件

    打开你的Typora xff0c 选择文件 gt 导入 第一次导入会让你下载 pandoc 插件 下载链接如下 xff1a https github com jgm pandoc releases download 2 14 1 pando
  • 案例描述:update中,MySQL inner join 和 left join的区别,小结果集驱动大结果集

    场景描述 以一个场景为例 xff1a 单据A xff1a 下游子表 xff08 数据量级小 xff09 单据B xff1a 下游主表 xff08 数据量级小 xff09 单据C xff1a 中游子表 xff08 数据量级小 xff09 单据
  • Hadoop生态圈(一)- Hadoop详解

    目录 前言1 Hadoop概述1 1 Hadoop是什么1 2 Hadoop发展简史1 2 Hadoop三大发行版本1 3 Hadoop优势1 4 Hadoop的组成1 4 1 Hadoop1 x 2 x 3 x区别1 4 2 HDFS架构
  • arduino硬件总结

    文章目录 arduino硬件总结串口通讯I2CSPI中断函数基本了解实现测速 ADC读取光敏传感器的值 pwm舵机控制 arduino硬件总结 arduino 支持中断 xff0c ADC PWM xff0c I2C xff0c spi x
  • 文件上传 - Apache SSI远程命令执行

    文章目录 一 漏洞原理二 漏洞场景 挖掘思路三 触发条件四 漏洞复现4 1 启动环境4 2 访问环境4 3 复现过程 五 防御措施 一 漏洞原理 在测试任意文件上传漏洞的时候 xff0c 目标服务端可能不允许上传php jsp asp后缀的
  • Linux:chmod -R 777 *含义

    Linux xff1a chmod R 777 首先 xff0c chmod命令是linux上用于改变权限的命令 xff0c R 是递归遍历子目录 xff0c 因为你要操作的文件使用的 通配符 777 xff0c 第一个7代表文件所属者的权
  • STM32HAL库学习笔记七——I2C通信

    HAL库快速部署I2C 本文主要介绍如何使用STM32CubeMX快速部署I2C通信 xff0c 并与EEPROM进行数据收发 文章目录 HAL库快速部署I2CI2C简介EEPROM简介HAL库部署IIC通信实现多字节写入一 CubeMX配
  • python报错Statements must be separated by newlines or semicolons解决方法

    今天做练习时遇到这样的报错 xff1a Statements must be separated by newlines or semicolons 翻译一下就是 xff1a 语句必须用换行符或分号分隔 首先按报错提示 xff0c 我把cl

随机推荐

  • python自然语言处理之spacy详解

    spaCy简介 spaCy号称工业级Python自然语言处理 xff08 NLP xff09 软件包 xff0c 可以对自然语言文本做词性分析 命名实体识别 依赖关系刻画 xff0c 以及词嵌入向量的计算和可视化等 spaCy模块有4个非常
  • anaconda创建env报错 ResolvePackageNotFound

    具体错误 如图 xff1a 按照其他博主 xff08 方法详情 xff09 提供的方法操作了还是有部分报错 xff1a 解决策略 继续上面解决剩下的部分报错 xff0c 打开 yaml文件 xff0c 记事本打开就行 将报错列出的几个包移到
  • LDA主题建模过程及参数详解

    平台及工具 语言 xff1a python 平台 xff1a anaconda 43 jupyter notebook 语料库 xff1a 近三百篇英文文献的摘要 主要代码 首先 xff0c pandas处理csv数据 span class
  • 已经成功安装了但是jupyter notebook仍然找不到模块

    问题描述 工具 语言 jupyter notebook 43 anaconda python 有时会遇到这样的情况 xff0c 命名已经install了模块 xff0c notebook还是报找不到模块错误 再装已经提示satisfied
  • pyecharts 地图绘制

    环境描述 win11 jupyter notebook 目标效果 世界地图 43 按数据进行分级着色 xff1b 最终效果图如下 xff1a pyecharts 绘制地图时注意点 可以实现目标地图绘制效果的python库很多 xff0c 这
  • 指定wb用户在指定日期范围内的wb内容抓取

    一 操作步骤 只记录过程 xff0c 不讲述原理 1 获取用户ID和cookie 用户ID在进入个人主页时导航栏中就会有显示 xff0c 例如下面这样 xff1a cookie获取 xff08 有的代码无需cookie也能运行 xff09
  • 中介变量、调节变量与协变量

    在平时看论文过程中偶会接触到这几个概念 xff0c 然而都没想过弄明白 xff0c 每次总觉得只要看明白个大概反正自己又不用这种方法 作为科研人 xff0c 还是应该保持谦逊 xff0c 保持学习 一 中介变量 1 概念 中介变量 xff0
  • linux环境搭建

    文章目录 linux环境搭建基础工具环境docker镜像docker 的基本操作git amp amp sshbash脚本 python 环境 linux环境搭建 基础工具环境 docker镜像 Docker CE 镜像源站 docker如
  • 【Linux】状态机

    Linux 状态机 首先感谢阅读 xff0c 作者是在工作中学习与积累 xff0c 每一个笔记都是心得和积累 xff0c 希望可以和大家一起交流学习 学习咱们先定好计划 xff0c 需要了解的都一样 xff0c 有 xff1a xff08
  • MyBatisPlus源码

    MyBatisPlus源码 文章目录 MyBatisPlus源码1 通用Mapper 96 BaseMapper 96 2 顶级Mapper 96 Mapper 96 3 通用Service 96 IService 96 4 通用Servi
  • bomb二进制炸弹拆除实验(MIPS)

    上学期计算机系统基础课程的一个实验 xff0c 在这里再简略整理一下 xff1a 实验要求 xff1a 仅给定一个MIPS二进制可执行文件bomb xff0c 要求运用GDB调试工具 xff0c 通过分析反汇编代码来输入正确的参数以拆除炸弹
  • 图与网络可视化实战(matlab实现)

    本篇以2020年数学建模美赛D题的足球传球网络可视化为例 xff0c 分三大步骤来简单讲解一下matlab在图与网络可视化方面的应用 xff1a Step1 构图 xff1a 首先根据输入数据构造邻接矩阵 xff0c 然后调用matlab中
  • Week8 - 程序设计思维与实践 - HRZ的序列(第二次CSP模拟T1)

    T1 HRZ的序列 该比赛已结束 xff0c 您无法在比赛模式下递交该题目 您可以点击 在题库中打开 以普通模式查看和递交本题 题目描述 相较于咕咕东 xff0c 瑞神是个起早贪黑的好孩子 xff0c 今天早上瑞神起得很早 xff0c 刷B
  • Week8 - 程序设计思维与实践 - HRZ学英语(第二次CSP模拟T2)

    T2 HRZ学英语 该比赛已结束 xff0c 您无法在比赛模式下递交该题目 您可以点击 在题库中打开 以普通模式查看和递交本题 题目描述 瑞神今年大三了 xff0c 他在寒假学会了英文的26个字母 xff0c 所以他很兴奋 xff01 于是
  • Week14 - 程序设计思维与实践 - 矩阵快速幂(+优化DP)

    题目连接 A Q老师与石头剪刀布 xff08 必做 xff09 题意 每一个大人曾经都是一个小孩 xff0c Q老师 也一样 为了回忆童年 xff0c Q老师 和 Monika 玩起了石头剪刀布的游戏 xff0c 游戏一共 n 轮 无所不知
  • Week14 - 程序设计思维与实践 - HDU3700 - Cat(限时模拟)

    Problem Description There is a cat cat likes to sleep If he sleeps he sleeps continuously no less than A hours For some
  • SDU《程序设计思维与实践》课程个人感想

    这门课到此也就宣告结束了呀 xff0c 回想过去居家学习的 16 周真的是既辛酸又充实 由于是非竞赛生 xff0c 之前没怎么接触过算法刷题这一方面 xff0c 唯一学的点算法也是来自上学期的数据结构 xff0c 回想刚开始上这门课的时候
  • 跳表的实现、分析以及可视化(Qt C++、Graphviz)

    演示程序截图 实现功能 跳表初始化跳表的查找操作跳表的插入操作跳表的删除操作 xff08 指定关键字的元素 关键字最小的元素 关键字最大的元素 xff09 跳表可视化 程序结构设计 初始化模块 xff1a void Initializati
  • 1、stm32F103入门学习--开发环境搭建(一)

    stm32简介 这款是网上销量比较多的板子 xff0c 我找板子主要还是看价格 xff0c 20元左右 xff0c 不需要太贵 xff0c 只是做个核心入门 xff0c 不要太多的外设 xff0c 特别是对初学者 xff0c 因为从来没见过
  • 森林与二叉树之间的转换以及可视化演示(C++实现)

    演示程序截图 基本要求 构造并实现森林的ADT和二叉树ADT xff0c 森林ADT中应包括初始化 插入元素 删除元素 xff0c 插入边 xff0c 删除边 xff0c 转换成二叉树 xff0c 显示森林及对应的二叉树等基本操作 xff0