CCP-CSP認證考試 201809-3 元素選擇器 c/c++題解

CCF-CSP認證考試題解目錄By東瓜lqd

題目描述:

題解

先說一句,這道題目只拿到了70分,而且具體哪幾個點還沒有拿到我自己都是知道了,下面是分析過程:
1. 對於數據的輸入: 我使用的是vector arr[MAX],也就是一個存儲字符串的二維數組。
注意點:因爲一行中有多個字符串,多個字符串以空格分隔開來,所以使用getline來輸入,然後使用strtok()將每個字符串存入二維數組即可(如果看不懂怎麼分割的,請評論)。
2. 注意題目的要求:標籤的字母不區分大小寫,所以全部轉換爲小寫,id屬性的字母區分大小寫,所以不要變。
3. 開始元素的選擇,也就是輸出結果
我的第一份代碼,考慮了:
1.結構化文檔只有一級(也就是沒有空格)
2.元素選擇器只有標籤orID屬性,不存在後代(也就是每一行只有一個字符串)
所以正好就過了第一個點,10分
我的第二份代碼,考慮了:
1.結構化文檔有多級(比較的時候,去掉空格比較)
2.元素選擇器只有標籤or屬性,不存在後代(也就是每一行只有一個字符串)
正好可以過五個點,50分
我的第三份代碼,考慮了:
1.結構化文檔有多級(比較的時候,去掉空格比較)
2.元素選擇器除了有標籤or屬性以外,還有後代(也就是每一行有多個字符串),但是我只考慮了兩代(也就是兩個字符串)
按道理來說可以過八個點,但是不知道哪出錯了,只有70分
還可以繼續優化的情況(不想繼續寫了):
1.元素選擇器兩級的情況應該要都過,80分
2.元素選擇器三級or多級的情況也要考慮進來,100分
(我下面貼出的代碼,就是由我一層層優化過來的,也就是這個70分代碼)

代碼:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cstring>
#include <string>
#include <algorithm>
#include <vector>
#include <deque>
#include <list>
#include <utility>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <bitset>
#include <iterator>
using namespace std;

typedef long long ll;
const int inf = 0x3f3f3f3f;
const ll  INF = 0x3f3f3f3f3f3f3f3f;
const int PI = acos(-1);
const int E = exp(1);
const int MOD = 1e9+7;
const int MAX = 1e5+5;
int n,m;
vector <string> text[100+5];// html文檔
vector <string> select[10+5];// css選擇器

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    /* 輸入:n行的結構化文檔 + m行的選擇器 */
    cin >> n >> m;
    cin.get();
 
    string str;
    for(int i = 0; i < n; i++)
    {
        getline(cin,str);
        char * cStr = (char*)str.c_str();
        char * result = NULL;
        result = strtok(cStr," ");
        while(result != NULL)
        {
            string tmp = result;
            text[i].push_back(tmp);
            result = strtok(NULL," ");
        }
    }
    for(int i = 0; i < m; i++)
    {
        getline(cin,str);
        char * cStr = (char*)str.c_str();
        char * result = NULL;
        result = strtok(cStr," ");
        while(result != NULL)
        {
            string tmp = result;
            select[i].push_back(tmp);
            result = strtok(NULL," ");
        }
    }

    /* 標籤中的字母不看大小寫,全變爲小寫形式\id屬性的字母看大小寫,還是保留原樣
     */
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < (int)text[i].size(); j++)
        {
            //cout << text[i][j] << " ";
            if(text[i][j][0] != '#')
            {
                // 標籤對大小寫不敏感,如果爲字母,則全轉換爲小寫
                for(int k = 0; k < (int)text[i][j].length(); k++)
                {
                    if(isalpha(text[i][j][k]))
                    {
                        text[i][j][k] = tolower(text[i][j][k]);
                    }
                }
            }
            else
            {
                // id屬性對大小寫敏感,不需要改
            }
        }
        //cout << endl;
    }
    for(int i = 0; i < m; i++)
    {
        for(int j = 0; j < (int)select[i].size(); j++)
        {
            //cout << select[i][j] << " ";
            if(select[i][j][0] != '#')
            {
                // 標籤對大小寫不敏感,如果爲字母,則全轉換爲小寫
                for(int k = 0; k < (int)select[i][j].length(); k++)
                {
                    if(isalpha(select[i][j][k]))
                    {
                        select[i][j][k] = tolower(select[i][j][k]);
                    }
                }
            }
            else
            {
                // id屬性對大小寫敏感,不需要改
            }
        }
        //cout << endl;
    }

    /* 輸出:m行選擇的結果:選擇出的元素個數 + 每個元素出現的行號(從小到大排序) */
    for(int i = 0; i < m; i++)
    {
        int sum = 0;
        vector <int> res;
        if(select[i].size() == 1)// 沒有後代關係,就只有一個字符串
        {
            string Select = select[i][0];
            for(int j = 0; j < n; j++)
            {
                bool flag = false;
                for(int k = 0; k < (int)text[j].size(); k++)
                {
                    int index = 0;
                    while(text[j][k][index] == '.')
                    {
                        index++;
                    }
                    string tmp = text[j][k].substr(index);
                    if(tmp == Select)// 比較兩個字符串,忽略掉元素選擇器的"."
                    {
                        flag = true;
                        res.push_back(j+1);
                        break;
                    }
                }
                if(flag)
                {
                    sum++;
                }
            }
            cout << sum << " ";
            for(int j = 0; j < (int)res.size(); j++)
            {
                cout << res[j] << " ";
            }
            cout << endl;
        }
        else if(select[i].size() == 2)// 有後代關係,兩個字符串
        {
            string Select1 = select[i][0];
            string Select2 = select[i][1];
            for(int j = 0; j < n; j++)
            {
                bool flag = false;
                for(int k = 0; k < (int)text[j].size(); k++)
                {
                    int index = 0;
                    while(text[j][k][index] == '.')
                    {
                        index++;
                    }
                    string tmp = text[j][k].substr(index);
                    if(tmp == Select2)// 比較兩個字符串,忽略掉元素選擇器的"."
                    {
                        /*
                        flag = true;
                        res.push_back(j+1);
                        break;
                        */
                        // 有Select2,還要保證前面有Select1作爲祖先,也就是點的個數比Select2的少偶數個
                        // Select2前面的點有index個
                        for(int j2 = j-1; j2 >= 0; j2--)
                        {
                            for(int k2 = 0; k2 < (int)text[j2].size(); k2++)
                            {
                                int index_t = 0;// 記錄下Select1前面的點
                                while(text[j2][k2][index_t] == '.')
                                {
                                    index_t++;
                                }
                                string tmp2 = text[j2][k2].substr(index_t);
                                if(tmp2 == Select1 && index_t < index)
                                {
                                    flag = true;
                                    res.push_back(j+1);
                                    break;
                                }
                            }
                            if(flag)
                            {
                                break;
                            }
                        }
                    }
                }
                if(flag)
                {
                    sum++;
                }
            }
            cout << sum << " ";
            for(int j = 0; j < (int)res.size(); j++)
            {
                cout << res[j] << " ";
            }
            cout << endl;
        }
    }


    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章