程序设计基础课程设计 —— 学校地图信息库系统

简介: 程序设计基础课程设计 —— 学校地图信息库系统

 通过参与本课程设计,你将有机会实现一个学校地图信息库系统。这个系统不仅能够让你充分发挥自己的想象力和动手能力,还能让你在实践中掌握多种计算机科学的核心技能。

  1. 最短路径算法:在本课程中,你将学习并掌握两种常用的最短路径算法——Dijkstra算法和Floyd算法。这两种算法在解决图论中的最短路径问题时具有广泛的应用。通过实践,你将深入理解这两种算法的原理和应用方法,为后续的编程项目打下坚实的基础。
  2. 文件操作:在开发过程中,你将学会如何利用文件来保存程序运行的数据信息。这一技能对于数据的持久化存储至关重要,无论是为了后续的分析还是为了方便用户查看历史数据,都离不开对文件的操作。
  3. 二维数组与字符串:二维数组是计算机科学中的一种基本数据结构,它可以用来表示各种复杂的数据关系。在本课程中,你将通过实际的项目需求,深入理解和掌握二维数组的使用。同时,你也将学习到如何在程序中处理和操作字符串,这在数据处理和用户交互中都是非常关键的技能。
  4. 文件操作代码:除了基本的打开文件和保存文件操作,你还将学会如何在程序中进行输入操作。这些技能将帮助你更好地与用户进行交互,使得你的程序更加易用和灵活。
  5. 全局变量的定义和使用:全局变量在程序设计中起着重要的作用,它们可以在程序的不同部分之间共享数据。在本课程中,你将学习如何定义和使用全局变量,以及如何在保证程序可读性和可维护性的同时,合理地使用全局变量。

       1.核心功能是最短路径的检索和输出。该功能可以由用户给定的点到全部点的最短路径,并提供景点代号、名称、简介等信息供用户查询。通过这个功能,用户可以方便地找到从当前位置到其他景点的最短路径,以便更高效地安排他们的行程。

       2.为来访客人提供图中任意景点相关信息的查询。该功能可以根据用户输入的起始景点编号,求出该景点到其他景点的最短路径线路及距离。这样,游客可以根据他们感兴趣的景点,快速了解到达其他景点的最佳路线,以便更好地规划他们的游览路线。

       3.为校园平面图增加和删除景点或边,修改边上的权值等。这个功能允许管理员对校园平面图进行维护和更新。他们可以添加新的景点或边,或者删除不再存在的景点或边。此外,他们还可以修改边上的权值,以反映不同景点之间的实际距离或通行时间。这样,校园导航小助手可以提供最准确和最新的导航信息,以满足用户的需求。

整体设计如下图

       实现了通过文件的方式保存地点信息和地点的存放景点代号、名称、简介等信息供用户查询,为来访客 人提供图中任意景点相关信息的查询距离信息分别为tu.txt、tu1.txt和最短路径FloydALGraph.txt,在程序进入时自动加载完成数据,将文件数据保存在相应的数组里。

       将函数名放在主函数里,在开启程序时完成自动载入数据。

       以模块化方式编写程序,可以使其层次清晰,易于调试和维护,让程序简而不繁。

       总的项目在完成任务的基础上添加了一些小功能,让用户体验更上一层楼,总的效果符合个人所想和设计的要求,算法上的总的时间复杂度在区间(O(1)到O(N2))上,掌握了文件的运用和Dijistra算法的运用,在算法的基础上还学会了如何让代码更整洁,也学会对代码有很好的命名,让人一目了然,也学会了运用cmd里的特殊代码如清屏函数System(”cls”)等。优点是可以很好的对代码有个很好的理解和算法的运用。

       改进:可继续分多个的模块实现该程序,使其程序更完善,还可以将图信息变成word文档或者变成一副图画的方式让人更容易读解,可以方便用户体验或是直接在程序基础上设计一个打印功。

       完成了存放景点编号,名称,介绍信息来提供用户查询,完成了根据用户需求输入其实景点编号,输出到其他所有景点的最短路线和距离,也完成了任意两点间最短路径的检索,其算法是用Dijkstra实现的。

       如图2所示,是由Dijkstra核心算法完成两点之间的最短路径。

点到所有点的最短路径距离(部分图)如图

Dijkstra核心算法代码,如图

       在此基础上添加了增点,加边,删点,删边,打印邻接矩阵(下图)并提示用户是否保存在txt文本里,其次还添加了退出程序保存文件,存放为txt文本,文本的编码是使用ASNI编码的。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<errno.h>
//#define m 5201314
#define max 999999
int ml[100];
int djs[110];
struct node {
  int number;
  char name[40];
  char introduce[500];
  int maxcount;
  int digitor;
}place[100],place1[100];
struct Tnode {
  int distance;
  int bia;
}map1[100][100],map2[100][100];
void inset(char* pFileName){
  FILE *err;
  FILE* pFile;
  err = fopen(pFileName, "r");//读取名为pFileName的文本文件 
  
  if (err == 0)//判断文件是否打开是否成功 
    printf("文件打开失败\n");
  else
    printf("文件打开成功\n");
//  double data[10][3];//先只考虑文件中的数据为10行3列的小数
int i=0;
  while((fscanf(err,"%d",&place[i].number))&&place[i].number!=EOF){
      place1[i].number=place[i].number;
//      getchar();
      fscanf(err,"%s",place[i].name);
      strcpy(place1[i].name,place[i].name);
//      getchar();
    fscanf(err,"%s",place[i].introduce);
    strcpy(place1[i].introduce,place[i].introduce);
    place[i].digitor=place1[i].digitor=0;
//    getchar();
//        printf("%d %s %s\n",place[i].number,place[i].name,place[i].introduce);
    i++;
    
    //fscanf_s函数固定格式读取文本中的数据; 
    }
    place[0].maxcount=place1[0].maxcount=i;
//  for (i = 0;i < place[0].maxcount;i++) {//将读取的数据输出
    for (int j = 0;j < 3;j++)
//      printf("%s",place[i].introduce); 
//    printf("\n");
//  }
  fclose(err);
 
}
void inset1(char* pFileName){
  FILE *err;
  err = fopen(pFileName, "r");
  if (err == 0)
    printf("文件打开失败\n");
  else
    printf("文件打开成功\n");
  for(int i=0;i<place[0].maxcount;i++){
    for(int j=0;j<place[0].maxcount;j++){
      fscanf(err,"%d",&map1[i][j].distance);
//      fgetchar();
      map2[i][j].distance=map1[i][j].distance;
      map1[i][j].bia=map2[i][j].bia=0;
    }
  }
  fclose(err);
 
}
void floyd(int n){
  for (int i = 0; i < n; i++) {//  floyd。
            for (int j = 0; j <n; j++) {
                for (int k = 0; k <n; k++) {
                    if (map2[j][i].distance + map2[i][k].distance <map2[j][k].distance) {
                        map2[j][k].distance = map2[j][i].distance + map2[i][k].distance;
                    }
                }
            }
        }
}
void lujing1(){
  FILE *err=fopen("tu1.txt","w");
  if (err == 0)
    printf("文件打开失败\n");
  else
    printf("文件打开成功\n");
  for(int i=0;i<place1[0].maxcount;i++){
    fprintf(err,"%d\n%s\n%s\n",place1[i].number,place1[i].name,place1[i].introduce);
  }
  fclose(err);
}
void lujing2(){
  FILE *err=fopen("最短路径FloydALGraph.txt","w");
  if (err == 0)
    printf("文件打开失败\n");
  else
    printf("文件打开成功\n");
  for(int i=0;i<place1[0].maxcount;i++){
    for(int j=0;j<place1[0].maxcount;j++){
      fprintf(err,"%d ",map2[i][j].distance);
    }
    fprintf(err,"\n");
  }
  fclose(err);
}
void DJS(int n,int m){    //迪杰斯特拉算法 
  int a,b,c,d,p,min;        
  int x[110],y[110];
  memset(x,-1,sizeof(x));
  memset(djs,0,sizeof(djs));
  memset(y,0,sizeof(y));
  memset(ml,0,sizeof(ml));
  for(a=0;a<place[0].maxcount;a++){
    djs[a]=map2[n][a].distance;
    if(djs[a]<max){
      x[a]=n;
    }
    if(a==n){x[a]=99999;}
  }
  ml[n]=1;
//  int fd=n;
  for(a=1;a<place[0].maxcount;a++){
    min=max;
    for(b=0;b<place[0].maxcount;b++){
      if(ml[b]==0&&djs[b]<min){
        min=djs[b];
        c=b;
      }
    }
    ml[c]=1;
//    fd=c;     //标记该点 
    for(d=0;d<place[0].maxcount;d++){
      if(ml[d]==0&&djs[d]>djs[c]+map2[c][d].distance){
        x[d]=c;
        djs[d]=djs[c]+map2[c][d].distance;
      }
    }
  }
  d=m;
  a=0;
  while(x[d]!=n){
    y[a]=x[d];
    d=x[d];
    a++;
  }
  printf("\n");
  c=a-1;
  printf("路线为:\n");
  printf("%s--->",place[n].name);
  for(a=c;a>=0;a--){
    printf("%s--->",place[y[a]].name); 
  }
  printf("%s\n",place[m].name);
  printf("最短路径长度为:%d 米\n",djs[m]);
}
void lb(){
  system("cls");      //清屏 
  printf("\n\n\n");
  printf("\t\t\t\t\t * * * * * * * * * * * * * * ** * * * * * * * * * * * * * * * * * * * * * * *\n");
  printf("\t\t\t\t\t * *                           *景点列表*                                 * *\n");
  printf("\t\t\t\t\t * ************************************************************************ *\n");
  printf("\t\t\t\t\t * *                                                                      * *\n");
  printf("\t\t\t\t\t * *  <1>学校北门  <2>学校南北门  <3>国际教育学院   <4>数字媒体艺术学院   * *\n");
  printf("\t\t\t\t\t * *                                                                      * *\n");
  printf("\t\t\t\t\t * *  <5>行政楼    <6>信工楼   <7>体育场 <8>商管楼 <9>A座教学楼           * *\n");
  printf("\t\t\t\t\t * *                                                                      * *\n");
  printf("\t\t\t\t\t * *  <10>中区学生宿舍  <11>继续教育学院大楼   <12>B座教学楼  <13>游泳馆  * *\n");
  printf("\t\t\t\t\t * *                                                                      * *\n");
  printf("\t\t\t\t\t * *  <14>报告厅、阶梯教室 <15>大礼堂、体育馆  <16>1食堂 <17>新图书馆     * *\n");
  printf("\t\t\t\t\t * *                                                                      * *\n");
  printf("\t\t\t\t\t * *  <18>2食堂  <19>东区学生宿舍 <20>教授楼 <21>教工宿舍 <22>西区学生宿舍* *\n"); 
  printf("\t\t\t\t\t * *                                                                      * *\n");
  printf("\t\t\t\t\t * *  <23>3食堂 <24>C座教学楼 <25>E座教学楼 <26>5F座教学楼 <27>实验楼     * *\n");
  printf("\t\t\t\t\t * *                                                                      * *\n");
  printf("\t\t\t\t\t * *            <28>H座教学楼                        <29>小镇         * *\n");
  printf("\t\t\t\t\t * ************************************************************************ *\n");
  printf("\t\t\t\t\t * * * * * * * * * * * * * * ** * * * * * * * * * * * * * * * * * * * * * * *\n");
  printf("\n\n\n");
}
//void qing(){
//  int n=place[0].maxcount;
//  for(int i=0;i<n;i++){
//    ml[i]=0;
//  }
//}
void gn6(){
  int a,b,n,m;
  system("cls");
  lb();
  while(1){
    printf("请输入初始景点 : ");
    scanf("%d",&n);
    if(n>=1&&n<=place[0].maxcount){
      system("cls");
      for(a=0;a<place[0].maxcount;a++){
        if(a!=n-1){
          DJS(n-1,a);
        }
      }
      printf("\n\n按回车键返回至主界面\n\n");
      getchar();getchar();
      break;
    }
    else{
      printf("输入错误,无该景点,请重新输入!!!");
      scanf("%d",&n); 
    }
      
  }
//  qing();
}
void lhj(int x){//游览路线
  int n=place[0].maxcount;
  int i,j,k=x,min=0,coune=0,mincount;
  printf("路线应为:");
  printf("%s--->",place[x].name);
  place[x].digitor=1;
  for(i=1;i<n;i++){
    min=max;
    k=x;
    int mnb=-1;
    for(j=0;j<n;j++){
      if(j!=k){
        if(min>map2[k][j].distance&&place[j].digitor==0){
          mnb=j;
          mincount=map2[k][j].distance;
        }
      }
    }
    coune=coune+mincount;
    if(mnb!=-1&&i<n-2){
      printf("%s--->",place[mnb].name);
      place[mnb].digitor=1;
      k=mnb;
    }else if(mnb!=-1&&i==n-2){
      printf("%s.",place[mnb].name);
      place[mnb].digitor=1;
      k=mnb;
    }
  }
  printf("\n总路程为 %d m。\n",coune);
  
}
void xiao1(char* pFileName){//在次建图
  FILE *err;
  FILE *pFile;
  err = fopen(pFileName, "w");//读取名为pFileName的文本文件 
  
  if (err == 0)//判断文件是否打开是否成功 
    printf("文件打开失败\n");
  else
    printf("文件打开成功\n");
    int i=0;
    scanf("%d",&place1[i].number); 
  while(place1[i].number!=-1){
    getchar();
    scanf("%s",place1[i].name);
    getchar();
    scanf("%s",place1[i].introduce);
    fprintf(err,"%d\n%s\n%s\n",place1[i].number,place1[i].name,place1[i].introduce);
    place1[i].digitor=0;
    i++;
    scanf("%d",&place1[i].number);
  }
  place1[0].maxcount=i;
  fclose(err);
  
}
void xiao2(int x){//删除节点
  int n=place1[0].maxcount;
  for(int i=0;i<n;i++){
    if(i>x){
      place1[i-1].number=place1[i].number-1;
      strcpy(place1[i-1].name,place1[i].name);
      strcpy(place1[i-1].introduce,place1[i].introduce);
      
    }
    if(i==n-1){place1[i].number=-1;}
  }
  for(int i=0;i<n;i++){
    if(i>x){
      for(int j=0;j<n;j++){
        map2[i-1][j].distance=map2[i][j].distance;
      }
    }   
  }
  for(int i=0;i<n;i++){
    if(i>x)
    for(int j=0;j<n-1;j++){
      map2[j][i-1].distance=map2[j][i].distance;
    }
  }
  printf("删成功。"); 
  lujing1();
  lujing2();
}
void xiao3(int x,int y){//删除边
//  FILE* err;
//  err=fopen(pFileName,"r");
//  int n=place[0].maxcount;
//  for(int i=0;i<n;i++){
//    for(int j=0;j<n;j++){
//      fscanf(err,"%d",&map2[i][j].distance);
//      fgetchar();
//    }
//  }
//  fclose(err);
  for(int i=0;i<place1[0].maxcount;i++){
    for(int j=0;j<place1[0].maxcount;j++){
      if((i==x&&j==y)||(i==y&&j==x)){
        map2[i][j].distance=max;
      }
      map2[i][j].bia=0;
    }
  }
  printf("删成功。");
  lujing2();
//  FILE* dsw;
//  dsw=fopen(pFileName,"a");
//  for(int i=0;i<n;i++){
//    for(int j=0;j<n;j++){
//      fprintf(dsw,"%d",map2[i][j].distance);
//      char fg;
//      fputchar(fg);
//    }
//  }
//  fclose(dsw);
}
void xiao4(){//增加节点 
  int n=place1[0].maxcount;
  place1[n].number=n+1;
  printf("\n请输入名字:");
  scanf("%s",place1[n].name);
  printf("\n请输入介绍:"); 
  scanf("%s",place[n].introduce);
  place1[0].maxcount++;
  n=place1[0].maxcount;
  for(int j=0;j<n;j++){
    scanf("%d",map2[n-1][j].distance);
    map2[j][n-1].distance=map2[n-1][j].distance;
  }
  lujing1();
  lujing2();
}
void xiao5(int x,int y,int w){//增加边
//  FILE* err;
//  err=fopen(pFileName,"a");
  for(int i=0;i<place[0].maxcount;i++){
    for(int j=0;j<place[0].maxcount;j++){
      if(i==x&&j==y||i==y&&j==x){
        map2[i][j].distance=w;
      }
    }
  }
  lujing2();
//  fclose(err);
}
void xiao6(){//更新信息
  printf("1:改地址名 2:改距离\n");
  printf("\n你想要干:");
  int x;
  int number;
  scanf("%d",&x);
  if(x==1){
    printf("\n请输入序号:");
    scanf("%d",&number);
//    FILE* err;
//    err=fopen(pFileName,"r");
//    int n=place[0].maxcount;
//    for(int i=0;i<n;i++){
//      fscanf(err,"%d\n%s\n%s\n",&place[i].number,place[i].name,place[i].introduce);
//    }
//    fclose(err);
    int n=place1[0].maxcount;
    for(int i=0;i<n;i++){
      if(i==number){
        printf("\n请更改名字:");
        scanf("%s",place1[i].name);
        getchar();
        printf("\n请填入介绍:");
        scanf("%s",place1[i].introduce);
      }
    }
    lujing1();
//    FILE* dsw;
//    dsw=fopen(pFileName,"w");
//    for(int i=0;i<n;i++){
//      for(int j=0;j<n;j++){
//        fprintf(dsw,"%d",map2[i][j].distance);
//        char fg;
//        fputchar(fg);
//      }
//    }
//    fclose(dsw); 
  }else if(x==2){
    printf("\n请输入起点:");
    int head,end;
    scanf("%d",&head);
    printf("\n请输入终点:");
    scanf("%d",&end);
    printf("\n请输入变后的距离:");
    int distance,n=place1[0].maxcount;
    scanf("%d",&distance);
    for(int i=0;i<n;i++){
      for(int j=0;j<n;j++){
        if(i==head&&j==end||i==end&&j==head){
          map2[i][j].distance=distance;
        }
      }
    }
    lujing2();
  }
}
void xiao7(){//打印邻接矩阵
  for(int i=0;i<place1[0].maxcount;i++){
    for(int j=0;j<place1[0].maxcount;j++){
      printf("%d ",map2[i][j].distance);
    }
    printf("\n");
  }
}
int main(){ 
  int i,j,k,l,n,m,x;
  inset("tu.txt");
  inset1("最短路径FloydALGraph.txt");
  system("cls");
  printf("----------欢迎使用校园导航小助手-----------\n");
  printf("          欢迎来到学校地图!    \n\n\n");
  printf("                菜 单 选 择\n");
  printf("     1、学校景点介绍              2、查看游览路线\n");
  printf("     3、查询景点间最短路径        4、景点信息查询\n");
  printf("     5、更改图信息                6、查询景点间可行路径\n");
  printf("     7、打印邻接矩阵              8、退出\n");
  printf("--------------------------------------------\n");
  printf("请输入你的选择:");
  scanf("%d",&x);
  while((int)x<1||(int)x>=9){
    printf("未识别出选项,抱歉请再次输入\n");
    scanf("%d",&x); 
  }
  while(x>=1&&x<9){
  
    if(x==1){
      for(i=0;i<place[0].maxcount;i++){
        printf("%d %s %s\n",place[i].number,place[i].name,place[i].introduce);
      }
    }else if(x==2){
      floyd(place[0].maxcount);
      printf("请输入一个起始景点的编号:");
      scanf("%d",&m);
      lhj(m);
    }else if(x==3){
      lb();
      printf("请输入一个起始景点的编号:");
      scanf("%d",&k);
      printf("\n请输入一个终点景点的编号:");
      scanf("%d",&l);
      DJS(k-1,l-1);
    }else if(x==4){
      printf("请输入你要查询的景点:");
      scanf("%d",&m);
      printf("%d %s %s\n",place[m].number,place[m].name,place[m].introduce); 
    }else if(x==5){
      printf("请问是要\n");
      printf("(1)在次建图       (2)删除节点      (3)删除边\n");
      printf("(4)增加节点       (5)增加边        (6)更新信息\n");
      printf("(7)打印邻接矩阵   (8)返回?\n");
      int y;
      scanf("%d",&y);
      while(y>=1&&y<9){
        if(y==1){
//          xiao1();
          xiao1("tu1.txt");
        }else if(y==2){
          printf("删除的点:");
          scanf("%d",&i);
          while(i<0||i>place1[0].maxcount){
            printf("抱歉你所输入的点不存在,请重新输入");
            scanf("%d",&i); 
          }
          xiao2(i);
//          xiao2("D:\\tu1.txt",i);
        }else if(y==3){
          printf("删除的边:");
          scanf("%d %d",&i,&j);
          
          xiao3(i,j);
//          xiao3("最短路径FloydALGraph.txt",i,j);
        }else if(y==4){
          printf("增加的点:");
//          xiao4("tu1.txt",i);
          xiao4();
        }else if(y==5){
          printf("增加的边:");
          int w;
          scanf("%d %d %d",&i,&j,&w);
          xiao5(i,j,w);
//          xiao5("最短路径FloydALGraph.txt",i,j,w);
        }else if(y==6){
//          xiao6("tu1.txt");
          xiao6();
        }else if(y==7){
          xiao7();
        }else if(y==8){break;
        }
        printf("(1)在次建图       (2)删除节点      (3)删除边\n");
        printf("(4)增加节点       (5)增加边        (6)更新信息\n");
        printf("(7)打印邻接矩阵   (8)返回?\n");
        printf("你接下来要干嘛?"); 
        scanf("%d",&y);
        
      }
      
    }else if(x==6){
      gn6();
    }else if(x==7){
      for(i=0;i<place[0].maxcount;i++){
        for(j=0;j<place[0].maxcount;j++){
          if(map1[i][j].distance<max)printf("[%d][%d]%d ",i,j,map1[i][j].distance);
          else printf("[%d][%d]无路 ",i,j);
        }
        printf("\n");
      }
    }else if(x==8){
//    system("cls");
    printf("\t\t\t\t\t    ****************************************************\n");
    printf("\t\t\t\t\t    *                     感谢使用                     *\n");
    printf("\t\t\t\t\t    *                                                  *\n");
    printf("\t\t\t\t\t    *                                                  *\n");
    printf("\t\t\t\t\t    *                                                  *\n");
    printf("\t\t\t\t\t    *                                                  *\n");
    printf("\t\t\t\t\t    *                                                  *\n");
    printf("\t\t\t\t\t    *                                                  *\n");
    printf("\t\t\t\t\t    *                                                  *\n");
    printf("\t\t\t\t\t    ****************************************************\n");
    printf("\n\n\n\n\n");
  break;
    }
    inset("tu1.txt");
    inset1("最短路径FloydALGraph.txt");
    printf("是否继续?1:0\n");
    int sa;
    printf("你的选择:");
    scanf("%d",&sa);
    if(sa==1)system("cls");
    if(sa==1){
      printf("----------欢迎使用校园导航小助手-----------\n");
      printf("          欢迎来到学校地图!    \n\n\n");
      printf("                菜 单 选 择\n");
      printf("     1、学校景点介绍              2、查看游览路线\n");
      printf("     3、查询景点间最短路径        4、景点信息查询\n");
      printf("     5、更改图信息                6、查询景点间可行路径\n");
      printf("     7、打印邻接矩阵              8、退出\n");
      printf("--------------------------------------------\n");
      printf("请输入你的选择:");
      scanf("%d",&x);
    }else{
      x=8;
    }
      
  }
  return 0;
}


相关文章
|
7月前
|
数据采集 运维 安全
信管第四章---信息系统管理(听课版)
【1月更文挑战第4天】乘风破浪会有时,直挂云帆济沧海
296 0
|
数据库 数据安全/隐私保护
【课程设计】招聘系统的设计与实现
【课程设计】招聘系统的设计与实现
106 0
|
前端开发 Java 测试技术
基于SSM的中学学生学籍管理系统设计与实现
基于SSM的中学学生学籍管理系统设计与实现
243 0
程序设计基础课程设计 —— 疫苗预约管理系统附录
程序设计基础课程设计 —— 疫苗预约管理系统附录
|
7月前
|
关系型数据库 程序员 BI
程序员中医诊所管理软件开发模块分析
将系统划分为患者管理模块、医生管理模块、药材药方管理模块、财务管理模块、报表统计模块和系统设置模块。
67 2
|
4月前
|
存储 算法 数据处理
【C/C++】C/C++ 校园失物招领系统设计与实现(源码+报告)【独一无二】
【C/C++】C/C++ 校园失物招领系统设计与实现(源码+报告)【独一无二】
|
6月前
|
前端开发 JavaScript Java
计算机Java项目|大学生租房平台的设计与实现
计算机Java项目|大学生租房平台的设计与实现
|
7月前
|
存储 编解码 测试技术
图书馆信息管理系统(项目需求和计划、项目设计)(下)
图书馆信息管理系统(项目需求和计划、项目设计)(下)
|
7月前
|
安全 测试技术 数据库
图书馆信息管理系统(项目需求和计划、项目设计)(上)
图书馆信息管理系统(项目需求和计划、项目设计)(上)
|
7月前
|
算法
程序设计基础课程设计 —— 疫苗预约管理系统
程序设计基础课程设计 —— 疫苗预约管理系统