首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

Sicily 14257 Myvim Plugin:Emmet 風格 HTML 縮寫展開器

     編輯:關於C++

題目描述

實現類 Emmet 的 HTML 縮寫展開。輸入縮寫字符串(含標籤名、id(#)、class(.)、子選擇器(>)、兄弟分組(())),輸出完整 HTML 標籤結構。約束:N ≤ 50,輸入長度 ≤ 120,輸出 ≤ 1000。

語法規則

  • 標籤名:字母數字組成。
  • #id:id 屬性,每標籤最多一個。
  • .class:class 屬性,可多個,按順序輸出。
  • >:子層級嵌套。
  • ():分組,生成同級標籤。

示例:div.aa#bb.cc.ee>p#g>span.d → 嵌套結構;div>(p#g1>span)(p#g2>span) → 同級 p 標籤。

解題思路:遞歸下降解析器

定義遞歸函數 parse(l, r) 處理子串 [l, r):

  1. 讀取標籤名(字母數字序列)。
  2. 循環讀取 #、.、()、>:
    • # 後跟 id 名。
    • . 後跟 class 名,累積。
    • ( 找到匹配 ),遞歸解析內容作為同級分組(一組可包含多個同級標籤)。
    • > 後跟子標籤,遞歸解析並嵌套輸出。
  3. 輸出開始標籤 <tag id="..." class="...">(id 優先於 class)。
  4. 若有子內容(> 或 () 產生),遞歸輸出子內容。
  5. 輸出結束標籤 </tag>。

C++ 代碼實現(核心邏輯)

string s;
bool isAlnum(char c) { return isalnum(c); }

void parse(int l, int r) {
    string tag, id, cls;
    int p = l;
    // 1. 讀標籤名
    while (p < r && isAlnum(s[p])) ++p;
    tag = s.substr(l, p - l);
    // 2. 解析屬性與結構
    while (p < r) {
        if (s[p] == '#') { // id
            int st = ++p;
            while (p < r && isAlnum(s[p])) ++p;
            id = s.substr(st, p - st);
        } else if (s[p] == '.') { // class
            int st = ++p;
            while (p < r && isAlnum(s[p])) ++p;
            cls += (cls.empty() ? "" : " ") + s.substr(st, p - st);
        } else if (s[p] == '(') { // 分組
            int st = ++p, cnt = 1;
            while (p < r) {
                if (s[p] == ')') --cnt;
                else if (s[p] == '(') ++cnt;
                if (cnt == 0) break;
                ++p;
            }
            parse(st, p); // 遞歸處理分組內容(同級)
            ++p; // 跳過 ')'
        } else if (s[p] == '>') { // 子標籤
            ++p;
            // 輸出當前標籤開始
            cout << "<" << tag;
            if (!id.empty()) cout << " id=\"" << id << "\"";
            if (!cls.empty()) cout << " class=\"" << cls << "\"";
            cout << ">";
            parse(p, r); // 遞歸處理子內容
            cout << "";
            return; // > 後必為最後部分
        } else break;
    }
    // 無 > 時輸出自閉或空標籤
    cout << "<" << tag;
    if (!id.empty()) cout << " id=\"" << id << "\"";
    if (!cls.empty()) cout << " class=\"" << cls << "\"";
    cout << ">";
}

int main() {
    int T; cin >> T; string dummy; getline(cin, dummy);
    while (T--) {
        getline(cin, s);
        parse(0, s.size());
        cout << endl;
    }
}

關鍵點

  • 分組 () 內可包含多個同級標籤(由 > 分隔),遞歸處理時順序輸出。
  • > 後必為最後部分,直接遞歸處理剩餘字符串。
  • 輸出格式嚴格:屬性順序 id→class,雙引號,無多餘空格。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved