BUAA 2020级“数据结构与程序设计”期中考试【含试卷下载】

<< 其他专栏文章

试卷下载

2020级“数据结构与程序设计”期中考试(试卷下载,提取码:buaa)
2020级期中模拟考试(试卷下载,提取码:buaa)

期中考试

1. 标识符的识别

【问题描述】

从控制台读⼊⼀⾏符合C语⾔语法要求的语句,该语句以分号结束。编写程序抽取出语句中的标识符,重复的标识符只 保留⼀个,然后按照字典序由⼩到⼤的顺序输出这些标识符。

规定:

1)读⼊的语句中字符个数不超过200,每个标识符的字符个数不超过32,语句中标识符的个数不超过50个,且⾄少有
⼀个标识符。

2)读⼊的语句中不会出现字符常量、字符串常量,也没有注释。

3)读⼊的语句中不会出现带后缀的常量类型:例如:2.5f、15l、18L、106ll、5u等情况。

【输⼊形式】

从控制台输⼊⼀⾏符合C语⾔语法要求的语句,语句以英⽂分号结束,末尾有回⻋符。

【输出形式】

按照字典序由⼩到⼤的顺序输出抽取出的标识符,各标识符间以⼀个空格分隔,最后⼀个标识符后有⽆空格均可。

【样例输⼊】

array_sum[i] = array_a[i] +array_a[j]+ _next2[ j ]getArea( x, y , z) - 100i;

【样例输出】

_next2 array_a array_sum getArea i j x y z

【样例说明】

从控制台读⼊的语句中有5个普通的变量:i、j、x、y和z,三个数组名:array_sum、array_a和_next2,⼀个函数调 ⽤,其函数名为getArea,将这9个标识符按照字典序由⼩到⼤排序输出。

「代码」
#include <stdio.h>
#include <string.h>
#include <ctype.h>

struct Name {
    char name[35];
};

int isdigit_str(char array[], int n);

int main(int argc, const char * argv[]) {

    struct Name info[55];
    char a[250];
    gets(a);
    //getword
    int n=0;
    for(int i=0,j=0,k=0 ;a[i]!='\0';i++)
    {
        if( isalpha(a[i]) || isdigit(a[i]) || a[i]=='_' ){
            info[j].name[k]=a[i];
            k++;
        }
        else if(k>0){//说明info[j].name[k]中已经至少有一个字符
            info[j].name[k]='\0';
            j++;
            n++;
            k=0;
        }
    }
    //去重
    for(int i=0; i<n; i++)
    for(int j=i+1; j<n; j++){
        if(strcmp(info[i].name,info[j].name)==0)
            strcpy(info[j].name, "-1");
        
    }
    
    for(int i=0; i<n; i++){
        if(isdigit_str(info[i].name,n))
            strcpy(info[i].name, "-1");
        
    }
    
    
    //sortbyname
    struct Name tmp;
    for(int i=0; i<n; i++)
    for(int j=i; j<n; j++){
        if(strcmp(info[i].name,info[j].name)>0)
        {
            tmp = info[i];
            info[i] = info[j];
            info[j] = tmp;
        }
    }
    //bianli
    for(int i=0;i<n;i++)
        if( strcmp(info[i].name,"-1")!=0 )//姓名为-1,判断为删除项
            printf("%s ", info[i].name);
    return 0;
}


int isdigit_str(char array[], int n)
{
    int j;
    int s=0;
    
    for(j=0; array[j]!='\0'; j++)
        if(isdigit(array[j]))
        {
            s++;
        }
    if(strlen(array)==s)
        return 1;
    else
        return 0;
}

2. 空闲空间申请模拟(⾸次适应)

【问题描述】

在操作系统中,空闲存储空间通常以空闲块链表⽅式组织,每个块包含块起始位置、块⻓度及⼀个指向下⼀块的指针。空闲块按照存储位置升序组织,最后⼀块指向第⼀块(构成循环链表)。当有空间申请请求时,按照如下原则在空闲块循环链表中寻找并分配合适的空间:

1)从当前位置开始遍历空闲块链表(初始时从地址最⼩的第⼀个空闲块开始),寻找第⼀个⼤于等于请求空间的空闲块(即⾸次适应原则);

2)如果选择的空闲块恰好与请求的⼤⼩相符合,则将它从链表中移除并返回给⽤户;这时当前位置变为被移除的空闲块指向的下⼀空闲块;

3)如果选择的空闲块⼤于所申请的空间⼤⼩,则将⼤⼩合适的空闲块返回给⽤户,剩下的部分留在空闲块链表中;这时当前位置仍然为该空闲块;

4)如果找不到⾜够⼤的空闲块,则申请失败;这时当前位置不变。

例如:下图示例给出了空闲块链表的初始状态,每个结点表示⼀个空闲块,结点中上⾯的数字指空闲块的起始位置,下⾯的数字指空闲块的⻓度,位置和⻓度都⽤正整数表示,⼤⼩不超过int表示范围。当前位置为最⼩地址为1024的空闲块。

若有4个申请空间请求,申请的空间⼤⼩依次为:1024、2560、10240和512。则从当前位置开始遍历上图的链表,按照上述原则寻找到满⾜条件的空闲块为地址是16384的空闲块,其⻓度正好为1024,所以将其从链表中删除,这时链表状态如下图所示,当前位置变成地址为32768的空闲块。

从当前位置开始为第⼆个空间请求(⼤⼩为2560)遍历链表,按照上述原则寻找到满⾜条件的空闲块为当前位置的空闲块,其⻓度为3072,⼤于请求的空间⼤⼩,于是申请空间后该空闲块剩余的⻓度为512,当前位置不变,链表状态如下图所示:

从当前位置开始为第三个空间请求(⼤⼩为10240)遍历链表,遍历⼀圈后发现找不到⾜够⼤的空闲块,则忽略该请求,当前位置不变。下⾯继续为第四个空间请求(⼤⼩为512)遍历链表,按照上述原则寻找到满⾜条件的空闲块仍然为当前位置的空闲块,其⻓度等于请求的空间⼤⼩,于是将该空闲块删除后,链表状态变为下图所示:

编写程序,模拟上述空闲空间申请。

【输⼊形式】

先从控制台读⼊⼀正整数,表示当前空闲块的个数(⼤于0且⼩于等于100)。

然后按照起始位置由⼩到⼤的顺序分⾏输⼊每个空闲块的起始位置和⻓度,位置和⻓度都⽤正整数表示,⼤⼩不超过int表示范围,两整数间以⼀个空格分隔。

最后在新的⼀⾏上依次输⼊申请空间的⼤⼩,以-1表示结束,各整数间以⼀个空格分隔,申请请求的个数不超过100个。

【输出形式】

按照上述原则模拟完空闲空间申请后,输出当前空闲空间链表状态,即从当前位置开始,遍历链表,分⾏输出剩余空闲块的起始位置和⻓度,位置和⻓度间以⼀个空格分隔。若申请完后,链表中没有空闲块,则什么都不输出。

【样例输⼊】

12
1024 512
8192 512
16384 1024
32768 3072
65536 8192
77824 1024
80896 8192
96016 1024
101136 5120
119328 512
134448 1024
142640 3072
1024 2560 10240 512 2048 6400 2560 5600 2000 -1

【样例输出】

101136 560
119328 512
134448 1024
142640 3072
1024 512
8192 512
65536 544
77824 1024
80896 1792
96016 1024

【样例说明】

样例输⼊了12个空闲块的信息,形成了如上述第⼀个图所示的空闲块链表;然后读取了9个空间申请请求,为前4个申请请求分配空间后,空闲块链表状态为上述最后⼀张图所示。满⾜第五个请求后,地址为65536的空闲块剩余⻓度为6144;满⾜第六个请求后,地址为80896的空闲块剩余⻓度为1792;满⾜第七个请求后,地址为101136的空闲块剩余⻓度为2560;满⾜第⼋个请求后,地址为65536的空闲块剩余⻓度为544;满⾜第九个请求后,地址为101136的空闲块剩余⻓度为560,这时链表中剩余10个空闲块,当前位置为地址是101136的空闲块,从该空闲块开始依次遍历输出所有剩余空闲块的起始位置和⻓度。

  • 3
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值