AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 78322342
Accepted
Andrew Parks
Andrew Parks
Asked: 2024-04-14 08:16:24 +0800 CST2024-04-14 08:16:24 +0800 CST 2024-04-14 08:16:24 +0800 CST

Algoritmo eficiente para reordenação parcial

  • 772

Considere a seguinte matriz de objetos:

[
{v: 'a'},
{v: 'b'},
{v: 'c', ptr: 'b'},
{v: 'd', ptr: 'a'},
{v: 'e'},
]

Alguns dos objetos contêm uma ptrpropriedade, referenciando o vvalor da propriedade de um objeto que deve preceder diretamente. Dois objetos nunca tentarão preceder diretamente o mesmo objeto e nunca haverá um loop (por exemplo, a->b->c->a) no array.

Portanto, aqui estão dois possíveis rearranjos válidos dos objetos:

[
{v: 'e'},
{v: 'd', ptr: 'a'},
{v: 'a'},
{v: 'c', ptr: 'b'},
{v: 'b'},
]
[
{v: 'c', ptr: 'b'},
{v: 'b'},
{v: 'd', ptr: 'a'},
{v: 'a'},
{v: 'e'}
]

Não importa onde os objetos aparecem na saída, se não houver nenhuma ptrpropriedade que faça referência a eles. Tudo o que importa é que certos objetos precedam diretamente outros onde a ptrpropriedade o solicita.

Qual é um algoritmo razoavelmente eficiente para realizar esse tipo de rearranjo?

Embora seja garantido que os dados não contenham loops, o rearranjo deve ter cuidado para não entrar em um loop infinito onde fica reorganizando os objetos para sempre.

Observe que, embora esses exemplos usem strings para ve ptr, o aplicativo real envolverá elementos DOM como valores para ve ptrreferências. Portanto, a solução só deve ser capaz de comparar propriedades ve ptrigualdade.

javascript
  • 3 3 respostas
  • 77 Views

3 respostas

  • Voted
  1. Best Answer
    user2357112
    2024-04-14T08:48:35+08:002024-04-14T08:48:35+08:00

    Descubra quais objetos têm outro objeto apontando para eles. Então, para cada objeto que não possui outro objeto apontando para ele, adicione esse objeto e tudo na seguinte cadeia ptr à saída:

    let val_to_obj = new Map();
    let has_predecessor = new Set();
    for (let obj of arr) {
        val_to_obj.set(obj.v, obj);
        if ('ptr' in obj) {
            has_predecessor.add(obj.ptr);
        }
    }
    let res = [];
    for (let obj of arr) {
        if (has_predecessor.has(obj.v)) {
            continue;
        }
        while (obj !== undefined) {
            res.push(obj);
            obj = val_to_obj.get(obj.ptr);
        }
    }
    
    • 1
  2. Spencer May
    2024-04-14T09:29:16+08:002024-04-14T09:29:16+08:00

    Eu sei que isso foi respondido, mas ainda quero postar o meu: p

    Adicionadas mais algumas cadeias para teste também. A raiz de cada cadeia é onde a cadeia resultante se originará, portanto, mesmo que a cadeia que começa em c seja definida antes do g desencadeado, o último elemento i é a raiz da cadeia c, portanto, toda a sua cadeia está posicionada lá.

    var st = [
        {v: 'a'},
        {v: 'f', ptr: 'e'},
        {v: 'b', ptr: 'h'},
        {v: 'c', ptr: 'b'},
        {v: 'd', ptr: 'a'},
        {v: 'e'},
        {v: 'h'},
        {v: 'g'},
        {v: 'i', ptr: 'c'}
    ]
    
    function createChain(x) {
        let i = 0;
        while (i < x.length) {
            // if chaining
            if (x[i]?.ptr) {
                // find index of chained element
                let follows = x.findIndex(y => y.v == x[i].ptr);
                if (follows > -1) {
                    let offset = 0;
                    // search for already-chained elements with `follows`
                    while (x[follows+offset+1] && x[follows+offset]?.ptr == x[follows+offset+1].v) {
                        offset++;
                    }
                    // splicing elements before index requires an offset
                    i = follows < i ? i-offset : i;
                    // offset calculations were non inclusive of follows, +1
                    x.splice(i, 0, ...x.splice(follows, offset+1));
                    // reset index to offset end position
                    i += offset-1;
                }
            }
            i++;
        }
        return x;
    }
    
    console.log(createChain(st));

    • 1
  3. Alexander Nenashev
    2024-04-14T18:13:26+08:002024-04-14T18:13:26+08:00

    Colete itens ptre copie a entrada inserindo ptritens antes de seus alvos:

    const input = [
      {v: 'a'},
      {v: 'b'},
      {v: 'c', ptr: 'b'},
      {v: 'd', ptr: 'a'},
      {v: 'e'},
    ]
    
    const pres = input.reduce((r, item) => ('ptr' in item && r.set(item.ptr, item), r), new Map);
    
    const prefill = (item, r) => {
      const pre = pres.get(item.v);
      if(!pre) return;
      pres.delete(item.v);
      prefill(pre, r);
      r.push(pre);
    };
    
    const result = input.reduce((r, item) => ('ptr' in item || (prefill(item, r), r.push(item)), r), []);
    
    console.log(result);

    E uma referência:

    ` Chrome/123
    ----------------------------------------------------------------------------------------
    >                   n=6       |       n=60        |       n=600       |      n=6000     
    Alexander     â–  1.00x x1m 187 | â–  1.00x   x1m 613 | â–  1.00x x100k 472 | â–  1.00x x10k 558
    user2357112     1.33x x1m 249 |   2.82x x100k 173 |   3.39x  x10k 160 |   3.01x  x1k 168
    ----------------------------------------------------------------------------------------
    https://github.com/silentmantra/benchmark `
    

    let offset = 0;
    const $chunk = (offset++, [
      {v: 'a' + offset},
      {v: 'b' + offset},
      {v: 'c', ptr: 'b' + offset},
      {v: 'd' + offset, ptr: 'a' + offset},
      {v: 'e', ptr: 'f' + offset},
      {v: 'f' + offset, ptr: 'd' + offset}
    ]);
    
    const $input = [];
    
    // @benchmark user2357112
    let arr = $input;
    let val_to_obj = new Map();
    let has_predecessor = new Set();
    for (let obj of arr) {
        val_to_obj.set(obj.v, obj);
        if ('ptr' in obj) {
            has_predecessor.add(obj.ptr);
        }
    }
    let res = [];
    for (let obj of arr) {
        if (has_predecessor.has(obj.v)) {
            continue;
        }
        while (obj !== undefined) {
            res.push(obj);
            obj = val_to_obj.get(obj.ptr);
        }
    }
    res;
    
    // @benchmark Alexander
    
    const pres = $input.reduce((r, item) => ('ptr' in item && r.set(item.ptr, item), r), new Map);
    
    const prefill = (item, r) => {
      const pre = pres.get(item.v);
      if(!pre) return;
      pres.delete(item.v);
      prefill(pre, r);
      r.push(pre);
    };
    
    $input.reduce((r, item) => ('ptr' in item || (prefill(item, r), r.push(item)), r), []);
    /*@skip*/ fetch('https://cdn.jsdelivr.net/gh/silentmantra/benchmark/loader.js').then(r => r.text().then(eval));

    • 1

relate perguntas

  • classificação de mesclagem não está funcionando - código Javascript: não é possível encontrar o erro mesmo após a depuração

  • método select.remove() funciona estranho [fechado]

  • Sempre um 401 res em useOpenWeather () - react-open-weather lib [duplicado]

  • O elemento de entrada não possui atributo somente leitura, mas os campos ainda não podem ser editados [fechado]

  • Como editar o raio do primeiro nó de um RadialTree D3.js?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle?

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Quando devo usar um std::inplace_vector em vez de um std::vector?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Marko Smith

    Estou tentando fazer o jogo pacman usando apenas o módulo Turtle Random e Math

    • 1 respostas
  • Martin Hope
    Aleksandr Dubinsky Por que a correspondência de padrões com o switch no InetAddress falha com 'não cobre todos os valores de entrada possíveis'? 2024-12-23 06:56:21 +0800 CST
  • Martin Hope
    Phillip Borge Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle? 2024-12-12 20:46:46 +0800 CST
  • Martin Hope
    Oodini Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores? 2024-12-12 06:27:11 +0800 CST
  • Martin Hope
    sleeptightAnsiC `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso? 2024-11-09 07:18:53 +0800 CST
  • Martin Hope
    The Mad Gamer Quando devo usar um std::inplace_vector em vez de um std::vector? 2024-10-29 23:01:00 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST
  • Martin Hope
    MarkB Por que o GCC gera código que executa condicionalmente uma implementação SIMD? 2024-02-17 06:17:14 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve