algo4-01~04.cpp 串 主程序

  1.  // algo4-1.cpp 实现算法4.6、4.7、4.8的程序
  2.  #include"c1.h"
  3.  #include"c4-1.h"
  4.  #include"bo4-1.cpp"
  5.  void get_next(SString T,int next[])
  6.  { // 求模式串T的next函数值并存入数组next。算法4.7
  7.    int i=1,j=0;
  8.    next[1]=0;
  9.    while(i<T[0])
  10.      if(j==0||T[i]==T[j])
  11.      {
  12.        ++i;
  13.        ++j;
  14.        next[i]=j;
  15.      }
  16.      else
  17.        j=next[j];
  18.  }
  19.  void get_nextval(SString T,int nextval[])
  20.  { // 求模式串T的next函数修正值并存入数组nextval。算法4.8
  21.    int i=1,j=0;
  22.    nextval[1]=0;
  23.    while(i<T[0])
  24.      if(j==0||T[i]==T[j])
  25.      {
  26.        ++i;
  27.        ++j;
  28.        if(T[i]!=T[j])
  29.          nextval[i]=j;
  30.        else
  31.          nextval[i]=nextval[j];
  32.      }
  33.      else
  34.        j=nextval[j];
  35.  }
  36.  int Index_KMP(SString S,SString T,int pos,int next[])
  37.  { // 利用模式串T的next函数求T在主串S中第pos个字符之后的位置的KMP算法。
  38.    // 其中,T非空,1≤pos≤StrLength(S)。算法4.6
  39.    int i=pos,j=1;
  40.    while(i<=S[0]&&j<=T[0])
  41.      if(j==0||S[i]==T[j]) // 继续比较后继字符
  42.      {
  43.        ++i;
  44.        ++j;
  45.      }
  46.      else // 模式串向右移动
  47.        j=next[j];
  48.    if(j>T[0]) // 匹配成功
  49.      return i-T[0];
  50.    else
  51.      return 0;
  52.  }
  53.  void main()
  54.  {
  55.    int i,*p;
  56.    SString s1,s2; // 以教科书算法4.8之上的数据为例
  57.    StrAssign(s1,"aaabaaaab");
  58.    printf("主串为: ");
  59.    StrPrint(s1);
  60.    StrAssign(s2,"aaaab");
  61.    printf("子串为: ");
  62.    StrPrint(s2);
  63.    p=(int*)malloc((StrLength(s2)+1)*sizeof(int)); // 生成s2的next数组空间
  64.    get_next(s2,p); // 利用算法4.7,求得next数组,存于p中
  65.    printf("子串的next数组为: ");
  66.    for(i=1;i<=StrLength(s2);i++)
  67.      printf("%d ",*(p+i));
  68.    printf("/n");
  69.    i=Index_KMP(s1,s2,1,p); // 利用算法4.6求得串s2在s1中首次匹配的位置i
  70.    if(i)
  71.      printf("主串和子串在第%d个字符处首次匹配/n",i);
  72.    else
  73.      printf("主串和子串匹配不成功/n");
  74.    get_nextval(s2,p); // 利用算法4.8,求得next数组,存于p中
  75.    printf("子串的nextval数组为: ");
  76.    for(i=1;i<=StrLength(s2);i++)
  77.      printf("%d ",*(p+i));
  78.    printf("/n");
  79.    printf("主串和子串在第%d个字符处首次匹配/n",Index_KMP(s1,s2,1,p));
  80.  }
 
  1.  // algo4-2.cpp 文本行编辑
  2.  #include"c1.h"
  3.  #include"c4-2.h" // 采用串的堆分配存储结构
  4.  #include"bo4-2.cpp" // 串的堆分配基本操作
  5.  #define MAX_LEN 25 // 文件最大行数
  6.  #define LINE_LEN 75 // 每行字符数最大值+1
  7.  #define NAME_LEN 20 // 文件名最大长度(包括盘符、路径)+1
  8.  // 全局变量
  9.  HString T[MAX_LEN];
  10.  char str[LINE_LEN],filename[NAME_LEN]="";
  11.  FILE *fp;
  12.  int n=0; // 文本行数
  13.  void Open()
  14.  { // 打开文件(新或旧)
  15.    if(filename[0]) // 文件已打开
  16.      printf("已存在打开的文件/n");
  17.    else
  18.    {
  19.      printf("请输入文件名(可包括盘符、路径,不超过%d个字符): ",NAME_LEN-1);
  20.      scanf("%s",filename);
  21.      fp=fopen(filename,"r"); // 以读的方式打开文件
  22.      if(fp) // 已存在此文件
  23.      {
  24.        while(fgets(str,LINE_LEN,fp)) // 由文件读入1行字符成功 
  25.        {
  26.          str[strlen(str)-1]=0; // 将换行符10强制改为串结束符0
  27.          if(n>=MAX_LEN)
  28.          {
  29.            printf("文件太大/n");
  30.            return;
  31.          }
  32.          StrAssign(T[n],str);
  33.          n++;
  34.        }
  35.        fclose(fp); // 关闭文件
  36.      }
  37.      else
  38.        printf("新文件/n");
  39.    }
  40.  }
  41.  void List()
  42.  { // 显示文本内容
  43.    int i;
  44.    for(i=0;i<n;i++)
  45.    {
  46.      printf("%d: ",i+1);
  47.      StrPrint(T[i]);
  48.    }
  49.  }
  50.  void Insert()
  51.  { // 插入行
  52.    int i,l,m;
  53.    printf("在第l行前插m行,请输入l m: ");
  54.    scanf("%d%d%*c",&l,&m);
  55.    if(n+m>MAX_LEN)
  56.    {
  57.      printf("插入行太多/n");
  58.      return;
  59.    }
  60.    if(n>=l-1&&l>0)
  61.    {
  62.      for(i=n-1;i>=l-1;i--)
  63.        T[i+m]=T[i];
  64.      n+=m;
  65.      printf("请顺序输入待插入内容:/n");
  66.      for(i=l-1;i<l-1+m;i++)
  67.      {
  68.        gets(str);
  69.        InitString(T[i]);
  70.        StrAssign(T[i],str);
  71.      }
  72.    }
  73.    else
  74.      printf("行超出范围/n");
  75.  }
  76.  void Delete()
  77.  { // 删除行
  78.    int i,l,m;
  79.    printf("从第l行起删除m行,请输入l m: ");
  80.    scanf("%d%d",&l,&m);
  81.    if(n>=l+m-1&&l>0)
  82.    {
  83.      for(i=l-1+m;i<n;i++)
  84.      {
  85.        free(T[i-m].ch);  
  86.        T[i-m]=T[i];
  87.      }
  88.      for(i=n-m;i<n;i++)
  89.        InitString(T[i]);
  90.      n-=m;
  91.    }
  92.    else
  93.      printf("行超出范围/n");
  94.  }
  95.  void Copy()
  96.  { // 拷贝行
  97.    int i,l,m,k;
  98.    printf("把第l行开始的m行插在原k行之前,请输入l m k: ");
  99.    scanf("%d%d%d",&l,&m,&k);
  100.    if(n+m>MAX_LEN)
  101.    {
  102.      printf("拷贝行太多/n");
  103.      return;
  104.    }
  105.    if(n>=k-1&&n>=l-1+m&&(k>=l+m||k<=l))
  106.    {
  107.      for(i=n-1;i>=k-1;i--)
  108.        T[i+m]=T[i];
  109.      n+=m;
  110.      if(k<=l)
  111.        l+=m;
  112.      for(i=l-1;i<l-1+m;i++)
  113.      {
  114.        InitString(T[i+k-l]);
  115.        StrCopy(T[i+k-l],T[i]);
  116.      }
  117.    }
  118.    else
  119.      printf("行超出范围/n");
  120.  }
  121.  void Modify()
  122.  { // 修改行
  123.    int i;
  124.    printf("请输入待修改的行号: ");
  125.    scanf("%d%*c",&i);
  126.    if(i>0&&i<=n) // 行号合法
  127.    {
  128.      printf("%d: ",i);
  129.      StrPrint(T[i-1]);
  130.      printf("请输入新内容: ");
  131.      gets(str);
  132.      StrAssign(T[i-1],str);
  133.    }
  134.    else
  135.      printf("行号超出范围/n");
  136.  }
  137.  void Search()
  138.  { // 查找字符串
  139.    int i,k,f=1; // f为继续查找标志
  140.    char b[2];
  141.    HString s;
  142.    printf("请输入待查找的字符串: ");
  143.    scanf("%s%*c",str);
  144.    InitString(s);
  145.    StrAssign(s,str);
  146.    for(i=0;i<n&&f;i++) // 逐行查找
  147.    {
  148.      k=1; // 由每行第1个字符起查找
  149.      while(k)
  150.      {
  151.        k=Index(T[i],s,k); // 由本行的第k个字符开始查找
  152.        if(k) // 找到
  153.        {
  154.          printf("第%d行: ",i+1);
  155.          StrPrint(T[i]);
  156.          printf("第%d个字符处找到。继续查找吗(Y/N)? ",k);
  157.          gets(b);
  158.          if(b[0]!='Y'&&b[0]!='y'// 中断查找
  159.          {
  160.            f=0;
  161.            break;
  162.          }
  163.          else
  164.            k++;
  165.        }
  166.      }
  167.    }
  168.    if(f)
  169.      printf("没找到/n");
  170.  }
  171.  void Replace()
  172.  { // 替换字符串
  173.    int i,k,f=1; // f为继续替换标志
  174.    char b[2];
  175.    HString s,t;
  176.    printf("请输入待替换的字符串: ");
  177.    scanf("%s%*c",str);
  178.    InitString(s);
  179.    StrAssign(s,str);
  180.    printf("替换为: ");
  181.    scanf("%s%*c",str);
  182.    InitString(t);
  183.    StrAssign(t,str);
  184.    for(i=0;i<n&&f;i++) // 逐行查找、替换
  185.    {
  186.      k=1; // 由每行第1个字符起查找
  187.      while(k)
  188.      {
  189.        k=Index(T[i],s,k); // 由本行的第k个字符开始查找
  190.        if(k) // 找到
  191.        {
  192.          printf("第%d行: ",i+1);
  193.          StrPrint(T[i]);
  194.          printf("第%d个字符处找到。是否替换(Y/N)? ",k);
  195.          gets(b);
  196.          if(b[0]=='Y'||b[0]=='y')
  197.          {
  198.            StrDelete(T[i],k,StrLength(s));
  199.            StrInsert(T[i],k,t);
  200.          }
  201.          printf("继续替换吗(Y/N)?");
  202.          gets(b);
  203.          if(b[0]!='Y'&&b[0]!='y'// 中断查找、替换
  204.          {
  205.            f=0;
  206.            break;
  207.          }
  208.          else
  209.            k+=StrLength(t);
  210.        }
  211.      }
  212.    }
  213.    if(f)
  214.      printf("没找到/n");
  215.  }
  216.  void Save()
  217.  { // 存盘
  218.    int i,j;
  219.    fp=fopen(filename,"w"); // 以写的方式重新打开文件
  220.    if(fp) // 打开文件成功
  221.    {
  222.      for(i=0;i<n;i++)
  223.      { // 依次将每行存入文件
  224.        for(j=0;j<T[i].length;j++) // 依次存入每个字符
  225.          fputc(T[i].ch[j],fp);
  226.        fputc(10,fp); // 存入换行符
  227.        ClearString(T[i]); // 释放串空间
  228.      }
  229.      fclose(fp); // 关闭文件
  230.    }
  231.    else
  232.      printf("存盘失败/n");
  233.  }
  234.  void main()
  235.  {
  236.    Status s=TRUE;
  237.    int i,k;
  238.    for(i=0;i<MAX_LEN;i++) // 初始化串
  239.      InitString(T[i]);
  240.    while(s)
  241.    {
  242.      printf("请选择: 1.打开文件(新或旧)  2.显示文件内容/n");
  243.      printf("        3.插入行  4.删除行  5.拷贝行  6.修改行/n");
  244.      printf("        7.查找字符串        8.替换字符串/n");
  245.      printf("        9.存盘退出          0.放弃编辑/n");
  246.      scanf("%d",&k);
  247.      switch(k)
  248.      {
  249.        case 1: Open();
  250.                break;
  251.        case 2: List();
  252.                break;
  253.        case 3: Insert();
  254.                break;
  255.        case 4: Delete();
  256.                break;
  257.        case 5: Copy();
  258.                break;
  259.        case 6: Modify();
  260.                break;
    1.  // algo4-3.cpp 根据书目文件bookinfo.txt生成书名关键词索引文件bookidx.txt,
    2.  // 为运行algo4-4.cpp做准备,算法4.9~4.14
    3.  #include"c1.h"
    4.  typedef int ElemType;
    5.  #include"c2-5.h"
    6.  #include"bo2-6.cpp"
    7.  #include"c4-2.h"
    8.  #include"bo4-2.cpp"
    9.  #define MaxKeyNum 25 // 索引表的最大容量(关键词的最大数目)
    10.  #define MaxLineLen 52 // 书目串(书目文件的1行)buf的最大长度
    11.  #define MaxNoIdx 10 // 非索引词(也是一个书目中关键词)的最大数目
    12.  struct WordListType // 一个书目的词表(顺序表)和非索引词表(有序表)共用类型
    13.  {
    14.    char *item[MaxNoIdx]; // 词表(字符串)指针数组
    15.    int last; // 词的数量
    16.  };
    17.  struct IdxTermType // 索引项类型
    18.  {
    19.    HString key; // 关键词(堆分配类型,c4-2.h)
    20.    LinkList bnolist; // 存放书号索引的链表(c2-5.h)
    21.  };
    22.  struct IdxListType // 索引表类型(有序表)
    23.  {
    24.    IdxTermType item[MaxKeyNum+1]; // 索引项数组类型
    25.    int last; // 关键词的个数
    26.  };
    27.  // 全局变量
    28.  char buf[MaxLineLen+1]; // 当前书目串(包括'/0')
    29.  WordListType wdlist,noidx; // 暂存一种书的词表,非索引词表
    30.  void InitIdxList(IdxListType &idxlist)
    31.  { // 初始化操作,置索引表idxlist为空表,且在idxlist.item[0]设一空串
    32.    idxlist.last=0;
    33.    InitString(idxlist.item[0].key); // 初始化[0]单元,函数在bo4-2.cpp中
    34.    InitList(idxlist.item[0].bnolist); // 初始化[0]单元,函数在bo2-6.cpp中
    35.  }
    36.  void ExtractKeyWord(int &BookNo)
    37.  { // 从buf中提取书名关键词到词表wdlist,书号存入BookNo
    38.    int i,l,f=1; // f是字符串buf结束标志 0:结束 1:未结束
    39.    char *s1,*s2;
    40.    for(i=1;i<=wdlist.last;i++)
    41.    { // 释放上一个书目在词表wdlist的存储空间
    42.      free(wdlist.item[i]);
    43.      wdlist.item[i]=NULL;
    44.    }
    45.    wdlist.last=0; // 初始化词表wdlist的词数量
    46.    BookNo=atoi(buf); // 将前几位数字转化为整数,赋给书号BookNo
    47.    s1=&buf[4]; // s1指向书名的首字符
    48.    while(f)
    49.    { // 提取书名关键词到词表wdlist
    50.      s2=strchr(s1,' '); // s2指向s1后的第一个空格,如没有,返回NULL
    51.      if(!s2) // 到串尾(没空格)
    52.      {
    53.        s2=strchr(s1,'/12'); // s2指向buf的最后一个字符(回车符10)
    54.        f=0;
    55.      }
    56.      l=s2-s1; // 单词长度
    57.      if(s1[0]>='A'&&s1[0]<='Z'// 单词首字母为大写
    58.      { // 写入词表
    59.        wdlist.item[wdlist.last]=(char *)malloc((l+1)*sizeof(char)); // 生成串空间(包括'/0')
    60.        for(i=0;i<l;i++)
    61.          wdlist.item[wdlist.last][i]=s1[i]; // 写入词表
    62.        wdlist.item[wdlist.last][l]=0; // 串结束符
    63.        for(i=0;i<noidx.last&&(l=strcmp(wdlist.item[wdlist.last],noidx.item[i]))>0;i++);
    64.        // 查找是否为非索引词
    65.        if(!l) // 是非索引词
    66.        {
    67.          free(wdlist.item[wdlist.last]); // 从词表中删除该词
    68.          wdlist.item[wdlist.last]=NULL;
    69.        }
    70.        else
    71.      wdlist.last++; // 词表长度+1
    72.      }
    73.      s1=s2+1; // s1移动到下一个单词的首字符处
    74.    };
    75.  }
    76.  void GetWord(int i,HString &wd)
    77.  { // 用wd返回词表wdlist中第i个关键词,算法4.11
    78.    StrAssign(wd,wdlist.item[i]); // 生成关键字字符串 bo4-2.cpp
    79.  }
    80.  int Locate(IdxListType &idxlist,HString wd,Status &b)
    81.  { // 在索引表idxlist中查询是否存在与wd相等的关键词。若存在,则返回其
    82.    // 在索引表中的位置,且b取值TRUE;否则返回插入位置,且b取值FALSE,算法4.12
    83.    int i,m;
    84.    for(i=idxlist.last;(m=StrCompare(idxlist.item[i].key,wd))>0;--i); // bo4-2.cpp
    85.    if(m==0) // 找到
    86.    {
    87.      b=TRUE;
    88.      return i;
    89.    }
    90.    else
    91.    {
    92.      b=FALSE;
    93.      return i+1;
    94.    }
    95.  }
    96.  void InsertNewKey(IdxListType &idxlist,int i,HString wd)
    97.  { // 在索引表idxlist的第i项上插入新关键词wd,并初始化书号索引的链表为空表,算法4.13
    98.    int j;
    99.    for(j=idxlist.last;j>=i;--j) // 后移索引项
    100.      idxlist.item[j+1]=idxlist.item[j];
    101.    InitString(idxlist.item[i].key); // bo4-2.cpp
    102.    StrCopy(idxlist.item[i].key,wd); // 串拷贝插入新的索引项 bo4-2.cpp
    103.    InitList(idxlist.item[i].bnolist); // 初始化书号索引表为空表 bo2-6.cpp
    104.    idxlist.last++;
    105.  }
    106.  void InsertBook(IdxListType &idxlist,int i,int bno)
    107.  { // 在索引表idxlist的第i项中插入书号为bno的索引,算法4.14
    108.    Link p;
    109.    MakeNode(p,bno); // 分配结点 bo2-6.cpp
    110.    p->next=NULL;
    111.    Append(idxlist.item[i].bnolist,p); // 插入新的书号索引 bo2-6.cpp
    112.  }
    113.  void InsIdxList(IdxListType &idxlist,int bno)
    114.  { // 将书号为bno的关键词插入索引表,算法4.10
    115.    int i,j;
    116.    Status b;
    117.    HString wd;
    118.    InitString(wd); // bo4-2.cpp
    119.    for(i=0;i<wdlist.last;i++)
    120.    {
    121.      GetWord(i,wd);
    122.      j=Locate(idxlist,wd,b); // 关键词的位置或待插入的位置(当索引表中不存在该词)
    123.      if(!b) // 索引表中不存在关键词wd
    124.        InsertNewKey(idxlist,j,wd); // 在索引表中插入新的索引项
    125.      InsertBook(idxlist,j,bno); // 插入书号索引
    126.    }
    127.  }
    128.  void PutText(FILE *f,IdxListType idxlist)
    129.  { // 将生成的索引表idxlist输出到文件f
    130.    int i,j;
    131.    Link p;
    132.    fprintf(f,"%d/n",idxlist.last);
    133.    for(i=1;i<=idxlist.last;i++)
    134.    {
    135.      for(j=0;j<idxlist.item[i].key.length;j++)
    136.        fprintf(f,"%c",idxlist.item[i].key.ch[j]); // HString类型串尾没有/0,只能逐个字符输出
    137.      fprintf(f,"/n%d/n",idxlist.item[i].bnolist.len);
    138.      p=idxlist.item[i].bnolist.head;
    139.      for(j=1;j<=idxlist.item[i].bnolist.len;j++)
    140.      {
    141.        p=p->next;
    142.        fprintf(f,"%d ",p->data);
    143.      }
    144.      fprintf(f,"/n");
    145.    }
    146.  }
    147.  void main()
    148.  { // 算法4.9
    149.    FILE *f; // 任何时间最多打开一个文件
    150.    IdxListType idxlist; // 索引表
    151.    int BookNo; // 书号变量
    152.    int k;
    153.    if(!(f=fopen("NoIdx.txt","r"))) // 打开非索引词文件
    154.      exit(OVERFLOW);
    155.    fscanf(f,"%d",&noidx.last); // 读取非索引词个数
    156.    for(k=0;k<noidx.last;k++) // 把非索引词文件的内容依次拷到noidx中
    157.    {
    158.      fscanf(f,"%s",buf);
    159.      noidx.item[k]=(char*)malloc((strlen(buf)+1)*sizeof(char));
    160.      strcpy(noidx.item[k],buf);
    161.    }
    162.    fclose(f); // 关闭非索引词文件
    163.    if(!(f=fopen("BookInfo.txt","r"))) // 打开书目文件
    164.      exit(FALSE);
    165.    InitIdxList(idxlist); // 设索引表idxlist为空,并初始化[0]单元
    166.    while(fgets(buf,MaxLineLen,f)) // 由书目文件读取1行信息到buf成功
    167.    {
    168.      ExtractKeyWord(BookNo);//将buf中的书号存入BookNo,关键词提取到词表(当前书目的关键词表)中
    169.      InsIdxList(idxlist,BookNo); // 将书号为BookNo的关键词及书号插入索引表idxlist中
    170.    }
    171.    fclose(f); // 关闭书目文件
    172.    if(!(f=fopen("BookIdx.txt","w"))) // 打开书名关键词索引文件
    173.      exit(INFEASIBLE);
    174.    PutText(f,idxlist); // 将生成的索引表idxlist输出到书名关键词索引文件
    175.    fclose(f); // 关闭书名关键词索引文件
    176.  }
  261.                break;
  262.        case 8: Replace();
  263.                break;
  264.        case 9: Save();
  265.        case 0: s=FALSE;
  266.      }
  267.    }
  268.  }
  1.  // algo4-4.cpp 根据algo4-3.cpp产生的文件,索引查询图书
  2.  #include"c1.h"
  3.  typedef int ElemType;
  4.  #include"c2-5.h"
  5.  #include"bo2-6.cpp"
  6.  #include"c4-2.h"
  7.  #include"bo4-2.cpp"
  8.  #define MaxBookNum 10 // 假设只对10个书名建索引表
  9.  #define MaxKeyNum 25 // 索引表的最大容量(关键词的最大数目)
  10.  #define MaxLineLen 46 // 书名的最大长度
  11.  struct IdxTermType // 索引项类型
  12.  {
  13.    HString key; // 关键词(堆分配类型,c4-2.h)
  14.    LinkList bnolist; // 存放书号索引的链表(c2-5.h)
  15.  };
  16.  struct IdxListType // 索引表类型(有序表)
  17.  {
  18.    IdxTermType item[MaxKeyNum+1]; // 索引项数组类型
  19.    int last; // 关键词的个数
  20.  };
  21.  struct BookTermType // 书目项类型
  22.  {
  23.    char bookname[MaxLineLen+1]; // 书名串(包括'/0')
  24.    int bookno; // 书号
  25.  };
  26.  struct BookListType // 书目表类型(有序表)
  27.  {
  28.    BookTermType item[MaxBookNum]; // 书目项数组类型
  29.    int last; // 书目的数量
  30.  };
  31.  void main()
  32.  {
  33.    FILE *f; // 任何时间最多打开一个文件
  34.    IdxListType idxlist; // 索引表
  35.    BookListType booklist; // 书目表
  36.    char buf[MaxLineLen+5]; // 当前书目串(包括书号和'/0')
  37.    HString ch; // 索引字符串
  38.    int BookNo; // 书号
  39.    Link p; // 链表指针
  40.    int i,j,k,flag=1; // flag是继续查询的标志
  41.    InitString(ch); // 初始化HString类型的变量
  42.    if(!(f=fopen("BookIdx.txt","r"))) // 打开书名关键词索引表文件
  43.      exit(OVERFLOW);
  44.    fscanf(f,"%d",&idxlist.last); // 书名关键词个数
  45.    for(k=0;k<idxlist.last;k++) // 把关键词文件的内容拷到idxlist中
  46.    {
  47.      fscanf(f,"%s",buf);
  48.      i=0;
  49.      while(buf[i])
  50.        buf[i++]=tolower(buf[i]); // 字母转为小写
  51.      InitString(idxlist.item[k].key);
  52.      StrAssign(idxlist.item[k].key,buf);
  53.      InitList(idxlist.item[k].bnolist); // 初始化书号链表,bo2-6.cpp
  54.      fscanf(f,"%d",&i);
  55.      for(j=0;j<i;j++)
  56.      {
  57.        fscanf(f,"%d",&BookNo);
  58.        MakeNode(p,BookNo); // 产生新的书号结点,bo2-6.cpp
  59.        p->next=NULL; // 给书号结点的指针域赋值
  60.        Append(idxlist.item[k].bnolist,p); // 在表尾插入新的书号结点,bo2-6.cpp
  61.      }
  62.    }
  63.    fclose(f);
  64.    if(!(f=fopen("BookInfo.txt","r"))) // 打开书目文件
  65.      exit(FALSE);
  66.    i=0;
  67.    while(fgets(buf,MaxLineLen,f))
  68.    { // 把书目文件的内容拷到booklist中
  69.      booklist.item[i].bookno=atoi(buf); // 前几位数字为书号
  70.      strcpy(booklist.item[i++].bookname,&buf[4]); // 将buf由书名开始的字符串拷贝到booklist中
  71.    }
  72.    booklist.last=i;
  73.    while(flag)
  74.    {
  75.      printf("请输入书目的关键词(一个):");
  76.      scanf("%s",buf);
  77.      i=0;
  78.      while(buf[i])
  79.        buf[i++]=tolower(buf[i]); // 字母转为小写
  80.      StrAssign(ch,buf);
  81.      i=0;
  82.      do
  83.      {
  84.        k=StrCompare(ch,idxlist.item[i++].key); // bo4-2.cpp
  85.      }while(k&&i<=idxlist.last);
  86.      if(!k) // 索引表中有此关键词
  87.      {
  88.        p=idxlist.item[--i].bnolist.head->next; // p指向索引表中此关键词相应链表的首元结点
  89.        while(p)
  90.        {
  91.          j=0;
  92.          while(j<booklist.last&&p->data!=booklist.item[j].bookno) // 在booklist中找相应的书号
  93.            j++;
  94.          if(j<booklist.last)
  95.            printf("%3d %s",booklist.item[j].bookno,booklist.item[j].bookname);
  96.          p=p->next; // 继续向后找
  97.        }
  98.      }
  99.      else
  100.        printf("没找到/n");
  101.      printf("继续查找请输入1,退出查找请输入0:");
  102.      scanf("%d",&flag);
  103.    }
  104.  }

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言实例解析精粹(第二版) 光盘代码 本文件包括以下内容: ※ 1、文件说明 ※ 2、源码操作说明 ※ 3、光盘目录清单 ◎ 源码操作说明 源代码使用方法是(以实例1为例): 将该实例的源码,比如实例1的1.c文件(可以在001目录下找到), 拷贝到tc编译器目录下,运行tc.exe,打开编译器, 按【F3】键或者“File->Open”菜单命令,打开1.c文件, 按【Ctrl+F9】键,或者“Run->Run”菜单命令,编译运行该程序。 ◎ 光盘目录清单如下: 第一部分 基础篇 001 第一个C程序 002 运行多个源文件 003 求整数之积 004 比较实数大小 005 字符的输出 006 显示变量所占字节数 007 自增/自减运算 008 数列求和 009 乘法口诀表 010 猜数字游戏 011 模拟ATM(自动柜员机)界面 012 用一维数组统计学生成绩 013 用二维数组实现矩阵转置 014 求解二维数组的最大/最小元素 015 利用数组求前n个质数 016 编制万年历 017 对数组元素排序 018 任意进制数的转换 019 判断回文数 020 求数组前n元素之和 021 求解钢材切割的最佳订单 022 通过指针比较整数大小 023 指向数组的指针 024 寻找指定元素的指针 025 寻找相同元素的指针 026 阿拉伯数字转换为罗马数字 027 字符替换 028 从键盘读入实数 029 字符行排版 030 字符排列 031 判断字符是否回文 032 通讯录的输入输出 033 扑克牌的结构表示 034 用“结构”统计学生成绩 035 报数游戏 036 模拟社会关系 037 统计文件的字符数 038 同时显示两个文件的内容 039 简单的文本编辑器 040 文件的字数统计程序 041 学生成绩管理程序 第二部分 数据结构篇 042 插入排序 043 希尔排序 044 冒泡排序 045 快速排序 046 选择排序 047 堆排序 048 归并排序 049 基数排序 050 二叉搜索树操作 051 二项式系数递归 052 背包问题 053 顺序表插入和删除 054 链表操作(1) 055 链表操作(2) 056 单链表就地逆置 057 运动会分数统计 058 双链表 059 约瑟夫环 060 记录个人资料 061 二叉树遍利 062 浮点数转换为字符 063 汉诺塔问题 064 哈夫曼编码 065 图的深度优先遍利 066 图的广度优先遍利 067 求解最优交通路径 068 八皇后问题 069 骑士巡游 070 用栈设置密码 071 魔王语言翻译 072 火车车厢重排 073 队列实例 074 K阶斐波那契序列 第三部分 数值计算与趣味数学篇 075 绘制余弦曲线和直线的迭加 076 计算高次方数的尾数 077 打鱼还是晒网 078 怎样存钱以获取最大利息 079 阿姆斯特朗数 080 亲密数 081 自守数 082 具有abcd=(ab+cd)2性质的数 083 验证歌德巴赫猜想 084 素数幻方 085 百钱百鸡问题 086 爱因斯坦的数学题 087 三色球问题 088 马克思手稿中的数学题 089 配对新郎和新娘 090 约瑟夫问题 091 邮票组合 092 分糖果 093 波瓦松的分酒趣题 094 求π的近似值 095 奇数平方的有趣性质 096 角谷猜想 097 四方定理 098 卡布列克常数 099 尼科彻斯定理 100 扑克牌自动发牌 101 常胜将军 102 搬山游戏 103 兔子产子(菲波那契数列) 104 数字移动 105 多项式乘法 106 产生随机数 107 堆栈四则运算 108 递归整数四则运算 109 复平面作图 110 绘制彩色抛物线 111 绘制正态分布曲线 112 求解非线性方程 113 实矩阵乘法运算 114 求解线性方程 115 n阶方阵求逆 116 复矩阵乘法 117 求定积分 118 求满足特异条件的数列 119 超长正整数的加法 第四部分 图形篇 120 绘制直线 121 绘制圆 122 绘制圆弧 123 绘制椭圆 124 设置背景色和前景色 125 设置线条类型 126 设置填充类型和填充颜色 127 图形文本的输出 128 金刚石图案 129 飘带图案 130 圆环图案 131 肾形图案 132 心脏形图案 133 渔网图案 134 沙丘图案 135 设置图形方式下的文本类型 136 绘制正多边形 137 正六边形螺旋图案 138 正方形螺旋拼块图案 139 图形法绘制圆 140 递归法绘制三角形图案 141 图形法绘制椭圆 142 抛物样条曲线 143 Mandelbrot分形图案 144 绘制布朗运动曲线 145 艺术清屏 146 矩形区域的颜色填充 147 VGA256色模式编程 148 绘制蓝天图案 149 屏幕检测程序 150 运动的小车动画 151 动态显示位图 152 利用图形页实现动画 153 图形时钟 154 音乐动画 第五部分 系统篇 155 读取DOS系统中的国家信息 156 修改环境变量 157 显示系统文件表 158 显示目录内容 159 读取磁盘文件 160 删除目录树 161 定义文本模式 162 设计立体窗口 163 彩色弹出菜单 164 读取CMOS信息 165 获取BIOS设备列表 166 锁住硬盘 167 备份/恢复硬盘分区表 168 设计口令程序 169 程序自我保护 第六部分 常见试题解答篇 170 水果拼盘 171 小孩吃梨 172 删除字符中的特定字符 173 求解符号方程 174 计算标准差 175 求取符合特定要求的素数 176 统计符合特定条件的数 177 字符倒置 178 部分排序 179 产品销售记录处理 180 特定要求的字符编码 181 求解三角方程 182 新完全平方数 183 三重回文数 184 奇数方差 185 统计选票 186 同时整除 187 字符左右排序 188 符号算式求解 189 数字移位 190 统计最高成绩 191 比较字符长度 192 合并整数 193 矩阵逆置 194 删除指定的字符 195 括号匹配 196 字符逆置 197 SIX/NINE问题 198 单词个数统计 199 方差运算 200 级数运算 201 输出素数 202 素数题 203 序列排序 204 整数各位数字排序 205 字符字母移位 206 Fibonacc数列 第七部分 游戏篇 207 商人过河游戏 208 吃数游戏 209 解救人质游戏 210 打字训练游戏 211 双人竞走游戏 212 迷宫探险游戏 213 迷你撞球游戏 214 模拟扫雷游戏 215 推箱子游戏 216 五子棋游戏 第八部分 综合实例篇 217 综合CAD系统 218 功能强大的文本编辑器 219 图书管理系统 220 进销存管理系统

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值