C++ STL練習(2)
阿新 • • 發佈:2018-11-22
題目1:反片語
思路:
由於有了上篇部落格題目中的經驗,遇到不區分大小寫,那就在判斷時用臨時變數儲存呼叫tolower()函式轉變成小寫形式的字串
1.可以寫一個函式對每個單詞標準化:全部轉化為小寫字母,然後再對字母排序
2.用map統計標準化每個單詞出現的次數,標準化之後題目中能通過字母重排的單詞相同
3.儲存單詞出現次數為1的原單詞
4.對儲存的單詞進行字典排序,然後打印出來
程式碼實現:
#include <iostream> #include <string> #include <vector> #include <algorithm> #include <map> using namespace std; //定義關聯陣列map用於統計每個單詞出現的次數 map<string,int> timesOfWord; //定義一個可變陣列用於儲存原單詞 vector<string> words; //標準化每個單詞 /* 注意:這個函式的定義不能直接返回引用,因為題目要求最終輸出要保留輸入中的大小寫 void standardizeWord(string &word) */ //所以我們可以傳入引用,在函式內部進行拷貝,然後返回拷貝的string物件 string standardizeWord(const string &word) { //定義變數儲存標準化的單詞 string standardWord = word; //遍歷單詞的每個字元,將每個字元轉換成小寫 for(unsigned int i=0;i < word.length();i++) { tolower(standardWord[i]); } //對單詞內的字元進行排序 sort(standardWord.begin(),standardWord.end()); return standardWord; } int main() { //定義一個變數用於儲存使用者輸入的單詞 注意:這道題目要求使用者輸入的是單詞,所以除過結束字元'#'和字母字元沒有其他字元 string inputText; //執行一次迴圈cin每次讀取多少字元?用什麼標識來決定? //迴圈結束的標誌:EOF Unix和Linux:ctrl+D windows:ctrl+Z和Enter //迴圈讀取使用者輸入的單詞 while(cin >> inputText) { //遇到使用者輸入的結束符‘#’就結束迴圈 if(inputText[0] == '#') break; //將單詞儲存在vector當中,用於最後進行輸出 words.push_back(inputText); //將接受到的單詞進行標準化 string standardWord = standardizeWord(inputText); //這裡的判斷是必要的,因為我們會在下面直接通過索引訪問map,但是我們訪問時必須保證我們所訪問的鍵存在 if(!timesOfWord.count(standardWord)) timesOfWord[standardWord] = 0; //讓標準化後的字串統計數+1 timesOfWord[standardWord]++; } //定義儲存要輸出單詞的陣列 vector<string> savePrintStr; //將統計次數為1的字串儲存到savePrintStr for(unsigned int i=0;i < words.size();i++) { if(timesOfWord[standardizeWord(words[i])]==1) { savePrintStr.push_back(words[i]); } } //對要輸出的字串排序 sort(savePrintStr.begin(),savePrintStr.end()); //列印結果 for(vector<string>::iterator it =savePrintStr.begin();it!=savePrintStr.end();it++) cout<<*it<<endl; return 0; }
eclipse下執行結果:
知識點詳細用法補充:(待補充)
while(cin >> inputText)中執行一次迴圈cin每次讀取多少字元?用什麼標識來決定?
題目2:集合棧計算機(後續補充)
思路:
程式碼實現:
eclipse下執行結果:
知識點詳細用法補充:
題目3:團體佇列
思路:本題沒有使用書中原來的思路,通過參考作者思路和自己思考,使用了類似作業系統當中多級頁表的原理
1. 定義兩種佇列:團隊內部佇列陣列(這個陣列可以使用關聯陣列,鍵:團隊編號,值:團隊佇列),團隊編號佇列
2.入隊:
我們先判斷該團隊佇列編號是否在團隊編號佇列中,
如果在,我們對應到團隊佇列陣列中可以用O(1)的時間複雜度找到對應團隊編號的佇列,將它插入到其中
如果不在,我們將該團隊編號入團隊編號佇列,同時新建該團隊佇列所對應的關聯陣列,將該編號入隊
3.出隊:
我們直接到團隊編號佇列的隊首元素,然後對應到map中相應的佇列的隊首元素出隊,
同時判斷出隊後,佇列是否為空,如果為空,釋放該map元素的記憶體
程式碼實現:
#include <iostream> #include <queue> #include <map> using namespace std; //函式宣告 void q_enqueue(); void q_dequeue(); //這裡使用vector可以嗎?這樣就可以不把陣列長度寫死,使用vector,array和內建陣列有什麼區別 //用於儲存團隊佇列陣列的最大團隊數 const int arrSizeOfTeam=1000; //儲存每個團隊成員資訊,用鍵值對儲存每個隊員的編號和他所屬隊的編號,鍵:隊員編號(唯一) 值:所屬團隊編號 map<int,int> teamMemInfo; //團隊編號佇列 queue<int> numQueue; //團隊佇列陣列 map<int,queue<int>> queueMap; //****************************************獲取使用者輸入的指令,並執行相應的操作************************** //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%下列思路類似於多級頁表的原理%%%%%%%%%%%%%%%%%%%%%%%%%% //定義兩種佇列:團隊內部佇列陣列(這個陣列可以使用關聯陣列,鍵:團隊編號,值:團隊佇列),團隊編號佇列 //入隊: //我們先判斷該團隊佇列編號是否在團隊編號佇列中, // 如果在,我們對應到團隊佇列陣列中可以用O(1)的時間複雜度找到對應團隊編號的佇列,將它插入到其中 // 如果不在,我們將該團隊編號入團隊編號佇列,同時新建該團隊佇列所對應的關聯陣列,將該編號入隊 //出隊: //我們直接到團隊編號佇列的隊首元素,然後對應到map中相應的佇列的隊首元素出隊, // 同時判斷出隊後,佇列是否為空,如果為空,釋放該map元素的記憶體 void q_enqueue() { queue<int> temp;//queue預設初始化時,佇列中有元素嗎? //獲取使用者輸入的隊員編號 int mNum; cin>>mNum; //獲取使用者所在團隊號 int tNum= teamMemInfo[mNum]; //團隊佇列map中是否有該團隊號(鍵) if(!queueMap.count(tNum)) {//沒有該鍵的話,我們動態申請新建一個佇列 //queueMap[tNum] = new queue<int>(); queueMap[tNum] = temp; numQueue.push(tNum); } queueMap[tNum].push(mNum); } void q_dequeue() { //獲取佇列編號的隊頭編號 int numDequeue = numQueue.front(); //列印要出隊的隊員 cout<<queueMap[numDequeue].front()<<endl; //找到隊頭編號佇列,執行出棧 queueMap[numDequeue].pop(); //判斷該對列是否為空,為空的話釋放記憶體 if(queueMap[numDequeue].empty()) //c++中map怎麼刪除元素,釋放記憶體呢? { //將編號隊列出隊 numQueue.pop(); //delete queueMap[numDequeue]; //c++中map怎麼刪除元素,釋放記憶體呢? for(map<int,queue<int>>::iterator it=queueMap.begin();it != queueMap.end();it++) { if(it->first == numDequeue) { //delete it->second; //it->second=NULL; //怎麼釋放一個queue的記憶體->STL容器的各種型別是如何釋放記憶體的? queueMap.erase(it); break; } } } } int main() { int scen = 0;//場景模擬的次數 int teamNum = 0;//團隊的數量 while((cin>>teamNum)&&teamNum) //獲取使用者輸入的團隊數量,並且保證團隊數量不為0執行下面的操作才有意義 { //每當執行迴圈的都是一次新的場景模擬,我們按照樣例輸出區分不同場景 cout<<"Scenario #"<<++scen<<endl; //****************************************獲取使用者輸入的團隊資訊***************************** for(int i=0;i < teamNum;i++) { //獲取使用者輸入的團隊的成員數量 int memNum; cin>>memNum; int tempMem;//用於接受使用者臨時儲存的隊員編號 //記錄使用者輸入的隊員資訊 while(memNum--) { cin>>tempMem; teamMemInfo[tempMem]= i; } } //判斷使用者輸入的指令,執行相應的操作 while(true) { //獲取使用者輸入的指令 string instruction; cin>>instruction; //判斷使用者輸入的指令型別 if(instruction[0] == 'S')//工程中這麼判斷缺乏安全性,在這裡我們假設使用者的輸入都是合法輸入 break; else if(instruction[0] == 'D') q_dequeue(); else if(instruction[0] == 'E') q_enqueue(); } cout<<"第"<<scen<<"次模擬結束"<<endl; } return 0; }
eclipse下執行結果:
知識點詳細用法補充:
1.STL容器記憶體釋放?
2.map
3.queue
題目4:醜數(後續補充)
思路:
程式碼實現:
eclipse下執行結果:
知識點詳細用法補充: