題目如下: 這題我剛開始被示例給迷惑了,是將key和value分開輸入的,類似於cin>>key>>value,這裡應該是要講每行字元串連接成一個新的字元串,然後遍歷整個字元串,遇到:表示key錄入完畢,遇到,和},要先判斷,的情況,確定,前面沒有},這是才表示value錄入完畢。再就是首碼的問題, ...
題目如下:
試題編號: 201709-3 試題名稱: JSON查詢 時間限制: 1.0s 記憶體限制: 256.0MB 問題描述: 問題描述 JSON (JavaScript Object Notation) 是一種輕量級的數據交換格式,可以用來描述半結構化的數據。JSON 格式中的基本單元是值 (value),出於簡化的目的本題只涉及 2 種類型的值: * 字元串 (string):字元串是由雙引號 " 括起來的一組字元(可以為空)。如果字元串的內容中出現雙引號 ",在雙引號前面加反斜杠,也就是用 \" 表示;如果出現反斜杠 \,則用兩個反斜杠 \\ 表示。反斜杠後面不能出現 " 和 \ 以外的字元。例如:""、"hello"、"\"\\"。 * 對象 (object):對象是一組鍵值對的無序集合(可以為空)。鍵值對錶示對象的屬性,鍵是屬性名,值是屬性的內容。對象以左花括弧 { 開始,右花括弧 } 結束,鍵值對之間以逗號 , 分隔。一個鍵值對的鍵和值之間以冒號 : 分隔。鍵必須是字元串,同一個對象所有鍵值對的鍵必須兩兩都不相同;值可以是字元串,也可以是另一個對象。例如:{}、{"foo": "bar"}、{"Mon": "weekday", "Tue": "weekday", "Sun": "weekend"}。 除了字元串內部的位置,其他位置都可以插入一個或多個空格使得 JSON 的呈現更加美觀,也可以在一些地方換行,不會影響所表示的數據內容。例如,上面舉例的最後一個 JSON 數據也可以寫成如下形式。 { "Mon": "weekday", "Tue": "weekday", "Sun": "weekend" } 給出一個 JSON 格式描述的數據,以及若幹查詢,編程返回這些查詢的結果。 輸入格式 第一行是兩個正整數 n 和 m,分別表示 JSON 數據的行數和查詢的個數。 接下來 n 行,描述一個 JSON 數據,保證輸入是一個合法的 JSON 對象。 接下來 m 行,每行描述一個查詢。給出要查詢的屬性名,要求返回對應屬性的內容。需要支持多層查詢,各層的屬性名之間用小數點 . 連接。保證查詢的格式都是合法的。 輸出格式 對於輸入的每一個查詢,按順序輸出查詢結果,每個結果占一行。 如果查詢結果是一個字元串,則輸出 STRING <string>,其中 <string> 是字元串的值,中間用一個空格分隔。 如果查詢結果是一個對象,則輸出 OBJECT,不需要輸出對象的內容。 如果查詢結果不存在,則輸出 NOTEXIST。 樣例輸入 10 5 { "firstName": "John", "lastName": "Smith", "address": { "streetAddress": "2ndStreet", "city": "NewYork", "state": "NY" }, "esc\\aped": "\"hello\"" } firstName address address.city address.postal esc\aped 樣例輸出 STRING John OBJECT STRING NewYork NOTEXIST STRING "hello" 評測用例規模與約定 n ≤ 100,每行不超過 80 個字元。 m ≤ 100,每個查詢的長度不超過 80 個字元。 字元串中的字元均為 ASCII 碼 33-126 的可列印字元,不會出現空格。所有字元串都不是空串。 所有作為鍵的字元串不會包含小數點 .。查詢時鍵的大小寫敏感。 50%的評測用例輸入的對象只有 1 層結構,80%的評測用例輸入的對象結構層數不超過 2 層。舉例來說,{"a": "b"} 是一層結構的對象,{"a": {"b": "c"}} 是二層結構的對象,以此類推。
這題我剛開始被示例給迷惑了,是將key和value分開輸入的,類似於cin>>key>>value,這裡應該是要講每行字元串連接成一個新的字元串,然後遍歷整個字元串,遇到:表示key錄入完畢,遇到,和},要先判斷,的情況,確定,前面沒有},這是才表示value錄入完畢。再就是首碼的問題,出現{時先判斷key是否為空,為空的話,那就首碼preHost不變,如果不為空,且要判斷preHost原來是否為空,如果是空的,那麼preHost=key,否則,preHost=preHost+"."+key。代碼如下
#include<stdio.h>
#include<iostream> #include<map> #include<string.h> using namespace std; int main() { string s=""; int n,m; cin>>n>>m; getchar(); for(int i=0;i<n;i++) { string temps; getline(cin,temps); s+=temps; } map<string,string> json; string key="",value=""; string kvs=""; int count=0,vflag=0,kflag=0; // cout<<s<<" len:"<<s.length()<<endl; string preHost=""; int len=s.length(); for(int i=0;i<len;i++) { if(s[i]!='\"'&&s[i]!='\\'&&s[i]!=' ') { if(s[i]==':'||s[i]==','||s[i]=='}') { if(s[i]==','||s[i]=='}') { if(s[i]==','&&s[i-1]=='}') { preHost=""; }else{ // cout<<"flag :"<<s[i]<<endl; kvs[count]='\0'; value=kvs; vflag=1; kvs=""; count=0; } }else{ kvs[count]='\0'; // cout<<"kvs:"<<kvs<<endl; key=kvs; // cout<<"key:"<<key<<endl; kvs=""; kflag=1; count=0; } }else{ if(s[i]!='{') { kvs+=s[i]; count++; }else if(s[i]=='{'){ if(key!="") { value="{"; vflag=2; if(preHost=="") { preHost=key; }else{ preHost=preHost+"."+key; } } } } }else if(s[i]=='\\') { i++; // cout<<"vflag:"<<vflag<<" kflag:"<<kflag<<endl; kvs+=s[i]; count++; } if(kflag==1&&vflag>=1) { // cout<<"preHost:"<<preHost<<endl; if(vflag==1) { if(preHost!="") key=preHost+"."+key; } else if(vflag==2) { key=preHost; } // cout<<"key:"<<key<<" value:"<<value<<endl; json[key]=value; vflag=0; kflag=0; key=""; value=""; if(s[i]=='}') { preHost=""; } } } for(int i=0;i<m;i++) { string temps; cin>>temps; if(json[temps]=="") { cout<<"NOTEXIST"<<endl; }else if(json[temps]=="{") { cout<<"OBJECT"<<endl; }else{ cout<<"STRING "<<json[temps]<<endl; } } return 0; }
補充知識:如何遍歷map:
map<string, string>::const_iterator it; for (it = json.begin(); it != json.end(); ++it) cout << it->first << "=" << it->second << endl;