[アルゴリズム]Lv.2文字列圧縮


データ処理の専門家になりたい「音声器」は、文字列を圧縮する方法を学んでいる.最近,文字列に連続的に現れる同じ値を文字数と繰返し値として表すことによって,より短い文字列に減少する簡単な無損圧縮法を学習した.
例えば、「aabbacc」については、「2 a 2 ba 3 c」と表すことができ(文字が1回繰り返されていない場合は1を省略する)、このような方式の欠点は、重複文字が少ない場合に圧縮率が低いことである.たとえば、文字列「abcabcdede」は完全に圧縮されません.この欠点を解決するために、「ピッチ」は、文字列を1つ以上の単位に切り取ることで圧縮し、より短い文字列として表す方法を探します.
たとえば、「abbcddababccdcdd」は、文字を1単位に切り取ると全く圧縮されず、2単位に切り取ると「2 ab 2 cd 2 ab 2 cd」と表すことができます.異なる方法で8単位でせん断および圧縮を行う場合、「2 abbcdcd」を使用して表すことができ、これは圧縮が最も短い方法である.
別の例は「abcabcdede」であり、文字を2単位に切り取って圧縮すると「abcabc 2 de」になり、3単位に切り取ると「2 abcdede」になり、この3単位が最も短い圧縮方法になります.3つの単位を切り取り、最後に残った文字列を貼り付けます.
圧縮する文字列sをパラメータとして指定する場合は、上述した方法に従って1つ以上の単位で文字列を切り取り、solution関数を完了して、表す文字列の中で最も短い長さを返します.
せいげんじょうけん
sの長さは1または1000以下である.
sは小文字のみからなる.
I/O例
s result
"aabbaccc" 7
"ababcdcdababcdcd" 9
"abcabcdede" 8
"abcabcabcabcdededededede" 14
"xababcdcdababcdcd" 17
I/O例説明
I/O例#1
文字列を1つの単位で切り取って圧縮する場合に最も短い.
I/O例#2
文字列を8単位で切り取って圧縮する場合が最も短い.
I/O例#3
文字列を3つの単位で切り取って圧縮する場合に最も短い.
I/O例#4
文字列を2つの単位で切断すると、文字列は「abcabcabc 6 de」になります.
文字列を3単位に切り取ると、「4 abcdededededededed」になります.
文字列を4単位に切り取ると、abcabcabc 3 dedeになります.
文字列を6単位で切断すると「2 abcabc 2 deded」となり、長さは最短14となる.
I/O例#5
文字列は、先頭から指定した長さで切り捨てなければなりません.
したがって、所与の文字列をx/abbcdcd/abbcdcdに切り取ることはできない.
この場合、最も短い長さは17であり、どうしても文字列を切り取っても圧縮されないためである.
私の答え
まず、ループ再帰、各文字列は1つ、2つ、3つです.
現在の文字列が次の文字列と同じ場合は、countを1つ追加します.
違う場合はsplitArrアレイでcount+strを押します.
countが1ならstrだけ押します.
このように押すとcountは1に再初期化されます.
このようにして作成したSplitArrをjoin文字列に変換し、CollectionLengArrに長さだけを入れてMathに変換します.CollectionLengthArr要素で最も高価な値をminで見つけて返します.
混同:
1. Math.Ceil(str.length/2)+1がsplitNum文字列の長さの半分より大きい場合
意味がないのでstr.length/2,+1は文字列が半分に分かれたときの圧縮文字列+1を求める.
2.文字列を1つ、2つ、3つの基準に分ける方法を検討した.
function solution(s) {
  const collectionLengthArr = [];
  let splitNum = 1;

  function makeCollectionLengthArr(str) {
    if (splitNum === Math.ceil(str.length / 2) + 1) return;

    const splitArr = [];
    let index = 0;
    let count = 1;

    for (let i = 0; i < str.length / splitNum; i++) {
      const splitStr = str.substring(index, index + splitNum);
      const nextSplitStr = str.substring(index + splitNum, index + splitNum + splitNum);
      
      if (splitStr === nextSplitStr) {
        count += 1;
      } else {
        if (count !== 1) {
          splitArr.push(`${String(count) + splitStr}`);
        }

        if (count === 1) {
          splitArr.push(splitStr);
        }

         count = 1;
      }

      index += splitNum;
    }
   
    collectionLengthArr.push(splitArr.join("").length);

    splitNum += 1;
    makeCollectionLengthArr(str);
  }
  
  makeCollectionLengthArr(s);

  return Math.min(...collectionLengthArr);
}
コードを整理していないので、後で解いたほうがいいです.