【问题标题】:How to reorder an Array to avoid consecutive duplicates如何重新排序数组以避免连续重复
【发布时间】:2021-03-11 04:57:15
【问题描述】:

我有一个数字数组 [1,2,2,2,3,4,5]

我想要做的是对数组进行排序以避免连续相等的数字[1,2,3,2,4,2,5]。但我不想从数组中删除任何数字,在更糟糕的情况下,当重复的数字多于其他数字时,我想将那些无法合并的数字放入其他数组中。

const original = [1,2,2,2,2,2,2,3,4];
const merged = [];
const rest = [];

例如 [1,2,2,2,2,2,2,3,4] 预期的结果应该是 [2,1,2,3,2,4,2] 和另一个数组 [2 ,2] 在原始数组中我有 6 次 2 并且我能够合并其余 6 个中的 4 个

    const original = [1,2,2,2,2,2,2,3,4];
    const merged = [2,1,2,3,2,4,2];
    const rest = [2,2];

我试图玩这个算法,但没有办法得到尊重的结果,这个算法会删除重复项

const testArr = [1, 1, 2, 2, 3, 3, 1, 1, 1];
const compress = (arr, len = 0, canDelete = false) => {
   if(len < arr.length){
      if(canDelete){
         arr.splice(len, 1);
         len--;
      }
      return compress(arr, len+1, arr[len] === arr[len+1])
   };
   return;
};
compress(testArr);
console.log(testArr);

您知道解决此类问题的最佳方法是什么吗?

【问题讨论】:

  • 我绝对不明白 2,1,2,3,2,4,2 是如何从您的源表中获得的...无论如何我希望 1 成为结果的第一个元素...
  • 只有一个值是重复的吗?如果是这样 - 它更简单。
  • 我觉得我有一个想法,让我努力奋斗吧
  • 取最常出现的元素。如果数组长度超过一半,则需要删除一些,否则您总是可以通过简单地在不同元素之间交替来找到解决方案。
  • 顺便说一句,这不是排序算法,因为你最终不会得到有序的元素。

标签: javascript node.js arrays algorithm duplicates


【解决方案1】:

这是一个非常有趣的问题,这是我的解决方案:


const original = [1,2,2,2,2,3,3,2,2,2,3,4]
console.log("Before: ", original)

let object_keys = {}

//Step 1: map all the values and how many times it duplicated
for(let val of original){
  if(object_keys[val]){
    object_keys[val]++
  }else{
    object_keys[val] = 1
  }
}

console.log(object_keys) // { '1': 1, '2': 7, '3': 3, '4': 1 }

//Step 2: Run over the object and create a new array. the method is each iterate, append new key

const get_the_most_duplicated_val = (object_keys, except) => {
  let max = 0
  let key = ''
  for(let v in object_keys){
    if(object_keys[v] > max && !except.includes(v)){
      max = object_keys[v]
      key = v
    }
  }
  return key
}

let merged = []
let rest = []

let merged_is_completed = false
while(!merged_is_completed){

  const append_val = (key) => {
    merged.push(key)
    object_keys[key]--
    if(object_keys[key] == 0){
      delete object_keys[key]
    }
  }

  const last_val = () => {
    return merged[merged.length - 1]
  }

  let most_key = get_the_most_duplicated_val(object_keys, [])
  append_val(most_key)
  let most_key2 = get_the_most_duplicated_val(object_keys, [most_key])
  append_val(most_key2)

  if(Object.keys(object_keys).length == 1){
    if(last_val() != Object.keys(object_keys)[0]){
      append_val(Object.keys(object_keys)[0])
    }
    for(let i=0;i<object_keys[Object.keys(object_keys)[0]];i++){
      rest.push(Object.keys(object_keys)[0])
    }
    merged_is_completed = true
  }
}
console.log("Merged: ", merged)
console.log("Rest: ", rest)

我把它放在 Codepen 里,你可以自己测试一下 :) https://codepen.io/gofmannir/pen/vYXEmPa?editors=0011

【讨论】:

  • 感谢 Nir ​​抽出宝贵时间,我只是在 codepen 中试了一下,效果很好。
【解决方案2】:

是一个有趣的任务,我只是写了一点代码,它不能完美运行,但你可以改进它。

const insert = (el, result) => {
    if (el !== result.merged[result.merged.length - 1]) {
        result.merged.push(el);
        if (result.rest.length !== 0) {
            for (let i = 0; i < result.rest.length; i++) {
                let restItemToInsert = result.rest[i];
                if (result.merged[result.merged.length - 1] !== restItemToInsert) {
                    result.merged.push(restItemToInsert);
                    result.rest.splice(i, 1);
                }
            }
        }
    } else {
        result.rest.push(el);
    }
    return result;
}

const recursive = (arr) => {
    let el = arr.shift();
    return arr.length === 0 ? { rest: [], merged: [el]} : insert(el, recursive(arr));
}

const testArr = [1, 1, 2, 2, 3, 3, 1, 1, 1];
const testArr2 = [1, 1, 1, 1, 3, 3, 1, 1, 1];
const original = [1,2,2,2,2,2,2,3,4];
console.log(recursive(original));
console.log(recursive(testArr));
console.log(recursive(testArr2));

如果你运行代码,你应该得到类似的东西。

{ rest: [ 2, 2, 2, 2 ], merged: [ 4, 3, 2, 1, 2 ] }
{ rest: [], merged: [
    1, 3, 1, 3, 1,
    2, 1, 2, 1
  ] }
{ rest: [ 1, 1, 1, 1 ], merged: [ 1, 3, 1, 3, 1 ] }

您可以看到,对于您的const original = [1,2,2,2,2,2,2,3,4];,它没有给出正确的答案。但是你可以改进它并让它发挥作用。

更新

我写了一个更好的插入函数,这应该适用于您示例中的任何数组。

const insert = (el, result) => {
    result.rest.unshift(el);
    for (let i = 0; i < result.rest.length; i++) {
        let restItem = result.rest[i];
        for (let j = 0; j < result.merged.length; j++) {
            let mergedItem = result.merged[j];
            if(mergedItem !== restItem) {
                if (result.merged[result.merged.length - 1] !== restItem) {
                    result.merged.push(restItem);
                    result.rest.splice(i, 1);
                    i = -1;
                    break;
                } 
                
                if(result.merged[0] !== restItem) {
                    result.merged.unshift(restItem);
                    result.rest.splice(i, 1);
                    i = -1;
                    break;
                }

                if (result.merged[j + 1] && result.merged[j + 1] !== restItem) {
                    result.merged.splice(j + 1, 0, restItem);
                    result.rest.splice(i, 1);
                    i = -1;
                    break;
                }            
            }
        }
    }
    return result;
}

【讨论】:

  • 谢谢,eh8 抽出时间,我会改进的!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-21
  • 1970-01-01
  • 2020-06-27
  • 2021-09-08
  • 1970-01-01
  • 2018-09-26
  • 1970-01-01
相关资源
最近更新 更多