題目描述:
題解:
先說一句,這道題目只拿到了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;
}