CCF——模板生成系统

来源:互联网 发布:c4d mac下载 编辑:程序博客网 时间:2024/06/15 16:49

问题描述

 成成最近在搭建一个网站,其中一些页面的部分内容来自数据库中不同的数据记录,但是页面的基本结构是相同的。例如,对于展示用户信息的页面,当用户为Tom时,网页的源代码是 ![这里写图片描述](http://img.blog.csdn.net/20170911202510216?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzMyNDgwMTk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) 而当用户为Jerry时,网页的源代码是 ![这里写图片描述](http://img.blog.csdn.net/20170911202632300?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzMyNDgwMTk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) 这样的例子在包含动态内容的网站中还有很多,为了简化生成网页的工作,成成觉得他需要引入一套模板生成系统。 模板是包含特殊标记的文本。成成用到的模板只包含一种特殊标记,格式为 {{ VAR }},其中 VAR 是一个变量。该标记在模板生成时会被变量 VAR 的值所替代。例如,如果变量 name = "Tom",则 {{ name }} 会生成 Tom。具体的规则如下:

  ·变量名由大小写字母、数字和下划线 (_) 构成,且第一个字符不是数字,长度不超过 16 个字符。
  ·变量名是大小写敏感的,Name 和 name 是两个不同的变量。
  ·变量的值是字符串。
  ·如果标记中的变量没有定义,则生成空串,相当于把标记从模板中删除。
  ·模板不递归生成。也就是说,如果变量的值中包含形如 {{ VAR }} 的内容,不再做进一步的替换。
 

输入格式

 输入的第一行包含两个整数 m, n,分别表示模板的行数和模板生成时给出的变量个数。

   接下来 m 行,每行是一个字符串,表示模板。
   接下来 n 行,每行表示一个变量和它的值,中间用一个空格分隔。值是字符串,用双引号 (“) 括起来,内容可包含除双引号以外的任意可打印 ASCII 字符(ASCII 码范围 32, 33, 35-126)。
   

输出格式

 输出包含若干行,表示模板生成的结果。

样例输入

11 2<!DOCTYPE html><html><head><title>User {{ name }}</title></head><body><h1>{{ name }}</h1><p>Email: <a href="mailto:{{ email }}">{{ email }}</a></p><p>Address: {{ address }}</p></body></html>name "David Beckham"email "david@beckham.com"

样例输出

<!DOCTYPE html><html><head><title>User David Beckham</title></head><body><h1>David Beckham</h1><p>Email: <a href="mailto:david@beckham.com">david@beckham.com</a></p><p>Address: </p></body></html>

评测用例规模与约定

    0 ≤ m ≤ 100   0 ≤ n ≤ 100

  输入的模板每行长度不超过 80 个字符(不包含换行符)。
  输入保证模板中所有以 {{ 开始的子串都是合法的标记,开始是两个左大括号和一个空格,然后是变量名,结尾是一个空格和两个右大括号。
  输入中所有变量的值字符串长度不超过 100 个字符(不包括双引号)。
  保证输入的所有变量的名字各不相同。

解题思路

 刚开始看到这题时,认为只要定义一个字符的二维数组便能解决问题,char s[105][105]; 输入是没有问题,但是进行关键字的判定时就会出现问题,输入的时候采用cin>>s[i];一行一行地输入,但当出现上面的关键字"{{ name }}"那怎么办,如何进行判断这个位置是在此行的第几个;所以果断放弃使用字符数组,改用字符串string。 但值得注意的是使用string,再输入的时候,一旦碰到空格“ ”和换行符'\n'就直接停止输入。所以要使用getline()函数,使得一整行的输入能被输入到string中,但遇到'\n'换行符就停止输入进字符串中去了。解决完输入问题,接着解决关键字判断的问题,当遇到如"{{ name }}"时,将该行的下标存放在新的数组当中去,记录第一个'{'和最后一个'}'的下标位置即可。 最后一步,也是最关键的一步,如何将要生成的字符和关键字进行替换。想了想还是使用C++带有的容器map中的replace函数直接进行替换即可完成该任务。 现在思路很清晰,上代码:

Code

#include <iostream>#include <string>#include <map>#include <stdio.h> using namespace std;int m, n;int main(){    int i, j;    string s[105];    string s1, s2, s3, s4;    cin >> n >> m;    getchar();    for (i=0;i<n;i++)    {        getline(cin, s[i]);    }    map<string, string>v;    for (j=0;j<m;j++)    {        int k, k1 = 0;        cin >> s1;        getchar();        getline(cin, s2);        s1.insert(0, "{{");        s1 += "}}";        s2.erase(0, 1);        s2.erase(s2.end() - 1, s2.end());        v[s1] = s2;    }    int j1[20], j2[20], k, k1;    for (i=0;i<n;i++)    {        k1 = 0;        memset(j1, -1, sizeof(j1));        memset(j2, -1, sizeof(j2));        for (j=0;s[i][j]!=0;j++)        {            if (s[i][j] == '{'&&s[i][j+1]=='{')            {                j1[k1] = j;            }            if (s[i][j]=='}'&&s[i][j+1]=='}')            {                j2[k1] = j + 1;            }            if (j1[k1]!=-1&&j2[k1]!=-1)            {                k1++;            }        }        int t = 0;        for (j=0;j<k1;j++)        {            s3 = "";            for (k = j1[j] + t; k <= j2[j] + t; k++)            {                s3.insert(s3.end(), s[i][k]);            }  //end k for                if (v.count(s3))                {                    s[i].replace(s[i].begin() + j1[j] + t, s[i].begin() + j2[j] + 1 + t, v[s3]);                    t = t + v[s3].size() - s3.size();                   }                else                {                    s[i].replace(s[i].begin() + j1[j] + t, s[i].begin() + j2[j] + 1 + t, "");                    t = t - s3.size();                }         //end else        }   //end for j        cout << s[i] << endl;    }    return 0;}

再上一个另外的版本吧,思路也是一样

Code

#include <iostream>  #include <stdio.h>  #include <string.h>  #include <map>  using namespace std;  int main()  {      int m, n;      string line[105], sv, s[105], v[105];      char tmp[105];      map<string, string> mp;      cin >> m >> n;      getline(cin, line[0]);      for(int i = 0; i < m; i++)      {          getline(cin, line[i]);      }      for(int i = 0; i < n; i++)      {          cin >> s[i];          getchar();          getline(cin, v[i]);          mp[s[i]] = v[i];      }      for(int i = 0; i < m; i++)      {          int flag = -1;          int k = 0;          int len = line[i].length();          for(int j = 0; j < len; j ++)          {              if(line[i][j] == '{' && line[i][j + 1] == '{' && flag == -1) //注意这里的判断              {                  flag = j;                  j = j + 2;              }              else if(flag != -1 && line[i][j] != ' ')              {                   tmp[k] = line[i][j];                   k ++;              }              else if(flag != -1 && line[i][j]== ' ')              {                  tmp[k++]='\0';                  string s, t;                  int tl;                  s = tmp;                  t = mp[s];                  tl = t.length();                  if(tl >= 1)                  {                      for(int l = 1; l < tl -1; l ++ )                      {                          cout<<t[l];                      }                  }                  flag = -1;                  k = 0;                  j = j + 2;              }              else cout<<line[i][j];          }          cout<<endl;      }      return 0;  }  
原创粉丝点击