`

因练习正则而感受到丰富的解题思路

阅读更多

不久前,在正则上终于可以登堂入室了,因担心久不练习而使其荒废,就在百度知道中不时的为他人用正则解决一些问题而练习.

 

偶而,在解决同一问题时,看到别人以不同方式和思路时,不由的心中窃喜,又学到了一招!

 

写代码程序员们都会,可是能想出独特解决思路的可不是人人都能具备的.能学到别人的思路可谓是提升自己思维的一大助力.


现摘几个小例子来看看.


用正则表达式查分下面字符串,拆分成字符串数组

  2011-11-10 10:28 提问者:j00710 | 悬赏分:20 | 浏览次数:85次

String s = "aa[兴奋]啊啊天天][...]b[?]bb[棒棒冰";

得到结果

String[] result = {"aa","[兴奋]","啊啊天天]","[...]","b","[?]","bb[棒棒冰"};


这是百度上的一个提问,我在看到题目后简单一分析,其实也很简单,就是以[...]这种格式来拆分字符串.先看看别人是怎么答的.嗯有一解法为

 

 

arr=s.split("[");
for(arr){
  arr[i].split("]");
}

 

 

这种写法不是JAVA的,而且方法也有问题,以[来分割,再以]来分割,那会多分的,如:[[[abc]a,应该分成[[,[abc],a结果呢?,唉,惨不忍睹.

没有好的解法,那我就来写个.

我的第一种解决思路是,以全局的正则来匹配,匹配时分两种情况,如果有[...]格式,则以取前缀和匹配格式,如果没有,则取所有字符.这种JAVA的写法代码较长,但很实用.写出正则 (?:(.*?)(\\[[^]]*\\]))|(.+$) 这里有三个捕获型括号,可以取到各部分的值,再写出代码

 

String eg="(?:(.*?)(\\[[^]]*\\]))|(.+$)";
 Matcher m = Pattern.compile(eg, Pattern.CASE_INSENSITIVE).matcher(str);
ArrayList list = new ArrayList();
while (m.find()) {
            if(m.group(1)!=null)list.add(m.group(1));
            if(m.group(2)!=null)list.add(m.group(2));
            if(m.group(3)!=null)list.add(m.group(3));
}
System.out.println(list); 
 

 

测试,有乱码.晕,是带有双字节字符的,那就再加上个unicode支持吧,把Pattern.CASE_INSENSITIVE改成Pattern.CASE_INSENSITIVE|Pattern.UNICODE_CASE.

再测试,成功.


可这代码,感觉太多了.就又想了一个解决思路.在[...]格式的前后插入特殊字符,再以特殊字符分割,只是这个字符串里不能含有特殊字符了,这里我选用了[]

String[] result = str.replaceAll("(\\[[^]]*\\])", "[]$1[]").split("\\[\\]")
 

 

本来我想这已经是最简单的了,但后来一位回答者又给出了一种思路.

Pattern p = Pattern.compile("(?=\\[.*?\\])|(?<=\\])");
String[] items = p.split(s); 
 

 

(其实这个可以写成String[] ss = str.replaseAll((?=\\[.*?\\])|(?<=\\]));)


这种思路是以位置来分割,我的是以特殊字符来分割.虽然这个解法也有限制,对于右位置判断正确,但左位置限制了]

这三种方法各有优劣,第一种是代码量太多,但最准.第二种代码较少,但限制了字符串中不能有[]这种字符.第三种最简单,但限制也最大,只有在无]]时才会准确.

不管怎么样,又学了一招,可用位置来分割.


还有一个问题.


一道java编程题

检举 | 2011-11-12 14:19 提问者:低调de狂 | 悬赏分:30 | 浏览次数:52次

随便输入一段字符串,把出现次数最多的打印出来,如:aabbbbbbbbbcccdffff,就把b打印出来,用java代码实现


这个问题如果是以前我是会想到把字符串中的每个字符进行记数,但现在我会是想到用正则来解决,先看看别人的解法,其中一位的思路给了我新的启发.

第一种解法.

 // 转成字符数组处理
		char[] cArray = str.toCharArray();
		Map<Character, Integer> map = new HashMap<Character, Integer>();
		// 统计各字符出现次数
		for (char c : cArray) {
			Integer count = map.get(c);
			if (null == count) {//第一次在map中是不可能找到该字符串的,我们直接给Integer加1
				map.put(c, 1);
			} else {
				map.put(c, count + 1);//之后的都先取出出现的次数,在他的Integer基础上加1
			}
		}
		int maxCount = 0;
		char mostChar = '0';
		// 比较获得出现次数最多的字符
		for (Map.Entry<Character, Integer> entry : map.entrySet()) {//map类型的迭代
			if (entry.getValue() > maxCount) {
				maxCount = entry.getValue();
				mostChar = entry.getKey();
			}
		}
		// 打印出结果
		System.out.println(mostChar);
 

 

 

这位的思路是遍历字符数组,把每个不同的字符都放到map中,如果有重复的就对计数加1,最后再遍历记数算,找到出现最多次数的字符.


第二种的解法,这种解法对我触动很大.

char[] help = new char[26];
	   for(int i=0;i<src.length();i++)
		   help[src.charAt(i)-'a']++;
	   int maxtimes=0;
	   char res = 0;
	   for(int i=0;i<26;i++)
		   if(help[i]>maxtimes) {
			   maxtimes=help[i];
			   res=(char)('a'+i);
		   }
	   return res;
  

 

这位的思路是预先放好26个字节长的字符数组,第一次遍历字符串,将每个字符去减a字符,这样得到的数值就是字符数组的相对下标,再向数组中记数加1,最后遍历字符数组,找出最大数值的下标,加上a就是最长的字符.


我的解决思路是利用正则.

String s = "aabbbbbbbbbcccdffff";
		Matcher m = Pattern.compile("((.)\\2*)").matcher(s);
		String l = "";
		while (m.find()) {
			l = l.length() < m.group(1).length() ? m.group(1) : l;
		}
		System.out.println(l.charAt(0)); 
 

 

 


这里三种解法,第一种是最正统的,用的最多的.第二种是有限制的,只能是小写字母的字符串,但最有启发性,第三种是对于正则有熟练的掌握性


这里暂时先讲这两个问题,希望能引出更多解题思路的朋友.

 

3
2
分享到:
评论
4 楼 thoughtfly 2011-11-17  
nizhihe 写道
String s = "aabbbbbbbbbcccdffff";  
        Matcher m = Pattern.compile("((.)\\2*)").matcher(s);  
        String l = "";  
        while (m.find()) {  
            l = l.length() < m.group(1).length() ? m.group(1) : l;  
        }  
        System.out.println(l.charAt(0));  
这个有问题吧,计算的是最长连续字符串是那个字符,不是计算的最多的是那个字符

对,这种方法是计算连续长度的,要计算最多出现的,最好就是第一种方法,循环分析每个字符
3 楼 thoughtfly 2011-11-17  
yizhl 写道
如果有中文 abcdefgggggsss1123333555中国中国中国 。。。。像这样 第二种还会准确么?

他的那种解法是因题而做的,只对小写字母有效,可这种思路值的一学
2 楼 yizhl 2011-11-15  
如果有中文 abcdefgggggsss1123333555中国中国中国 。。。。像这样 第二种还会准确么?
1 楼 nizhihe 2011-11-15  
String s = "aabbbbbbbbbcccdffff";  
        Matcher m = Pattern.compile("((.)\\2*)").matcher(s);  
        String l = "";  
        while (m.find()) {  
            l = l.length() < m.group(1).length() ? m.group(1) : l;  
        }  
        System.out.println(l.charAt(0));  
这个有问题吧,计算的是最长连续字符串是那个字符,不是计算的最多的是那个字符

相关推荐

    正则表达式练习器,练习正则表达式的好工具

    正则表达式练习器,练习正则表达式的好工具

    正则表达式练习题

    自己总结的部分javascript的正则表达式练习,希望可以帮助大家,未完整版,随后追加

    正则练习器regex

    "正则练习器regex"是一个专门用于调试和学习正则表达式的实用工具,它提供了友好的界面和丰富的功能,帮助用户更好地理解和运用正则表达式。 正则表达式的基本概念: 1. 字符类:[]内包含的一组字符,如 `[abc]` ...

    Java正则表达式介绍和练习

    Java正则表达式介绍和练习Java正则表达式介绍和练习Java正则表达式介绍和练习

    正则表达式综合练习

    正则表达式(Regular Expression,简称regex)是用于匹配字符串的一种模式,它在IT行业中扮演着重要的角色,尤其是在数据处理、文本分析、爬虫技术等领域。正则表达式通过使用预定义的字符集和特殊符号,可以高效地...

    正则相关练习题

    正则相关练习题,学习完后,正则表达式提升一个level!

    用于练习正则表达式的java运行源码

    这个名为“正则表达式”的.java文件是专为初学者设计的练习资源,帮助他们理解和掌握正则表达式的基本用法。 在Java中,正则表达式通过`java.util.regex`包中的类来实现。主要涉及到以下几个核心类: 1. **Pattern...

    正则表达式练习器VBScript版

    通过"正则表达式练习器VBScript版",用户不仅可以熟悉正则表达式的基本语法,还能掌握更高级的技巧,如正向和负向前瞻、预查后查以及复杂的分组。这个练习器特别适合初学者和进阶者,让他们在实际操作中不断巩固和...

    正则表达式学习资料以及练习项目代码很多

    这个压缩包包含了丰富的正则表达式学习资源,适合有一定基础的初学者深入学习。 1. **基础概念** - **模式匹配**:正则表达式定义了一种模式,可以用来匹配符合该模式的字符串。 - **元字符**:如`.`代表任意单个...

    javascript正则表达式综合练习

    这篇博客“javascript正则表达式综合练习”可能是一个实践教程或示例集合,旨在帮助开发者提升在JavaScript中使用正则表达式的技能。通过链接访问(已提供但在此不展示)可以深入学习相关知识。 在JavaScript中,...

    正则表达式的网页练习器

    "正则表达式的网页练习器"是一个实用的在线工具,它帮助用户快速学习和实践正则表达式,通过交互式的方式检验正则表达式的正确性,从而在10秒内解决简单的正则编写问题。 一、正则表达式基本概念 1. 元字符:如 . ^...

    C#正则表达示练习器

    C#正则表达示练习器, C#正则表达示练习器

    正则表达式练习器

    通过使用正则表达式练习器,初学者可以系统地学习正则表达式,而经验丰富的用户也可以检验和优化自己的正则表达式技能,提升在实际项目中的应用能力。在编程、数据分析、Web开发等领域,掌握正则表达式都能带来显著...

    linux系统shell正则表达式-练习工具和教材

    三、正则表达式练习工具 1. Regex101(在线工具):提供实时测试和解释功能,便于学习和调试正则表达式。 2. RegExr(网页应用):同样具有实时测试和解析功能,还提供了代码生成器。 3. regexcrossword.com:以填字...

    正则表达式 练习 java

    正则表达式练习器 正则表达式是一种强大的字符串匹配工具,它可以帮助开发者快速地匹配和提取字符串中的特定模式。然而,要熟练掌握正则表达式并不是一件容易的事情。为此,本文提供了一个正则表达式练习器,通过这...

    正则表达式基础教程(内含正则表达是的练习器)

    正则表达式,简称为正则或regex,是一种模式匹配工具,用于在文本中查找、替换或提取符合特定模式的字符串。它广泛应用于编程语言、文本编辑器、搜索引擎以及各种数据处理工具中,是IT行业中不可或缺的基础技能之一...

    正则文法到DFA

    正则文法是一种描述语言的形式化方法,而DFA是一种简单的计算模型,用于识别这些文法定义的语言。 正则文法,也称为类型-3文法,是由E. N. Ginsburg在1966年提出的。这种文法包含四个元素:非终结符、终结符、起始...

    正则表达式 到 NFA

    这是编译原理的一个实验, 是把一个正则表达式转化为不确定有穷自动机NFA的算法程序,朋兴趣的朋友可以下载来看看哦. 一个正则表达式就是由普通字符(例如字符 a 到 z)以及特殊字符(称为元字符)组成的文字模式...

    正则表达式到dfa.rar

    而"正则表达式到dfa.zip"可能是更深入的资料,可能包括更多复杂的正则表达式转换示例、算法实现代码或者教学视频等。 学习正则表达式到DFA的转换对于理解正则表达式的内部机制非常重要,这有助于编写更高效的文本...

Global site tag (gtag.js) - Google Analytics