编译原理第一次实验报告

news2024/11/5 14:58:06
  • 源代码及附件:编译原理实验一源程序及附件资源-CSDN文库
  • 实验题目

  • 实验要求

  • 实验设计

前两部分指出了实验的宏观把控,为了具体实施实验,我们需要预先为实验做出如下设计:

本次实验我选取了C语言的一个子集进行设计词法分析器,其中单词种类如下:(也可参考附件中的单词种类表)

根据题目要求,我们用正则文法来定义我们的子集:

  1. S→关键字|运算符|分界符|整型常量|浮点型常量|标识符
  2. 关键字

→ void|main|int|float|for|while|switch|case|if|else|return|break

(3)运算符 → +|-|*|/|=|==|<|<=|>|>=

(4)分界符 → (|)|[|]|{|}|,|;|:

(5)整型常量 → digit(digit)*

(6)浮点型常量 → digit(digit).digit(digit)

(7)digit→ 0|1|2|3|4|5|6|7|8|9

(8)letter→ a|b|…|z|A|B|…|Z

(9)标识符 → letter(letter|digit)*

  • 实验分析

基本算法思想是:读取文件,逐个字符分析,若是空白符则跳过,为字母时将连续的字母使用超前搜索组合成为变量或关键字;若是数字,则要判断是否为浮点数,即利用超前搜索,判断扫描到的字符是否为小数点;若是分隔符或者操作符,利用switch语句判断并输出,若是其他字符,输出为未定义的字符。

相关代码段:

void lexicalAnalysis(FILE* fp)

{

    char ch;        

    while ((ch = fgetc(fp)) != EOF)    /

    {

        token = ch;                                   

        if (ch == ' ' || ch == '\t' || ch == '\n'//忽略空格、Tab和回车

        {

             if (ch == '\n')                            //遇到换行符,记录行数的row加1

                 row++;

             continue;                                

        }

        else if (isLetter(ch))        //以字母开头,关键字或标识符

        {

             token = "";                   //token初始化

             while (isLetter(ch) || isDigit(ch)) //非字母或数字时退出,将单词存储在token中

             {

                 token.push_back(ch);  //将读取的字符ch存入token中

                 ch = fgetc(fp);           //获取下一个字符

             }

             //文件指针后退一个字节,即重新读取上述单词后的第一个字符

             fseek(fp, -1L, SEEK_CUR);

             if (isKey(token)) //关键字

                 code = TokenCode(getKeyID(token));

             else //标识符

                 code = TK_IDENT; //单词为标识符

        }

        else if (isDigit(ch)) //无符号常数以数字开头

        {

             int isdouble = 0; //标记是否为浮点数

             token = "";          //token初始化

             while (isDigit(ch))   //当前获取到的字符为数字

             {

                 token.push_back(ch);      //读取数字,将其存入token中

                 ch = fgetc(fp);               //从文件中获取下一个字符

                 //该单词中第一次出现小数点

                 if (ch == '.' && isdouble == 0)

                 {

                     //小数点下一位是数字

                     if (isDigit(fgetc(fp)))

                     {

                         isdouble = 1;    //标记该常数中已经出现过小数点

                         fseek(fp, -1L, SEEK_CUR);     //将超前读取的小数点后一位重新读取

                         token.push_back(ch);          //将小数点入token中

                         ch = fgetc(fp);               //读取小数点后的下一位数字

                     }

                 }

             }

             if (isdouble == 1)

                 code = TK_DOUBLE; //单词为浮点型

             else

                 code = TK_INT;                //单词为整型

             //文件指针后退一个字节,即重新读取常数后的第一个字符

             fseek(fp, -1L, SEEK_CUR);

        }

        else switch (ch)

        {

             /*运算符*/

        case '+': code = TK_PLUS;     //+加号         

             break;

        case '-': code = TK_MINUS;    //-减号

             break;

        case '*': code = TK_STAR;     //*乘号     

             break;

        case '/': code = TK_DIVIDE;        //除号

             break;

        case '=':

        {

             ch = fgetc(fp);               //超前读取'='后面的字符

             if (ch == '=')                //==等于号

             {

                 token.push_back(ch);  //将'='后面的'='存入token中

                 code = TK_EQ;        //单词为"=="

             }

             else {                        //=赋值运算符

                 code = TK_ASSIGN;     //单词为"="

                 fseek(fp, -1L, SEEK_CUR); //将超前读取的字符重新读取

             }

        }

        break;

        case '<':

        {

             ch = fgetc(fp);               //超前读取'<'后面的字符

             if (ch == '=')                //<=小于等于号

             {

                 token.push_back(ch);  //将'<'后面的'='存入token中

                 code = TK_LEQ;            //单词为"<="

             }

             else {                        //<小于号

                 code = TK_LT;        //单词为"<"

                 fseek(fp, -1L, SEEK_CUR); //将超前读取的字符重新读取

             }

        }

        break;

        case '>':

        {

             ch = fgetc(fp);               //超前读取'>'后面的字符

             if (ch == '=')                //>=大于等于号

             {

                 token.push_back(ch);  //将'>'后面的'='存入token中

                 code = TK_GEQ;            //单词为">="

             }

             else {                        //>大于号

                 code = TK_GT;        //单词为">"

                 fseek(fp, -1L, SEEK_CUR); //将超前读取的字符重新读取

             }

        }

        break;

        /*分界符*/

        case '(': code = TK_OPENPA;        //(左圆括号

             break;

        case ')': code = TK_CLOSEPA;   //)右圆括号

             break;

        case '[': code = TK_OPENBR;        //[左中括号

             break;

        case ']': code = TK_CLOSEBR;   //]右中括号

             break;

        case '{': code = TK_BEGIN;    //{左大括号

             break;

        case '}': code = TK_END;      //}右大括号

             break;

        case ',': code = TK_COMMA;    //,逗号

             break;

        case ';': code = TK_SEMOCOLOM; //;分号

             break;

        case':':code = TK_MAO;//:冒号

             break;

             //未识别符号

        default: code = TK_UNDEF;

        }

        print(code);              //打印词法分析结果

    }

}

定义了如下数据结构作为状态终态:

    /* 关键字 */

    KW_VOID, //void关键字

    KW_MAIN, //main关键字

    KW_INT,      //int关键字

    KW_DOUBLE,   //double关键字

    KW_FOR,      //for关键字

    KW_WHILE,    //while关键字

    KW_SWITCH,   //switch关键字

    KW_CASE, //case关键字

    KW_IF,       //if关键字

    KW_ELSE, //else关键字

    KW_RETURN,   //return关键字

    KW_BREAK,//break关键字

    /* 运算符 */

    TK_PLUS, //+加号

    TK_MINUS,    //-减号

    TK_STAR, //*乘号

    TK_DIVIDE,   ///除号

    TK_ASSIGN,   //=赋值运算符

    TK_EQ,       //==等于号

    TK_LT,       //<小于号

    TK_LEQ,      //<=小于等于号

    TK_GT,       //>大于号

    TK_GEQ,      //>=大于等于号

    TK_MAO,    //:冒号

    /* 分隔符 */

    TK_OPENPA,   //(左圆括号

    TK_CLOSEPA//)右圆括号

    TK_OPENBR,   //[左中括号

    TK_CLOSEBR//]右中括号

    TK_BEGIN,    //{左大括号

    TK_END,      //}右大括号

    TK_COMMA,    //,逗号

    TK_SEMOCOLOM, //;分号

    /* 常量 */

    TK_INT,      //整型常量

    TK_DOUBLE,   //浮点型常量

    /* 标识符 */

TK_IDENT

  为了使得输出有所取分,使用不同颜色输出:

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED); //未识别的符号为红色

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_BLUE);    //关键字为蓝色

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN);   //运算符和分隔符为绿色

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN);   //常量为黄色

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY); //关键字为灰色

利用文件作为输入。

输入文档1.txt:

double add(double x, double y)

{

    double a = 3.456;

    return x + y;

}

$

int main()

{

            int i;

            switch(i)

           {

               case 1:   break;

            }

            if(double(i,i)>i)

                  break;

            int a[10];

}         

输出结果为:

其中注意红色标记:

说明我们实现了错误识别的功能。

  • 源代码

#include <iostream>

#include <string>

#include <Windows.h>

using namespace std;

/* 单词编码 */

enum TokenCode

{

    /*未定义*/

    TK_UNDEF = 0,

    /* 关键字 */

    KW_VOID, //void关键字

    KW_MAIN, //main关键字

    KW_INT,      //int关键字

    KW_DOUBLE,   //double关键字

    KW_FOR,      //for关键字

    KW_WHILE,    //while关键字

    KW_SWITCH,   //switch关键字

    KW_CASE, //case关键字

    KW_IF,       //if关键字

    KW_ELSE, //else关键字

    KW_RETURN,   //return关键字

    KW_BREAK,//break关键字

    /* 运算符 */

    TK_PLUS, //+加号

    TK_MINUS,    //-减号

    TK_STAR, //*乘号

    TK_DIVIDE,   ///除号

    TK_ASSIGN,   //=赋值运算符

    TK_EQ,       //==等于号

    TK_LT,       //<小于号

    TK_LEQ,      //<=小于等于号

    TK_GT,       //>大于号

    TK_GEQ,      //>=大于等于号

    TK_MAO,    //:冒号

    /* 分隔符 */

    TK_OPENPA,   //(左圆括号

    TK_CLOSEPA//)右圆括号

    TK_OPENBR,   //[左中括号

    TK_CLOSEBR//]右中括号

    TK_BEGIN,    //{左大括号

    TK_END,      //}右大括号

    TK_COMMA,    //,逗号

    TK_SEMOCOLOM, //;分号

    /* 常量 */

    TK_INT,      //整型常量

    TK_DOUBLE,   //浮点型常量

    /* 标识符 */

    TK_IDENT

};

TokenCode code = TK_UNDEF;    //记录单词的种别码

const int MAX = 12;               //关键字数量

int row = 1;                  //记录字符所在的行数

string token = "";                //用于存储单词

char  keyWord[][10] = { "void","main","int","double","for","while","switch","case","if","else","return","break"};    //存储关键词

void print(TokenCode code)

{

    switch (code)

    {

        /*未识别的符号*/

    case TK_UNDEF:

        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED); //未识别的符号为红色

        cout << '(' << code << ',' << token << ")" << "未识别的符号在第" << row << "行。" << endl;

        return;

        break;

        /*关键字*/

    case KW_VOID:

    case KW_MAIN:

    case KW_INT:    

    case KW_DOUBLE

    case KW_FOR:    

    case KW_WHILE:  

    case KW_SWITCH

    case KW_CASE:

    case KW_IF:     

    case KW_ELSE:

    case KW_RETURN

    case KW_BREAK:

        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_BLUE);    //关键字为蓝色

        break;

        /* 运算符 */

    case TK_PLUS:

    case TK_MINUS:  

    case TK_STAR:

    case TK_DIVIDE

    case TK_ASSIGN

    case TK_EQ:     

    case TK_LT:     

    case TK_LEQ:

    case TK_GT:     

    case TK_GEQ:        

    /* 分隔符 */

    case TK_OPENPA

    case TK_CLOSEPA:

    case TK_OPENBR

    case TK_CLOSEBR:

    case TK_BEGIN:  

    case TK_END:

    case TK_COMMA:  

    case TK_SEMOCOLOM:   

    case TK_MAO:   

        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN);   //运算符和分隔符为绿色

        break;

        /* 常量 */

    case TK_INT:

    case TK_DOUBLE

        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN);   //常量为黄色

        if (token.find('.') == token.npos)

             cout << '(' << code << ',' << atoi(token.c_str()) << ")" << endl;                     

        else

             cout << '(' << code << ',' << atof(token.c_str()) << ")" << endl;                         

        return;

        break;

        /* 标识符 */

    case TK_IDENT:

        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY); //关键字为灰色

        break;

    default:

        break;

    }

    cout << '(' << code << ',' << token << ")" << endl;

}

bool isKey(string token)

{

    for (int i = 0; i < MAX; i++)

    {

        if (token.compare(keyWord[i]) == 0)

             return true;

    }

    return false;

}

int  getKeyID(string token)

{

    for (int i = 0; i < MAX; i++)

    {   //关键字的内码值为keyWord数组中对应的下标加1

        if (token.compare(keyWord[i]) == 0)

             return i + 1;

    }

    return -1;

}

bool isLetter(char letter)

{

    if ((letter >= 'a' && letter <= 'z') || (letter >= 'A' && letter <= 'Z'))

        return true;

    return false;

}

bool isDigit(char digit)

{

    if (digit >= '0' && digit <= '9')

        return true;

    return false;

}

void lexicalAnalysis(FILE* fp1)

{

    char ch;        

    while ((ch = fgetc(fp1)) != EOF)  

    {

        token = ch;                                   

        if (ch == ' ' || ch == '\t' || ch == '\n'

        {

             if (ch == '\n')                           

                 row++;

             continue;                                

        }

        else if (isLetter(ch))       

        {

             token = "";                  

             while (isLetter(ch) || isDigit(ch))

             {

                 token.push_back(ch); 

                 ch = fgetc(fp1);     

             }

             fseek(fp1, -1L, SEEK_CUR);

             if (isKey(token))

                 code = TokenCode(getKeyID(token));

             else

                 code = TK_IDENT;

        }

        else if (isDigit(ch))

        {

             int isdouble = 0;

             token = "";         

             while (isDigit(ch))  

             {

                 token.push_back(ch);     

                 ch = fgetc(fp1);             

                

                 if (ch == '.' && isdouble == 0)

                 {

                     if (isDigit(fgetc(fp1)))

                     {

                         isdouble = 1;   

                         fseek(fp1, -1L, SEEK_CUR);   

                         token.push_back(ch);         

                         ch = fgetc(fp1);             

                     }

                 }

             }

             if (isdouble == 1)

                 code = TK_DOUBLE;

             else

                 code = TK_INT;               

             fseek(fp1, -1L, SEEK_CUR);

        }

        else switch (ch)

        {

        case '+': code = TK_PLUS;                 

             break;

        case '-': code = TK_MINUS;   

             break;

        case '*': code = TK_STAR;             

             break;

        case '/': code = TK_DIVIDE;       

             break;

        case '=':

        {

            ch = fgetc(fp1);             

             if (ch == '=')               

             {

                 token.push_back(ch); 

                 code = TK_EQ;       

             }

             else {                       

                 code = TK_ASSIGN;    

                 fseek(fp1, -1L, SEEK_CUR);

             }

        }

        break;

        case '<':

        {

             ch = fgetc(fp1);             

             if (ch == '=')               

            {

                 token.push_back(ch); 

                 code = TK_LEQ;           

             }

             else {                       

                 code = TK_LT;       

                 fseek(fp1, -1L, SEEK_CUR);

             }

        }

        break;

        case '>':

        {

             ch = fgetc(fp1);             

             if (ch == '=')               

             {

                 token.push_back(ch); 

                 code = TK_GEQ;           

             }

             else {                       

                 code = TK_GT;       

                 fseek(fp1, -1L, SEEK_CUR);

             }

        }

        break;

       

        case '(': code = TK_OPENPA;       

             break;

        case ')': code = TK_CLOSEPA;  

             break;

        case '[': code = TK_OPENBR;       

             break;

        case ']': code = TK_CLOSEBR;  

             break;

        case '{': code = TK_BEGIN;   

             break;

        case '}': code = TK_END;     

             break;

        case ',': code = TK_COMMA;   

             break;

        case ';': code = TK_SEMOCOLOM;

             break;

        case':':code = TK_MAO;

             break;

            

        default: code = TK_UNDEF;

        }

        print(code);              //打印词法分析结果

    }

}

int main()

{

    string filename;     

    FILE* fp1;               

    cout << "请输入源文件名:" << endl;

    while (true) {

        cin >> filename;     

        if ((fopen_s(&fp1, filename.c_str(), "r")) == 0)    

             break;

        else

             cout << "路径输入错误!" << endl; 

    }

    cout << "/=***************************词法分析结果***************************=/" << endl;

    lexicalAnalysis(fp1);     //词法分析

    fclose(fp1);

    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); //字体恢复原来的颜色

    return 0;

}

  • 实验总结

这是编译原理的第一次实验,之前因为理解题意不明,也与老师探讨了多次,上网查阅各种资料等等,最终终于完成了实验。

在实验过程中发生过种种问题,一开始为图方便,想到过使用硬编码来实现实验,但最终还是使用了FA的方式。

通过本次实验,我对NFA、DFA的知识有了更深入的了解,编程能力也进一步增强,可以说这次实验是我对编译原理与实际应用的第一次初步实现,对我的影响深远!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2231115.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Llama 3.2 Vision Molmo:多模态开源生态系统基础

编者按&#xff1a; 视觉功能的融入对模型能力和推理方式的影响如何&#xff1f;当我们需要一个既能看懂图像、又能生成文本的 AI 助手时&#xff0c;是否只能依赖于 GPT-4V 这样的闭源解决方案&#xff1f; 我们今天为大家分享的这篇文章&#xff0c;作者的核心观点是&#xf…

C++_day01

目录 0. 课前须知 1. C发展历史&#xff08;了解&#xff09; 2. C特点&#xff08;熟悉&#xff09; 3. 面向对象核心术语&#xff08;熟悉&#xff09; 4. 开发环境 5. 新建项目 4. 开发环境 5. 新建项目 0. 课前须知 C的思维与C语言完全不同&#xff0c;不能生搬硬套。 C偏向…

安娜的档案(Anna’s Archive) 镜像网站/国内最新可访问入口(持续更新)

安娜的档案&#xff08;Anna’s Archive&#xff09;是一个颇受关注的资源库。它涵盖了广泛的内容&#xff0c;可能包括各类文献、资料等。其特色在于丰富的信息储备和一定的系统性。安娜的档案&#xff08;Anna’s Archive&#xff09;用户可以从中获取多样的知识和数据&#…

Linux 下执行定时任务之 Systemd Timers

不知道 ECS 因为什么缘故&#xff0c;上面安装的 MySQL 服务老是不定期挂掉&#xff0c;本来想通过 Linux 得 Cron 配置个半小时的定时检测任务&#xff0c;结果一直没有执行&#xff0c;因此又尝试使用了 Systemd Timers 进行了重新配置&#xff0c;简要做个记录。 Systemd Ti…

【星闪EBM-H63开发板】AT固件的接口简介

引言 前面介绍了星闪EBM-H63开发板的透传固件&#xff0c;现在介绍一下AT固件。AT固件比透传固件要复杂的多&#xff0c;都让功能也多很多&#xff0c;可以配置很多星闪相关的参数。AT固件没有AT命令模式和数据模式切换的问题&#xff0c;因为收发的数据是出现在AT命令中的。 …

51单片机教程(四)- 点亮LED灯

1、项目分析 让输入/输出口的P1.0连接一盏LED灯进行点亮。 2、技术准备 1 LED组成 ​ 说明 二极管有 P型 和 N型材料构成&#xff0c;通常是&#xff1a;硅/锗 掺杂其他元素&#xff08;硼、磷等&#xff09; 电子是带负电的&#xff0c;是负电荷的载体&#xff0c;电子流…

开源库 FloatingActionButton

开源库FloatingActionButton Github:https://github.com/Clans/FloatingActionButton 这个库是在前面这个库android-floating-action-button的基础上修改的&#xff0c;增加了一些更强大和实用的特性。 特性&#xff1a; Android 5.0 以上点击会有水波纹效果 可以选择自定义…

Ubuntu 24.04上启用 root 用户通过 SSH 和图形界面进行登录

一、启用 root 用户的密码登录 设置 root 用户密码&#xff1a; 在终端中输入以下命令为 root 用户设置一个密码&#xff1a; testtest-virtual-machine:~$ sudo passwd root [sudo] test 的密码&#xff1a; 新的密码&#xff1a; 无效的密码&#xff1a; 密码是一个回文…

深度学习基础知识-损失函数

目录 1. 均方误差&#xff08;Mean Squared Error, MSE&#xff09; 2. 平均绝对误差&#xff08;Mean Absolute Error, MAE&#xff09; 3. Huber 损失 4. 交叉熵损失&#xff08;Cross-Entropy Loss&#xff09; 5. KL 散度&#xff08;Kullback-Leibler Divergence&…

基于vue框架的的考研信息共享平台v0eyp(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;国家政策,用户,院校政策,院校信息,考研资料,资料分类,考研论坛 开题报告内容 基于Vue框架的考研信息共享平台开题报告 一、研究背景与意义 随着考研人数的逐年增长&#xff0c;考研学生对高效、便捷、个性化的信息获取需求愈发强烈。…

区别:矩阵合同和矩阵酉相似

矩阵的合同和酉相似在许多方面具有相似性&#xff0c;但也有明显的区别。 定义 矩阵合同&#xff1a;给定矩阵 A 和 B &#xff0c;若存在一个非奇异矩阵 P &#xff0c;使得 则称矩阵 A 和 B 是合同的。合同变换常用于实对称矩阵的特征问题等。 酉相似&#xff1a;给定矩阵 …

海的回忆:海滨学院班级记忆录技术实现

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…

半个月,练完这50个Python实战项目你就牛了!

今日精选50个Python实战项目&#xff0c;边做边学&#xff0c;让Python技能突飞猛进&#xff01; 好记性不如烂笔头&#xff0c;实践是提升技能的王道&#xff01;这70个项目涵盖广泛&#xff0c;难度亲民&#xff0c;特别适合Python新手入门与进阶。它们不仅实用性强&#xf…

贪心算法习题其三【力扣】【算法学习day.20】

前言 ###我做这类文档一个重要的目的还是给正在学习的大家提供方向&#xff08;例如想要掌握基础用法&#xff0c;该刷哪些题&#xff1f;&#xff09;我的解析也不会做的非常详细&#xff0c;只会提供思路和一些关键点&#xff0c;力扣上的大佬们的题解质量是非常非常高滴&am…

【Python游戏开发】石头剪刀布游戏(附完整Python完整代码)

石头剪刀布游戏:Pygame实现 结果图前言核心函数思考步骤实现原理和公式代码实现结论结果图 前言 石头剪刀布是一种经典的猜拳游戏,简单易玩但却蕴含着一定的策略性。本文将介绍如何使用Python和Pygame库开发一个简单的石头剪刀布游戏,并探讨其中的核心功能实现和思考过程。 …

Python | Leetcode Python题解之第526题优美的排列

题目&#xff1a; 题解&#xff1a; class Solution:def countArrangement(self, n: int) -> int:f [0] * (1 << n)f[0] 1for mask in range(1, 1 << n):num bin(mask).count("1")for i in range(n):if mask & (1 << i) and (num % (i …

阿里云k8s-master部署CNI网络插件遇到的问题

问题 按照网络上的部署方法 cd /opt/k8s # 下载 calico-kube-controllers配置文件&#xff0c;可能会网络超时 curl https://docs.projectcalico.org/manifests/calico.yaml -O kubectl apply -f calico.yaml 试了很多次都不行&#xff0c;k8s-master都是Not ready的状态 ca…

【数据结构与算法】第8课—数据结构之二叉树(堆)

文章目录 1. 树1. 什么是树&#xff1f;1.2 树的相关概念1.3 树的表示法 2. 二叉树2.1 特殊的二叉树2.2 二叉树的性质2.3 二叉树的存储结构 3. 实现顺序结构二叉树3.1 堆的概念3.2 堆的实现3.2.1 堆的数据结构3.2.2 堆的初始化3.2.3 堆插入数据3.2.4 删除堆顶数据3.2.5 堆的判空…

基于MATLAB人脸检测的汽车疲劳驾驶检测

课题介绍 疲劳驾驶导致汽车交通事故逐年增加&#xff0c;为了提升驾车的安全性&#xff0c;需对驾驶员疲劳状态实时监测并及时提醒. 为了提高疲劳驾驶判断效率及准确率&#xff0c;本文运用Viola-Jones 框架特征矩阵进行人脸预判断&#xff1b;预判断过程中为了减少Haar 值计算…

【p2p、分布式,区块链笔记 Torrent】WebTorrent的上传和下载界面

上传 upload.html client.seed <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>文件上传与哈希值&l…