CCF CSP認證考試歷年真題 模板生成系統 C語言實現
試題名稱:日期計算 時間限制:1.0s 記憶體限制:256.0MB
問題描述:
成成最近在搭建一個網站,其中一些頁面的部分內容來自資料庫中不同的資料記錄,但是頁面的基本結構是相同的。例如,對於展示使用者資訊的頁面,當用戶為 Tom 時,網頁的原始碼是
而當用戶為Jerry 時,網頁的原始碼是
這樣的例子在包含動態內容的網站中還有很多。為了簡化生成網頁的工作,成成覺
得他需要引入一套模板生成系統。
模板是包含特殊標記的文字。成成用到的模板只包含一種特殊標記,格式為 {{ 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 "
樣例輸出
<!DOCTYPE html>
<html> <head>
<title>User David Beckham</title>
</head> <body>
<h1>David Beckham</h1>
<p>Email: <a href="mailto:[email protected]">[email protected]</a></p>
<p>Address: </p>
</body> </html>
評測用例規模與約定 0 ≤ m ≤ 100 0 ≤ n ≤ 100
輸入的模板每行長度不超過 80 個字元(不包含換行符)。
輸入保證模板中所有以 {{ 開始的子串都是合法的標記,開始是兩個左大括號和一
個空格,然後是變數名,結尾是一個空格和兩個右大括號。
輸入中所有變數的值字串長度不超過 100 個字元(不包括雙引號)。
保證輸入的所有變數的名字各不相同。
分析:
題目本身邏輯不能,這題主要考驗對程式輸入,輸出,字串的運用。這裡我用C語言來寫,主要的scanf,printf的格式控制符的瞭解,這裡給出兩個不錯的連結:
http://blog.csdn.net/qingkong8832/article/details/6667701
http://blog.csdn.net/sdhfll/article/details/1892926
程式碼在此:
#include<stdio.h> #include<string.h> #define F_PATH "C:\\Users\\Administrator\\Desktop\\C\\data.txt" #define ADDITION 10 //字串新增多餘空間防止溢位 typedef struct{ char value[80 + ADDITION]; }late; // 一行模板 typedef struct{ char key[100 + ADDITION]; char value[100 + ADDITION]; }variable; // 一個變數 int main() { int m, n; late str[100 + ADDITION]; variable var[100 + ADDITION]; char ch; scanf("%d %d", &m, &n); /* while( (ch=getchar()) != '\n' ) continue;*/ ch = getchar(); // 必須加這個,因為%[]讀取時會把上一個\n給讀取到進去然後跳過直接空字串。不用ch = getchar();就得在上一個scanf()改成 scanf("%d %d\n", &m, &n)。又或者把ch = getchar();換成上面那個我while迴圈 for(int i = 0; i < m; i ++) { scanf("%[^\n]%*c", str[i].value); //接收一行 } for(int i = 0; i < n; i ++) { scanf("%s %*c%[^\"]", var[i].key, var[i].value); scanf("%*c"); // %[^\"] 不會接收後面的\",不過\"還是在輸入快取中,在獲取變數的值後需要把這個\"從輸入快取中去掉以免影響下一次 } for(int i = 0; i < m; i ++) //迴圈輸出m行模板 { int len = strlen(str[i].value); for(int j = 0; j < len; j ++) //迴圈判斷沒行模板的每個字元 { if(str[i].value[j] == '{' && str[i].value[j+1] == '{') //由於沒有巢狀,所有直接判斷即可 { char strtemp[100]; j += 3; //跳入模板變數區域 int u = 0; while(str[i].value[j] != ' ') //獲取模板裡的變數 { strtemp[u ++] = str[i].value[j]; j ++; } for(int k = 0; k < n; k ++) //查詢對應的變數替代輸出 { if(strcmp(strtemp, var[k].key) == 0) { printf("%s", var[k].value); break; } } j += 3; //跳出模板變數區域 } else { printf("%c", str[i].value[j]); //無需替換字元直接輸出 } } printf("\n"); } return 0; }