西西软件园多重安全检测下载网站、值得信赖的软件下载站!
软件
软件
文章
搜索

首页编程开发其它知识 → Loglan逻辑综合可发音语言

Loglan逻辑综合可发音语言

相关软件相关文章发表评论 来源:本站整理时间:2010/8/23 9:59:54字体大小:A-A+

作者:佚名点击:48次评论:0次标签: 逻辑 验证 语法

  • 类型:其它游戏大小:677KB语言:英文 评分:5.0
  • 标签:
立即下载
4 页 Loglan问题解决方案
Solution
解答
view sourceprint?01 #include <iostream>

02 #include <string>

03 #include <vector>

04 using namespace std;

05 //各种符号的枚举,后面的注释为题目中对应的符号

06 enum SYMBOL{A, MOD, LA, BA, DA, PREDA, NAM, SE, PC, P, PN, PS, ST, VP, PV, UN};

07 bool aVowel[] = {1,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0}; //元音表

08 static SYMBOL aConvTbl[14][4] = { //状态转换表

09 {PREDA, UN, PREDA, PREDA}, {PREDA, UN, UN, PS}, {NAM, UN, UN, PN},

10 {LA, UN, PS, PN}, {MOD, UN, PS, VP}, {A, PS, PS, PS}, {PS, UN, UN, P},

11 {DA, UN, P, PC}, {BA, PN, P, PC}, {VP, PN, UN, PV}, {PV, UN, PN, ST},

12 {PV, UN, UN, ST}, {PC, UN, UN, SE}, {ST, UN, UN, SE},

13 };

14 //判断是否元音字母的函数

15 inline bool isvowel(char c) {

16 return islower(c) && aVowel[c - 'a'];

17 }

18 //将输入的字符串转为状态

19 SYMBOL Token2Status(const string &str) {

20 int nNum = str.length();

21 if (!isvowel(str[nNum - 1])) {

22 return NAM; //末尾不是元音的为NAM

23 }

24 switch (nNum) {

25 case 1: return A; //只有一位元音的只能是A

26 case 5: //用位运算快速判断谓词是否符合规则CCVCV或CVCCV

27 nNum = isvowel(str[4]);

28 nNum |= ((isvowel(str[0]) << 4) | (isvowel(str[1]) << 3));

29 nNum |= ((isvowel(str[2]) << 2) | (isvowel(str[3]) << 1));

30 return (nNum == 5 || nNum == 9) ? PREDA : UN;

31 case 2: //两位的单词

32 switch (str[0]) { //根据第一位判断是哪一组

33 case 'g': return MOD;

34 case 'b': return BA;

35 case 'd': return DA;

36 case 'l': return LA;

37 }

38 }

39 return UN; //未能识别的错误符号

40 }

41 //词法分析函数,算法过程详见相关文档

42 bool ParseSentence(vector<SYMBOL> &Set) {

43 for (int i = 0; i < 14; ++i) { //依次处理每一种状态

44 SYMBOL *pTbl = aConvTbl[i]; //为加快运算,节省代码,设临时变量

45 for (vector<SYMBOL>::iterator j = Set.begin(); j != Set.end();) {

46 if (*j != pTbl[0]) {

47 ++j; //不是指定符号,遍例下一个

48 continue;

49 } //如果指定了前面或后面相邻的符号则验证其是否存在

50 if (pTbl[1] != UN && (j == Set.begin() || *(j - 1) != pTbl[1])) {

51 ++j; //存在的符号与指定的不符,结果错误

52 continue;

53 }

54 if (pTbl[2] != UN && (j == Set.end() - 1 || *(j + 1) != pTbl[2])) {

55 ++j; //存在的符号与指定的不符,结果错误

56 continue;

57 } //删除前后的符号(如果指定)

58 j = pTbl[1] != UN ? Set.erase(j - 1) : j;

59 j = pTbl[2] != UN ? Set.erase(j + 1) - 1 : j;

60 *j = pTbl[3]; //当前符号变更为指定的目标符号

61 }

62 }

63 return (Set.size() == 1 && Set.front() == SE); //返回结果

64 }

65 //主函数

66 int main(void) {

67 vector<SYMBOL> Set;

68 for (string str; cin >> str && str != "#";) { //循环读入每个单词

69 int nDot = str.find('.'); //如果单词中发现句点,则认为句子结束

70 if (nDot == str.npos) { //没有发现句点

71 Set.push_back(Token2Status(str)); //将单词转为符号后存入语句

72 continue;

73 } //以下为发现句点,即遇到句子结束

74 str.erase(str.length() - 1); //删除句点

75 if (!str.empty()) { //单词不为空则加入语句

76 Set.push_back(Token2Status(str));

77 } //以下进行词法分析并输出结果

78 cout << (ParseSentence(Set) ? "Good" : "Bad!") << endl;

79 Set.clear(); //清空语句,准备处理下一条语句

80 }

81 return 0;

82 }<BR>

    相关评论

    阅读本文后您有什么感想? 已有人给出评价!

    • 8 喜欢喜欢
    • 3 顶
    • 1 难过难过
    • 5 囧
    • 3 围观围观
    • 2 无聊无聊

    热门评论

    最新评论

    发表评论 查看所有评论(0)

    昵称:
    表情: 高兴 可 汗 我不要 害羞 好 下下下 送花 屎 亲亲
    字数: 0/500 (您的评论需要经过审核才能显示)