題目
Token的種類:
Case1:Identifier
底線或英文字母開頭,之後跟著英文字母或底線或數字
Ex:int, _abc, k9999, a, cc, kfn_0, a2b, return
Case2:Number
一般的數字,測資不會有包含小數點的浮點數出現。
Ex:1, 23, 284, 295, 7729...
Case3:Special Symbol ( 以下所列出來的33種特殊符號 )
+ - * / > < = % & | ^ "
' . , ( ) [ ] { } ! : ;
++ -- += <= >= == != && ||
你的程式會根據以上三種case將讀入的input做分類,接著將會根據讀入的command執行以下動作:
- 結束程式
- 印出總共多少個token
- 印出所有的token
- 印出三種case各有多少token
Input的方式採用螢幕輸入,會輸入一段長度不定的token,用換行作為token的分隔,也就是說一行只會有一個token,並會以END_OF_FILE 這個字做結尾。你要做的事情只有讀取這些資料,並且判斷它們屬於何種token。接著會輸入數個0~3的數字,來測試互動式功能選項。
The actual input and output for running your program is something that looks like the following:
例一:
例二:
完整程式碼
#include<iostream>
#include <string>
using namespace std;
//4.
int classifier (char token[]){
char letter= token[0];
//測試是否為Identifier
if( (65<=letter && letter<=90) || (97<=letter && letter<=122) || letter==95 ) return 1;
//測試是否為Number
else if(48<=letter && letter<=57) return 2;
//為SpecialSymbol
return 3;
}
int main()
{
//1.設定輸入的儲存變數
char token[30]; //儲存此次單行的token
char inputAll[100][30]; //存下所有輸入的token
int inputNum=0;
int num_Identifier = 0;
int num_Number = 0;
int num_SpecialSymbol = 0;
//2.在cmd輸入多個token 並且存下來直到END_OF_FILE才停止
while(cin >> token){
//input為END_OF_FILE時中斷輸出
string s;
s=token;
if (s.compare("END_OF_FILE") == 0) break;
//把token紀錄在inputAll當中
std::copy(token, token+30, inputAll[inputNum++]);
//4.判斷輸入token類別
if(classifier(token)==1) num_Identifier++;
else if(classifier(token)==2) num_Number++;
else if(classifier(token)==3) num_SpecialSymbol++;
}
//3.處理完之後對街按下0 1 2 3的效果
int cmdCode;
while(cin >> cmdCode){
if(cmdCode==0) break;
switch (cmdCode)
{
case 1:
printf("Total number of tokens: %d\n",inputNum);
break;
case 2:
for(int i=0;i<inputNum;i++){
printf("[%s]\n",inputAll[i]);
}
break;
case 3:
printf ("Identifier: %d,Number: %d,Special Symbol: %d\n",num_Identifier,num_Number,num_SpecialSymbol);
break;
default:
break;
}
}
}
解題過程
基本語法:
https://www.csie.ntu.edu.tw/~b98902112/cpp_and_algo/cpp02/user_defined_function.html
儲存token和設定各變數
觀念: array
char token[30]; //儲存此次單行的token
char inputAll[100][30]; //存下所有輸入的token
int inputNum=0;
int num_Identifier = 0;
int num_Number = 0;
int num_SpecialSymbol = 0;
輸入階段
接下來我們知道會一直輸入token 直到token值為END_OF_FILE為止
觀念:while
while(cin >> token){
...
}
1.先把輸入的token從char[] --> string , 再看看是不是END_OF_FILE
觀念:string, string比較
char[]-->string:
https://asd9616132.pixnet.net/blog/post/468832115-char%E8%BD%89string-%E5%92%8C-string%E8%BD%89char
string比較:
https://shengyu7697.github.io/cpp-string-compare/
string s;
s=token;
if (s.compare("END_OF_FILE") == 0) break;
先把token轉成string s
再用function s.compare("END_OF_FILE")判斷是否s(token)為"END_OF_FILE"
是的話結束輸入階段
2.把這的token記錄起來,紀錄在inputAll裡面
觀念: 二維矩陣
//把token紀錄在inputAll當中
std::copy(token, token+30, inputAll[inputNum++]);
3.以classifier function判斷輸入token為甚麼種類
觀念:if/else
if(classifier(token)==1) num_Identifier++;
else if(classifier(token)==2) num_Number++;
else if(classifier(token)==3) num_SpecialSymbol++;
4.classifier function實作
程式碼:
int classifier (char token[]){
char letter= token[0];
//測試是否為Identifier
if( (65<=letter && letter<=90) || (97<=letter && letter<=122) || letter==95 ) return 1;
//測試是否為Number
else if(48<=letter && letter<=57) return 2;
//為SpecialSymbol
return 3;
}
觀念:ASCII,char型別,邏輯判斷
ASCII表:
https://tool.oschina.net/commons?type=4
我們先取每個token的第一個字母,並以char型態資料用ASCII型態判斷 (e.g. "A"=97)屬於哪種類別
char letter= token[0];
Identifier的第一個字為ASCII 65~90、97~122、95
Number為ASCII 48~57
剩下的為SpecialSymbol
//測試是否為Identifier
if( (65<=letter && letter<=90) || (97<=letter && letter<=122) || letter==95 ) return 1;
//測試是否為Number
else if(48<=letter && letter<=57) return 2;
//為SpecialSymbol
return 3;
cmd操作階段
我們處理完了按下1 2 3 會出現的數據之後,接下來我們要將按下的數字鍵和會出現的輸出做對應,這裡我們用到switch ,並且將輸入1,2,3,0訂為變數cmdCode:
觀念: switch, while, break
完整程式碼:
int cmdCode;
while(cin >> cmdCode){
if(cmdCode==0) break;
switch (cmdCode)
{
case 1:
printf("Total number of tokens: %d\n",inputNum);
break;
case 2:
for(int i=0;i<inputNum;i++){
printf("[%s]\n",inputAll[i]);
}
break;
case 3:
printf ("Identifier: %d,Number: %d,Special Symbol: %d\n",num_Identifier,num_Number,num_SpecialSymbol);
break;
default:
break;
}
}
case1:
case 1:
printf("Total number of tokens: %d\n",inputNum);
break;
前面我們在輸入token時就有使用inputNum來計數,由於是從0開始因此之後還要+1
,但是因為END_OF_FILE也會算在inputNum裡面要-1,因此inputNum直接就可以代表token總數量
觀念:printf
一般來說printf是C語法中的cmd輸出,當輸出有變數又有字串時非常實用
printf("hello world!") //hello world
int num = 100;
printf("the number is %d",num); //the number is 100
case2:
觀念: for
case 2:
for(int i=0;i<inputNum;i++){
printf("[%s]\n",inputAll[i]);
}
break;
以for迴圈將inputAll當中所有token列印出來
case3:
case 3:
printf ("Identifier: %d,Number: %d,Special Symbol: %d\n",num_Identifier,num_Number,num_SpecialSymbol); break;
把所有剛剛計數過的數字用printf呈現出來
這樣我們就完成這題啦~