자료 저장소

# map을 이용한 문장 생성 프로그램

map을 사용하여 문장 구조, 즉 문법을 정의하고, 그 정의된 문법을 만족하는 문장을 무작위로 생성하는 프로그램

makesentence.cpp
#include <iostream> 
#include <string>
#include <vector>
#include <algorithm>
#include <map>

usingnamespacestd;

typedef vector<string> Rule;
typedef vector<Rule> Rule_collection;
typedef map<string, Rule_collection> Grammar;

/* 인자가 공백문자이면 true, 그렇지 않다면 false를 리턴 */
bool space(char c)
{
return isspace(c);
}

/* 인자가 공백문자이면 false, 그렇지 않다면 ture를 리턴 */
bool not_space(char c)
{
return !isspace(c);
}

vector<string> split(conststring& str)
{
typedefstring::const_iterator iter;
vector<string> ret;
iter i=str.begin();

while(i!=str.end())
{
// 맨 앞의 빈칸을 무시
i=find_if(i, str.end(), not_space);

// 단어의 끝을 검색
iter j=find_if(i, str.end(), space);

// [i,j) 범위의 단어를 복사
if(i!=str.end())
ret.push_back(string(i,j));

// 다음 단어를 검색
i=j;
}
return ret;
}

Grammar read_grammar(istream& in)
{
Grammar ret;
string line;

while(getline(in, line))
{
vector<string> entry = split(line);

//
if(!entry.empty())
ret[entry[0]].push_back(Rule(entry.begin() + 1, entry.end()));
}
return ret;

}

int nrand(int n)
{
if(n<=0 || n>RAND_MAX)
throw domain_error("Argument to nrand is out of range");

constint bucket_size = RAND_MAX / n; // 32767 / 10 3276

int r;

do r=rand() / bucket_size;
while(r >= n); //

return r;
}

bool bracketed(conststring& s)
{
return s.size() > 1 && s[0] == '<' && s[s.size() -1] == '>';
}

void gen_aux(const Grammar& g, conststring& word, vector<string>& ret)
{
// 입력 string이 각괄호로 둘러쌓여있지 않다면 그 자체로 출력의 일부가 된다.
if(!bracketed(word))
{
ret.push_back(word);
}
else
{
Grammar::const_iterator it=g.find(word);

if(it == g.end())
throw logic_error("empty rule");

const Rule_collection& c = it->second;

const Rule& r = c[nrand(c.size())];

for(Rule::const_iterator i=r.begin(); i!=r.end(); ++i)
gen_aux(g,*i,ret);
}
}

vector<string> gen_sentence(const Grammar& g)
{
vector<string> ret;
gen_aux(g, "<sentence>", ret);
return ret;
}

int main()
{
vector<string> sentence = gen_sentence(read_grammar(cin));

vector<string>::const_iterator it=sentence.begin();

if(!sentence.empty())
{
cout<<*it;
++it;
}

while(it!=sentence.end())
{
cout<<" "<<*it;
++it;
}
cout<<endl;

return0;
}


댓글 로드 중…

최근에 게시된 글