前幾天寫了一篇關於TopCoder上的習題的問題+代碼+簡評的文章,現在開始寫該系列的第二篇文章.
注意,這個系列會有三篇文章,是以前我做過的一次完整的SRM的套題,有250分題,500分題和1000分題,本篇文章將介紹500分題.之後我將不定期抽時間去參加最新的SRM,然後把題目和解答奉上:)
題目來源:SRM250 DIV2
層級:500Points
題目:
Problem Statement:
Problem Statement
For computers it can be hard to determine in which language a given text is written. A simple way to try to determine the language is the following: for the given text and for some sample texts, for which we know the languages, we determine the letter frequencies and compare these.
The frequency of a letter is the total number of occurrences of that letter divided by the total number of letters in the text. To determine this, we ignore case and non-letter characters.
Once the letter frequencies of the text and of a language are known, we can calculate the difference between the two. This difference we define by the sum of the squared differences of the frequencies:
The lesser this value, the closer text resembles that language. Compare text with each element of languages and return the (0-based) index of the language that has the smallest difference with text. In case of a tie, return the smallest index.
Definition
Class:
LanguageRecognition
Method:
whichLanguage
Parameters:
vector <string>, string
Returns:
int
Method signature:
int whichLanguage(vector <string> languages, string text)
(be sure your method is public)
Constraints
-
languages contains between 1 and 50 elements, inclusive.
-
Each element of languages has length between 1 and 50, inclusive.
-
text has length between 1 and 50, inclusive.
-
Each element of languages and text consists only of characters with ASCII value between 32 and 127, inclusive.
-
Each element of languages and text contains at least one letter ('A'-'Z' and 'a'-'z').
Examples
0)
{"This is an English sentence.",
"Dieser ist ein Deutscher Satz.",
"C'est une phrase Francaise.",
"Dit is een Nederlandse zin."
}
"In welke taal is deze zin geschreven?"
Returns: 3
The differences are 0.0385, 0.0377, 0.0430 and 0.0276, so the sentence is written in language 3, Dutch. Note that Dutch is somewhat similar to German, somewhat less similar to English and not similar to French.
1)
{"aaaaa","bbbb","ccc","dd","e"}
"xxx"
Returns: 0
In case of a tie, return the language with the smallest index.
2)
{"AABB","AaBb","A? B!","ab!@#$%"}
"ab"
Returns: 0
Ignore case and the non-letter characters.
/*
分析:在TopCoder或者ACM做題,最重要的是要看懂題目:(,這時,程式員才能真正的感受到英文的重要,因為不光是要看懂,更重要的是因為比賽是限時的,還需要看的快.本題的大致意思是要做個語言識別,當然實際上需要你做的可遠沒這個題目名字嚇人.具體描述是,給你幾個句子作為參選句子,然後給你一個句子作為需要識別的句子.你要選出這個句子是屬於上述句子中哪種類型的.判斷的依據就是根據字母出現的頻率來判斷,把各個字母出現頻率和減去上面每個句子的頻率和,值最小的,就是最接近的,則把該句子索引選出.這道題其實不難,關鍵在於理清思路,把需要實現的功能劃分成子函數來實現,最後就可以較輕鬆的完成.我的解題代碼如下:
*/
#include <iostream>
#include <string>
#include <stdio.h>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
using namespace std;
typedef vector<float> VEC_FLT;
class LanguageRecognition
{
public:
int lanNum;
VEC_FLT difs;
public:
int whichLanguage(vector <string> languages, string text)
{
int mostone = 0;
float smallest = 100;
float tmp;
VEC_FLT textFren;
VEC_FLT curFren;
textFren = GetVecOfString(text);
for(int i=0;i<languages.size();i++)
{
curFren = GetVecOfString(languages[i]);
tmp = GetDifferences(curFren,textFren);
cout<<tmp<<endl;
if(tmp<smallest) //如果更小,則換
{
smallest = tmp;
mostone = i;
}
}
return mostone;
}
float GetDifferences(VEC_FLT f1,VEC_FLT f2)
{
float returnValue = 0;
for(int i=0;i<26;i++)
{
returnValue+= (f1[i]-f2[i])*(f1[i]-f2[i]);
}
return returnValue;
}
VEC_FLT GetVecOfString(string str)
{
VEC_FLT returnFlt(26,0);
vector<int> letters(26,0);
int totalletters = 0;
for(int i=0;i<str.size();i++) //首先統計有效字母的總個數和分別數量
{
if(str[i]>=97&&str[i]<=122) //為非大寫的字母才統計
{
letters[str[i]-97]++;
totalletters++;
}
else if(str[i]>=65&&str[i]<=90) //為非小寫字母才統計
{
letters[str[i]-65]++;
totalletters++;
}
}
if(totalletters!=0)
{
for(int i=0;i<26;i++) //產生頻率
{
returnFlt[i] = letters[i]/(float)totalletters;
}
}
return returnFlt;
}
};
呵呵,是不是也不難呢?所以說,高分的題也不一定難,關鍵還是要理清思路,才能快速的解決.