1. 程式人生 > >7-3 詞頻統計(30 分) 巧解

7-3 詞頻統計(30 分) 巧解

2018年8月15日 于山東

7-3 詞頻統計(30 分)

請編寫程式,對一段英文文字,統計其中所有不同單詞的個數,以及詞頻最大的前10%的單詞。

所謂“單詞”,是指由不超過80個單詞字元組成的連續字串,但長度超過15的單詞將只擷取保留前15個單詞字元。而合法的“單詞字元”為大小寫字母、數字和下劃線,其它字元均認為是單詞分隔符。

輸入格式:

輸入給出一段非空文字,最後以符號#結尾。輸入保證存在至少10個不同的單詞。

輸出格式:

在第一行中輸出文字中所有不同單詞的個數。注意“單詞”不區分英文大小寫,例如“PAT”和“pat”被認為是同一個單詞。

隨後按照詞頻遞減的順序,按照詞頻:單詞

的格式輸出詞頻最大的前10%的單詞。若有並列,則按遞增字典序輸出。

輸入樣例:

This is a test.

The word "this" is the word with the highest frequency.

Longlonglonglongword should be cut off, so is considered as the same as longlonglonglonee.  But this_8 is different than this, and this, and this...#
this line should be ignored.

輸出樣例:(注意:雖然單詞the
也出現了4次,但因為我們只要輸出前10%(即23個單詞中的前2個)單詞,而按照字母序,the排第3位,所以不輸出。)

23
5:this
4:is

這道題其實不難,只是有些東西題目並沒有給清楚。

坑:看輸出格式的提示裡 “注意“單詞”不區分英文大小寫” 這句話 ,你既然是在輸出格式裡寫出,就會指引我們往輸出不論是da'x大小寫都是正確的 結果呢?只有小寫過了,大寫卻沒過。

 

技巧:使用匹配攻破之。scanf

​
#define _CRT_SECURE_NO_WARNINGS
#include "bits/stdc++.h"
using namespace std;

struct stx {
	string t;
	int x;
}Px[100000+10];
int pxcnt = 0;
bool cmp(struct stx A, struct stx B) {
	if (A.x < B.x) return false;
	else if (A.x == B.x && A.t>B.t) return false;
	return true;
}
class newgame {
public:
	string t;
	map<string, int>KS;
	void run() {
		tsolve();
	}
private:
	void tsolve() {
		char PTS[5000];
		while (!strstr(PTS,"#")) {
			int numk = scanf("%800[A-Za-z0-9_#]", PTS); // 輸入匹配
			PTS[15] = 0;
			if (numk) {
				t = PTS;
				transform(t.begin(), t.end(), t.begin(), ::tolower); // 轉小寫
				if (strstr(PTS, "#")) t[t.size() - 1] = 0;
				if(t[0]!=0)	KS[t]++;
			}
			getchar();
		}
		printf("%d\n",KS.size());

		for (map<string, int>::iterator it = KS.begin(); it != KS.end(); it++) Px[pxcnt++] = { it->first,it->second };
		sort(Px, Px + pxcnt, cmp);
		int cdnum = KS.size()*0.1;
		for (int i = 0; i < cdnum; i++) {
			cout << Px[i].x << ":" << Px[i].t << endl;
		}
	}
};

int main() {

	newgame P;
	P.run();
	system("pause");
	return 0;
}

​

 

使用匹配時候務必小心死迴圈 造成這個原因是 scanf又接收了回車造成!!!需要加上getchar()