if elseの最適化の小思の試験問題

6755 ワード

タイトルには未知の数と値の数字があり、それらを3つに分けて、それぞれの和をできるだけ等しくするように要求されています.
構想
  • 配列を降順に並べ替える
  • は3つの配列を作成し、各配列の現在の和
  • を記録する.
  • の次の数は、現在の和の最小の配列に割り当てる.

  • バージョン1.0
          var arr = [5, 2, 6, 88, 6, 95, 15, 45, 22];
          //      
          arr = arr.sort(function(a, b) {
            return b - a
          });
          //     ,      
          var oneArr = [],
            twoArr = [],
            threeArr = [];
    //        
          oneArr.sum = 0;
          twoArr.sum = 0;
          threeArr.sum = 0;
          for(var i = 0; i < arr.length; i++) {
            if(oneArr.sum <= twoArr.sum) {
              if(oneArr.sum <= threeArr.sum) {
                oneArr.sum += arr[i];
                oneArr.push(arr[i]);
              } else {
                threeArr.sum += arr[i];
                threeArr.push(arr[i]);
              }
            } else {
              if(twoArr.sum <= threeArr.sum) {
                twoArr.sum += arr[i];
                twoArr.push(arr[i]);
              } else {
                threeArr.sum += arr[i];
                threeArr.push(arr[i]);
              }
            }
    
          }
          console.log('oneArr',oneArr,'twoArr',twoArr,'threeArr',threeArr);
    

    見苦しいと思います.一つはif elseの山が見苦しいです.もう一つはこの名前とデータ構造が見苦しいです.最適化してもらえませんか.
    バージョン2.0 switch+Math.min
          var arr = [5, 2, 6, 88, 6, 95, 15, 45, 22];
          arr = arr.sort(function(a, b) {
            return b - a
          });
          var oneArr = [],
            twoArr = [],
            threeArr = [],
            a = 0,
            b = 0,
            c = 0,
            item;
          for(var i = 0; i < arr.length; i++) {
            item = arr[i];
            switch (Math.min(Math.min(a,b),c)){
                case a:
                  a += item;
                  oneArr.push(item);
                    break;
                case b:
                b += item;
                twoArr.push(item);
                    break;
                case c:
                c += item;
                threeArr.push(item);
                    break;
            }
          }
          console.log('oneArr',a,oneArr,'twoArr',b,twoArr,'threeArr',c,threeArr);
    

    実際、考え方の変化でなければ、最適化の鍵はどのようにデータを格納するか、どのようにデータを設定するか、どのようにデータを取得するか、どのようにデータ間を連絡マークするかの問題である.私たちが望んでいる効果は分岐が少ないか、階層が浅いかです.
    明らかにoneArrとa,twoArrとb,threeArrとcの間には関連がある.このような連絡はバージョン1.0ではオブジェクトの属性で直接タグ付けされているが、直接は使えなかった.バージョン2.0ではswitchで連絡するが、実際にはデータ面から緊密につながっているわけではない.
    どのようにoneArrとaの2つの間を連絡する問題、aを通じてoneArrを探し当てる必要があります
    オブジェクトのようなデータ構造にはif else、例えばfatherが確かに存在する.son=>123、実はfather+['son']で123という値が見つかります.ここでfatherは空間(変数)と見なすことができ、'son'は条件、あるいは条件の結果と見なすことができる.
    思い出せない..オブジェクトバージョン...
    一つの問題を考えて、oneArrとaの2つの変数の間で、お互いに相手を見つけることができるようにしたいです.つまり、私がoneArrを見つけたとき、aを見つけることができて、aを見つけたとき、oneArrを見つけることができます.どうすればいいですか.
    第一の考え方は、両者の間の概念上の関係、すなわちアルゴリズム上の関係である.この問題では、aは実はoneArrの各項目の和である.したがって、oneArrによってaを算出することは可能であるが、逆に、aによってoneArrという配列を逆算出することはできない.
    第2の考え方は、オブジェクトのようなデータ形式を通じて、彼ら二人に連絡を与えることができる.
    //    oneArr   a      ,        
          var oneArr = [1,2,3];
          var a = {};
          oneArr.a = a;
          a.oneArr = oneArr;
    
    //         a         sum;
          a.sum = oneArr.reduce(function (a,b) {
            return a += b
          });
    

    しかし、このようなことはめったにないようです.ある角度から言えば、これは死の循環だからです.あるいはデッドサイクルを形成するやすい.
    より一般的なオブジェクト構造は、バージョン1.0の様子です.
         var obj = {};
         obj.arr = [1,2,3];
         obj.sum = oneArr.reduce(function (a,b) {
            return a += b
          });
    

    私は以前よくこのような構造で連絡を生むことを考えていたが、厳密にはarrはsumを見つけることができず、sumもarrを見つけることができず、objは彼ら二人を見つけることができ、sum、arrがobjを見つけることができれば、実際にはお互いを見つけることができる.しかし、この言語には存在しません.子は父を探しています.継承関係ではprototypeは見つかるが、一般オブジェクト関係では存在しない.
    あるいは、文字列によって間接的なつながりが生じるようなものもあるようです.
    var a = 'some';
    var arr[a] = [1,2,3];
    var sum[a] = 6;
    
    arr   sum         ,             'some',
     ,   'some'      ,           ,        .
    
    -------------------------------------------------
          ,     ,                .
    
    
          var objArr = {};
          var objSum = {};
          var keyArr = ['one','two','thr'];
          for(var i = 0; i < keyArr.length; i++) { //    
            objArr[keyArr[i]] = [];
            objSum[keyArr[i]] = 0;
          }        
          for(var i = 0; i < arr.length; i++) {
            item = arr[i];
            switch (Math.min(Math.min(objSum[keyArr[0]],objSum[keyArr[1]]),objSum[keyArr[2]])){
                case objSum[keyArr[0]]:
                  objSum[keyArr[0]] += item;
                  objArr[keyArr[0]].push(item);
                    break;
                case objSum[keyArr[1]]:
                objSum[keyArr[1]] += item;
                objArr[keyArr[1]].push(item);
                    break;
                case objSum[keyArr[2]]:
                objSum[keyArr[2]] += item;
                objArr[keyArr[2]].push(item);
                    break;
            }
          }
    

    Es 6にはmapのものが現れていますが、この文章の観点から言えば、mapがオブジェクトよりも優れているのは、オブジェクトの属性が文字列でなければならないことです.例えば、
     obj['some'] = 123;
    obj.mike         obj['mike']
      obj       ,              ,
           ,        toString     .
    
      
    
    obj[{}] = 111; /   
    obj[{}] /    111
    obj[{a:1}] /   111
    obj['[object Object]'] /      111,         111
          ,       toString   , 
           toString        '[object Object]',
    
      
    obj[[]] = 222; /   
    obj[''] /    222
       []    toString     ''
    Array      toString         join  .
    
      
    obj[1] = 333; /    1        Number
    obj[1] /   333    
    obj['1'] /   333         , 1      toString    .
    
    

    要するに、オブジェクトの後ろの値は文字列タイプでなければならない.mapは異なる、様々なタイプを識別することができ、参照値のアドレスを識別することができる.
          var m = new Map();
          /  
          var a = 1;
          var b = '1';
          m.set(a,'aaa');
          m.set(b,'bbb');
          /  
          m.get(a) ; /   'aaa'
          m.get(b) : /   'bbb'
          m.get(1) ; /   'aaa'
          m.get('1') : /   'bbb'
                  ,         toString     .
    
                   
          
          var a = [];
          var b = {};
          /   
          m.set(a,'ccc');
          m.set(b,'ddd');
          /   
          m.get(a) /   'ccc'
          m.get(b) /   'ddd'
          /     
          m.get([]) /   undefined
          m.get({}) /    undefined
                ,              ,
                     [],[],[]
                   ,            .
          
                      
          m.set([1,2],'quick');
          m.get([1,2]) /      quick    undefined
    
                map         key   ,
                           .  ,          .
    
                    ,             ,
              "  "            .
    
            
          var obj = {age : 18};
          m.set(obj,'mike');
          m.get(obj); /   mike ,    .
               obj
          obj.age = 19; /   , obj           ,          .
          m.get(obj); /    mike,     .
          
    

    振り返ってmapでこの問題を強引にカバーします