代码之家  ›  专栏  ›  技术社区  ›  CQM

排序两个关联数组/堆栈

  •  2
  • CQM  · 技术社区  · 6 年前

    我正在实施我设计的算法,并探索不同的方法

    这不是一个家庭作业问题,但我会像这样解释:假设一个商人在不同的日子购买了苹果库存,也在不同的日子出售了一些。我想要他们当前购买的加权平均时间戳。

    我将此数据对象存储为历元时间的时间戳字符串和苹果数量。我的数据集实际上在单独的数据集中包含购买和销售,如下所示:

    //buys
    var incomingArray = {
      "1518744389": 10,
      "1318744389": 30
    };
    
    //sells
    var outgoingArray = {
      "1518744480": 3,
      "1418744389": 5,
      "1408744389": 8
    };
    

    我希望结果只显示remainding incomingArray时间戳购买对。

    var incomingArrayRemaining = {
      "1518744389": 7,
      "1318744389": 17
    };
    

    您可以看到,在稍后的时间戳中,3个苹果有一个传出事务,因此从10中减去。在购买10之前有13笔传出交易,但在购买30之后,所以他们只从30中减去。

    注意,如果在10之后转移的数量超过10,则会从10和30中减去。苹果的数量永远不能少于0。

    首先,为了实现我的目标,我似乎需要知道有多少人实际上仍然拥有他们购买的地块。

    与后进先出法中的堆栈减法不同,这似乎更像是税务批次会计。这些地块本身必须独立处理。

    因此,我必须在传出数组中获取卖出的第一个索引的时间戳,并在传入数组中找到最近的买入时间戳

    以下是我尝试的内容:

    for (var ink in incomingArray) {
      var inInt = parseInt(ink);
    
      for (var outk in outgoingArray) {
        if (inInt >= 0) {
          var outInt = parseInt(outk);
    
          if (outInt >= inInt) {
            inInt = inInt - outInt;
            if (intInt < 0) {
              outInt = inInt * -1; //remainder
              inInt = 0;
            } //end if
          } //end if
        } //end if
      } //end innter for
    } //end outer for
    

    它是不完整的,嵌套for循环解决方案的计算时间已经很短。

    该函数只是尝试对交易进行排序,以便只剩下剩余余额,方法是从最近的传入余额中减去一个传出余额,然后将剩余余额携带到下一个传入余额中

    我觉得递归解决方案会更好,或者可能是我没有想到的更优雅的解决方案(javascript中的嵌套对象forEach访问器)

    在对它们进行排序之后,我需要实际使用加权平均法,我已经有了一些想法。

    首先排序,然后对剩余数量进行加权平均。

    无论如何,我知道StackOverflow上的javascript社区对寻求帮助特别苛刻,但我陷入了僵局,因为我不仅需要一个解决方案,而且需要一个计算效率高的解决方案,所以我可能会悬赏。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Jonas Wilms    6 年前

    您可以将对象转换为时间戳-值对数组。外向型可能是负面的。然后,您可以轻松地在时间戳之后对其进行排序,并按照自己的喜好进行累积:

     const purchases = Object.entries(incomingArray).concat(Object.entries(outgoingArray).map(([ts, val]) => ([ts, -val])));
    
     purchases.sort(([ts1, ts2]) => ts1 - ts2);
    

    现在,您可以迭代时间跨度,并在值增加时将增量存储在新数组中(新输入):

     const result = [];
     let delta = 0, lastIngoing = purchases[0][0];
    
     for(const [time, value] of purchases){
       if(value > 0){
        // Store the old
        result.push([lastIngoing, delta]);
        // Set up new
       delta = 0;
       lastIngoing = time;
      } else {
       delta += value;
      }
    }