状态机编程思想(1):括号内外字符串统计
2017-12-01 15:55
281 查看
这是曾经的一个面试题,正好引出状态机编程思想。挺不错的一个例子。
左括号“(”
右括号“)”
下划线“_”
大小写字母构成的字符串(单字母也算作字符串)
该字符串组成有以下规则限定:
括号成对出现且不会嵌套,保证语法正确
字符串可以出现在括号内,也可以出现在括号外
各个字符串之间必须用下划线“_”隔开
括号外的字符串必须以下划线“_”为边界;括号内字符串的边界可以是下划线“_”,也可以是括号“(”、“)”
请解决问题:
括号内字符串个数
统计括号外最长字符串的长度
判定括号边界时需要保存之前的状态,而处理程序和判定状态逻辑往往混乱成一锅粥,难解难分
不同状态下的处理逻辑不同,这样对于大型问题,逻辑之间有可能产生耦合,甚至在不同状态间跳来跳去
还有效率问题,每次处理当前字符时还有同时处理左右相邻字符,工作量有冗余,效率降低
嗯,不信的话,可以自己按照上述最简单的思路实现一下,你就明白了。
有人说,复杂逻辑我不怕啊,细心就好。So...是时候请出我们的大侠--“状态机”了。
让我们用状态迁移图表示上面的问题(若看不清图,可以右键在新的标签页看,或者下载下来看):
我设置了两个状态,一个用来区分括号内外,一个用来区分是否是字母,从而进行不同的处理。
括号内外分成了两个子状态,这两个子状态是互斥的,因此他们内部的状态变量可以共用。
至于状态之间转移条件,直接看代码即可理解:
有没有感觉到很方便?思路更清晰了,效率也上去了。
注:状态机不同于设计模式中常说的状态模式。
就这么多吧,欢迎提出测试样例找bug,共同进步。
出处:http://www.cnblogs.com/xiaoxi666/p/7929347.html
题目描述
给定一个字符串,它由以下字符组成:左括号“(”
右括号“)”
下划线“_”
大小写字母构成的字符串(单字母也算作字符串)
该字符串组成有以下规则限定:
括号成对出现且不会嵌套,保证语法正确
字符串可以出现在括号内,也可以出现在括号外
各个字符串之间必须用下划线“_”隔开
括号外的字符串必须以下划线“_”为边界;括号内字符串的边界可以是下划线“_”,也可以是括号“(”、“)”
请解决问题:
括号内字符串个数
统计括号外最长字符串的长度
传统思路
我们拿到这个问题时,第一感觉往往是顺序遍历字符串,并检测左右相邻字符是否满足边界条件,从而进行分支处理。但是这样做有以下棘手之处:判定括号边界时需要保存之前的状态,而处理程序和判定状态逻辑往往混乱成一锅粥,难解难分
不同状态下的处理逻辑不同,这样对于大型问题,逻辑之间有可能产生耦合,甚至在不同状态间跳来跳去
还有效率问题,每次处理当前字符时还有同时处理左右相邻字符,工作量有冗余,效率降低
嗯,不信的话,可以自己按照上述最简单的思路实现一下,你就明白了。
有人说,复杂逻辑我不怕啊,细心就好。So...是时候请出我们的大侠--“状态机”了。
状态机思路
状态机是编译原理中的一种技术,学过电学的读者应该也在《数字电子技术》中用过它,归根结底,就是把复杂的问题逻辑化为一个一个的状态,我们处理问题的过程就是在各个状态之间不断迁移(包含自迁移),这样画出来的图就叫做状态迁移图,帮助我们把一锅难缠的粥转化为一张清晰的网。当然,这里不会深究状态机的概念,详情请自查(比如还有状态迁移表等等)。让我们用状态迁移图表示上面的问题(若看不清图,可以右键在新的标签页看,或者下载下来看):
我设置了两个状态,一个用来区分括号内外,一个用来区分是否是字母,从而进行不同的处理。
括号内外分成了两个子状态,这两个子状态是互斥的,因此他们内部的状态变量可以共用。
至于状态之间转移条件,直接看代码即可理解:
public class CountWords { final static int InBracket = 0;// 括号内 final static int OutBracket = 1;// 括号外 final static int IsLetter = 0;// 是字母 final static int NotLetter = 1;// 不是字母 public static void main(String[] args) { test("_yy_()()_(_apple_welcome)_ssjjjs_");//2,6 test("__()()_(_)__()_");//0,0 test("_ya_");//0,2 test("_yy_(_)(r)_(_wel_c_ome_k)_");//5,2 test("_yy_aa_");//0,2 test("_yy_(aaa_bb_c)()__yyyyy_");//3,5 test("(u)_()_(__)()_yy_()");//1,2 test("__(a_wwwww)");//2,0 test("__(_a_wwwww_)_____ddd____()()()()()()");//2,3 } public static void test(String str) { // 状态初始化 int state_INOUT = OutBracket; int state_letter = NotLetter; // 统计结果初始化 int outLengthOfLongestWord = 0; int outLengthOfCurrentWord = 0; int inNumsOfWord = 0; // 开始处理 for (int i = 0; i < str.length(); ++i) { // 取出当前字符 char c = str.charAt(i); // 根据括号设置状态:括号内、括号外 if (c == '(') { state_INOUT = InBracket; } if (c == ')') { state_INOUT = OutBracket; } // 括号内状态 if (state_INOUT == InBracket) { if (state_letter == IsLetter) { if (c == '_' || c == ')') { state_letter = NotLetter; } } else if (state_letter == NotLetter) { if (Character.isLetter(c)) { state_letter = IsLetter; ++inNumsOfWord; } } } // 括号外状态 else if (state_INOUT == OutBracket) { if (state_letter == IsLetter) { // System.out.println(c); if (c == '_' || c == '(') { if (outLengthOfLongestWord < outLengthOfCurrentWord) { outLengthOfLongestWord = outLengthOfCurrentWord; } outLengthOfCurrentWord = 0; state_letter = NotLetter; } else if (Character.isLetter(c)) { ++outLengthOfCurrentWord; } } if (state_letter == NotLetter) { if (Character.isLetter(c)) { state_letter = IsLetter; ++outLengthOfCurrentWord; } } } } System.out.println("括号内的字符串数:" + inNumsOfWord); System.out.println("括号外的最长字符串长度:" + outLengthOfLongestWord); System.out.println(); } }
有没有感觉到很方便?思路更清晰了,效率也上去了。
注:状态机不同于设计模式中常说的状态模式。
就这么多吧,欢迎提出测试样例找bug,共同进步。
出处:http://www.cnblogs.com/xiaoxi666/p/7929347.html
相关文章推荐
- 状态机编程思想(1):括号内外字符串统计
- 利用状态机编程思想求解统计英文句子中单词个数问题
- python基础编程_13_字符串中字母、空格、数字的统计
- 编程实现统计一行字符串中大小写字母,数字的个数
- JAVA编程思想-第十三章 字符串
- 用c语言编程 统计输入的一个字符串中每个字母出现的次数
- 字符串(编程思想)
- 实际的状态机编程思想例子
- 《Java 编程思想》第13章 字符串 笔记
- java编程思想-字符串
- 实际的状态机编程思想例子(zz)
- 编程. 已知字符串:"this is a test of java". 按要求执行以下操作: (1) 统计该字符串中字母s出现的次数 (2) 取出子字符串"test" (3) 用多种方式将本字
- 2014年2月8日 java编程思想 String字符串学习 面试题目回顾
- 面试编程题1:给定一个字符串,统计出每个字母出现次数
- 13字符串-Java编程思想
- Java编程,从文件中读取一行字符串,统计数字,英文字符,其他的个数。
- 引言_基于活动状态机架构的编程方法(状态化编程思想)(Statefulization Programming Method)
- Java编程思想_字符串
- Java 编程思想13章--字符串
- 怎样删除C/C++代码中的所有注释?浅谈状态机的编程思想