【CCF】命令行選項

試題名稱: 命令行選項
時間限制: 1.0s
內存限制: 256.0MB
問題描述:
問題描述
  請你寫一個命令行分析程序,用以分析給定的命令行裏包含哪些選項。每個命令行由若干個字符串組成,它們之間恰好由一個空格分隔。這些字符串中的第一個爲該命令行工具的名字,由小寫字母組成,你的程序不用對它進行處理。在工具名字之後可能會包含若干選項,然後可能會包含一 些不是選項的參數。
  選項有兩類:帶參數的選項和不帶參數的選項。一個合法的無參數選項的形式是一個減號後面跟單個小寫字母,如"-a" 或"-b"。而帶參數選項則由兩個由空格分隔的字符串構成,前者的格式要求與無參數選項相同,後者則是該選項的參數,是由小寫字母,數字和減號組成的非空字符串。
  該命令行工具的作者提供給你一個格式字符串以指定他的命令行工具需要接受哪些選項。這個字符串由若干小寫字母和冒號組成,其中的每個小寫字母表示一個該程序接受的選項。如果該小寫字母后面緊跟了一個冒號,它就表示一個帶參數的選項,否則則爲不帶參數的選項。例如, "ab:m:" 表示該程序接受三種選項,即"-a"(不帶參數),"-b"(帶參數), 以及"-m"(帶參數)。
  命令行工具的作者準備了若干條命令行用以測試你的程序。對於每個命令行,你的工具應當一直向後分析。當你的工具遇到某個字符串既不是合法的選項,又不是某個合法選項的參數時,分析就停止。命令行剩餘的未分析部分不構成該命令的選項,因此你的程序應當忽略它們。
輸入格式
  輸入的第一行是一個格式字符串,它至少包含一個字符,且長度不超過 52。格式字符串只包含小寫字母和冒號,保證每個小寫字母至多出現一次,不會有兩個相鄰的冒號,也不會以冒號開頭。
  輸入的第二行是一個正整數 N(1 ≤ N ≤ 20),表示你需要處理的命令行的個數。
  接下來有 N 行,每行是一個待處理的命令行,它包括不超過 256 個字符。該命令行一定是若干個由單個空格分隔的字符串構成,每個字符串裏只包含小寫字母,數字和減號。
輸出格式
  輸出有 N 行。其中第 i 行以"Case i:" 開始,然後應當有恰好一個空格,然後應當按照字母升序輸出該命令行中用到的所有選項的名稱,對於帶參數的選項,在輸出它的名稱之後還要輸出它的參數。如果一個選項在命令行中出現了多次,只輸出一次。如果一個帶參數的選項在命令行中出 現了多次,只輸出最後一次出現時所帶的參數。
樣例輸入
albw:x
4
ls -a -l -a documents -b
ls
ls -w 10 -x -w 15
ls -a -b -c -d -e -l
樣例輸出
Case 1: -a -l
Case 2:
Case 3: -w 15 -x

Case 4: -a -b


用了好長時間,一晚上的時間....剛開始的時候走了點彎路,想用排序解決,後來有了靈感,直接用26長度的數組解決了。然後是被空格坑了,又浪費了很多時間....最不擅長的地方。大一下學期OJ系統用getchar()什麼的結果沒通過所以有了陰影....因爲學校的OJ系統不支持getchar()什麼的。


#include<iostream>
#include<string>
#include<sstream>
using namespace std;


string a[26] ={""};//26個小寫字母中 帶參數的命令 所帶的命令
int b[26] = {0};//26個小寫字母中有多少是命令,1表示不帶參數的,2表示不帶參數的。
int c[26] = {0};//當前的一行指令中有多少個命令,1表示不帶參數的,2表示不帶參數的。

//清空c數組
void clearc(){
	int i = -1;
	for(;++i<26;){
		c[i] = 0;
	}
}

//輸出結果
void displayc(){
	int i = -1,sum=0;
	string d[52]={""};
	for(;++i<26;){
		switch(c[i]){
		case 1:
			d[sum] = d[sum] + "-" + (char)(i+97);
			sum++;
			break;
		case 2:
			d[sum] = d[sum] + "-" + (char)(i+97);
			d[sum] = d[sum] + " " + a[i];
			sum++;
			break;
		};
	}
	for(i=-1;++i<sum-1;){
		cout<<d[i]<<' ';
	}
	if(sum>0){
		cout<<d[i];
	}
	cout<<endl;
}

int main(){
	string s,result;
	char str[256];
	int n;
	cin>>s;
	int i,index,j,ispara=0,k;
	//首先將不同的命令寫入b數組,作爲參考依據。
	for(i=s.length();--i>=0;){
		if(s[i] != ':'){
			index = (int)s[i] - 97;
			b[index] = 1;//1表示這個是個不帶參數的命令
			a[index] = "";
		}
		else{
			i--;
			index = (int)s[i] - 97;
			b[index] = 2;//2表示這個是個帶參數的命令
			a[index] = "";
		}
	}
	//指定輸入多少行指令
	cin>>n;
	//開始輸入一行又一行的指令
	for(j=-1;++j<=n;){
		//讀入空格的輸入,這個要注意的是由於前面cin>>n的時候已經有回車了所以會跳過一次,這個時候要注意不要有任何輸出。
		cin.getline(str,256);
		s.assign(str);
		ispara = 0;//這個忘了初始化了,CCF只能拿90分
		for(i=-1;++i<s.length();){
			//一直讀取到空格
			if(s[i] == ' '){
				//判斷當前是否是 讀取參數的狀態,0表示不讀取,1表示讀取
				switch(ispara){
				case 0://如果前面是不帶參的變量(不讀取參數的狀態)
					//判斷是否有'-'符號
					if(i+2<s.length() && s[i+1] == '-'){
						//跳過'-'符號直接讀取小寫字母
						i = i + 2;
						index = (int)s[i] - 97;
						//根據參考依據來判斷是否是命令
						switch(b[index]){
						case 1://如果該字母被賦值爲1,則說明是不帶參的變量
							c[index] = 1;
							break;
						case 2://如果該字母被賦值爲2,則說明是帶參的變量
							c[index] = 2;
							ispara = 1;//進入讀取參數的狀態
							break;
						case 0://0表示沒有這個指令,終止
							i = s.length();
							break;
						};
					}
					else{//如果不是'-'的命令狀態或已經到達了串尾,則終止
						i = s.length();
					}
					break;
				case 1://讀取參數的狀態
					for(k= i; i+1 < s.length() && s[i+1]!=' ';i++){}
					a[index] = s.substr(k+1,i-k);
					ispara = 0;
					break;
				};
			}
		}
		if(j>0){
			cout<<"Case "<<j<<": ";
			displayc();
			clearc();
		}
	}
	return 0;
}




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