Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
348 views
in Technique[技术] by (71.8m points)

做了一题JS面试题,写的很不好,寻求更好的方法

题目:


2017/3/16 16:11 更新

非常感谢各位大大的回答,真的非常感动,每个答案我会一个一个看过去,正在努力学习中...


实现一个算法,寻找字符串中出现次数最少的、并且首次出现位置最前的字符。如cbaacfdeaebb,符合要求的是f,因为他只出现了一次(次数最少)。并且比其他只出现一次的字符(如d)首次出现的位置最靠前。

下面是我的写法,小弟没学过数据结构与算法,半路出家,基础不好,写的太烂了,效率无比低下,希望有各位大大能够给出一些更好的写法。

我的写法:

var str = "cbaacfdeaebb";
var arr = str.split('');

// 各元素以及对应出现的次数
var res = arr.reduce(function (obj, key, index, arr) {
    if(obj.hasOwnProperty(key)) {
        obj[key] ++;
    } else {
        obj[key] = 1;
    }
    return obj;
}, {}); 

// 次数组成的数组
var indexArr = []; 

for(var prop in res) {
    indexArr.push(res[prop]);    
}

// 找出出现次数最少的数
var minTimes = Math.min.apply(null,indexArr);

// 出现次数最少元素的数组
var eleArr = [];

for(var p in res) {
    if(res[p] === minTimes) {
        eleArr.push(p); 
    }
}

console.log(eleArr[0])

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

斗胆来评价一下诸位大神的答案。。。

@莲_涳栢__ :

var o = [].reduce.call('cbaacfdeaebb',function(p,n){
          return p[n] = (p[n] || 0) + 1,p;
       },{}),
   s = Object.keys(o).reduce(function(p,n){
       return o[p] <= o[n] ? p : n;
   });
   console.log(s,o[s]); 

正统的Hash Table思路。缺点是Object.keys()不能保证顺序,所以存在风险。


@边城 :

const all = "cbaacfdeaebb".split("")
    .reduce((all, ch, i) => {
        const m = all[ch] || (all[ch] = { ch: ch, index: i, count: 0 });
        m.count++;
        return all;
    }, {});

const theOne = Object.keys(all)
    .map(ch => all[ch])
    .reduce((min, t) => min.count === t.count
        ? (min.index > t.index ? t : min)
        : (min.count > t.count ? t : min));

console.log(`${theOne.ch}: ${theOne.count}`);

引入了index来解决顺序问题,比较健康和简练。


@u3u

function findFirstChar(string) {
  const desc = [];
  [...string].forEach((char, index) => {
    const item = desc.find(item => item.char === char)
    item ? item.count++ : desc.push({ char, index, count: 1 })
  })
  return desc.sort((a, b) => a.count - b.count)[0]
}

利用数组代替Hash Table,解决了顺序问题,思路不错。
但是Array.sort()并不一定是stable的,这个造成的风险更大。


@hsfzxjy

const less = (x, y) => x.count <= y.count && x.first < y.first

function firstSingle (string) {
  let map = {}
  string.split('')
    .forEach((char, index) => {
      if (map[char]) 
        map[char].count++
      else
        map[char] = { count: 1, first: index, char }
    })
  return Object.values(map).reduce((x, y) => less(x, y) ? x : y).char
}

思路相似,利用Hash Table,并引入了index解决顺序问题。
ES2017还没有正式发布,Object.values目前还是草案。
另外原谅我强迫症重新排个版:

const less = (x, y) => (x.count <= y.count && x.first < y.first) ? x : y;

function firstSingle (string) {
  let map = {}
  string.split('')
        .forEach((char, index) => {
            map[char] ? map[char].count++ : map[char] = { count: 1, first: index, char } 
        });
  return Object.values(map).reduce(less).char
}

最后是我的two cents:

var str = "cbaacfdeaebb";

var result = [...new Set(str)]
            .map(el => ({el, len: str.split(el).length}))
            .reduce((a,e) => (a.len > e.len ? e : a))
            .el;

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...