您的位置:首页 > 其它

算法导论:字符统计问题

2015-05-07 19:27 190 查看
  在ACM之家看到一道有趣的算法题,好多类似华为,Google等IT巨鳄,都以此为模板来考察实习生。

  (1)华为的考题形式是:通过键盘输入一串小写字母(a~z)组成的字符串,编写一个字符串过滤程序,若字符串中出现多个相同的字符,将非首次出现的字符过滤掉。如,输入字符串“abacacde”,则输出的过滤结果为“abcde”。

  不是很难的问题,采用枚举法,一个二重循环就可搞定。示例代码如下:

package org.warnier.zhang.demo;

public class StringFilter {

public String filter(String origin) {
String result;
if (origin == null) {
result = null;
} else {
char[] chars = origin.toCharArray();
StringBuilder sb = new StringBuilder();

for (int i = 0; i < chars.length; i++) {
int j = 0;
for (; j < i; j++) {
if (chars[i] == chars[j]) {
break;
}
}
if (j == i) {
sb.append(chars[i]);
}
}
result = sb.toString();
}
return result;
}
}


  官网给出的解决方案更巧妙,如下翻译为了Java版:

  public String filter(String origin){
String result;
if(origin == null){
result = null;
}else{
/**
* 判断字符是否出现的标志;
*/
boolean[] flags = new boolean[26];
for(int i = 0; i < flags.length; i++){
flags[i] = false;
}
char[] chars = origin.toCharArray();
StringBuilder sb = new StringBuilder();
/**
* 判断字符是否第一次出现;
*/
for(int i = 0; i < chars.length; i ++){
if(false == flags[chars[i] - 'a']){
flags[chars[i] - 'a'] = true;
sb.append(chars[i]);
}
}
result = sb.toString();
}
return result;
}


  (2)Google的考题形式是:在一个字符串中找到第一个只出现一次的字符,如输入abaccdeff,则输出b。

  如果提前参见过华为面试的实习生是不是就要幸运的多了,在没有算法复杂度的要求下,上面的代码简单修改一下就搞定了。如,  

  public String filter(String origin) {
String result = null;
if (origin != null) {
char[] chars = origin.toCharArray();
for (int i = 0; i < chars.length; i++) {
for (int j = 0; j < i; j++) {
if (chars[i] == chars[j]) {
chars[i] = '0';
chars[j] = '0';
break;
}
}
}
for (int i = 0; i < chars.length; i++) {
if (chars[i] != '0') {
result = String.valueOf(chars[i]);
break;
}
}
}
return result;
}


  官网也给出了一种全新的解法,翻译为Java版如下:

public String filter(String origin){
String result = null;
if(origin != null){
/**
* 保存字符出现的次数;
*/
int[] flags = new int[26];
for(int i = 0; i < flags.length; i++){
flags[i] = 0;
}
/**
* 统计字符出现的次数;
*/
char[] chars = origin.toCharArray();
for(int i = 0; i < chars.length; i++){
flags[chars[i] - 'a']++;
}
for(int i = 0; i < flags.length; i++){
if(flags[i] == 1){
result = String.valueOf((char)('a' + i));
break;
}
}
}
return result;
}


  其实,官网给出的答案不难看出与上面华为考题解答的相似处。这从另一个角度说明,这道考题虽然华为,Google的考察角度不同,但是万变不离其宗,解题的过程中要拨开迷雾,看清本质。

  再者,官网的解题策略也是一种巧妙的思路,我曾在自己的一篇博客“分享:GenericCalendar工具类”中,采用类似上述“判断字符是否出现”,“保存字符出现次数”标志量的方式处理平,闰年二月天数的选择问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: