Я пытаюсь понять, есть ли кто-нибудь, кто мог бы указать мне правильное направление. У меня есть программа, которая производит массив логических значений, которые состоят из false (0) или true (1). Вот так: [0,0,0,1,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,1,1,0,0,1,0]. Этот массив обычно имеет длину от 50 до 400. Вместо того, чтобы показывать весь массив конечному пользователю, я хочу сделать его более «читабельным». Одна из вещей, которые я должен сделать, это разбить на меньшие повторяющиеся фрагменты массивов, которые показывают, сколько раз это должно повторяться (от 1 до n раз). Я приведу некоторые примеры:

Пример № 1 простой:

Before: [1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1] 
After: [1,0,1]*7 time, 

Пример № 1 более сложный:

Before: [1,1,1,0,1,1,0,1,1,0,1,1,0,1,0,0,1,0,1,1,0,1] 
After: [1,1]*1 time, [1,0,1]*4 times, [0,0] *1 time, [1,0,1]*2 times

Как видно из примеров, как до, так и после, на самом деле это один и тот же, но только другой способ печати.

Помните, что в моей программе я могу иметь большие массивы (размер до 400). И часто намного проще распечатать (для пользователя) [1,0,1,1] * 55, чем [1,0,1,1, ... <длинный массив> ..., 1,0, 1,1 ]

Редактировать: Основная цель - сделать массив проще для чтения, так как он будет читаться 1 на 1 (человеком).

So '01'*22 rather than '01010101010101010101010101010101010101010101'

И также я предпочел бы более высокое число умножения, а не низкое.

'01'*22 is better than '0101'*11 which is better than '010101'*7 + '01'*1

-4
Christian 17 Май 2020 в 09:50

3 ответа

Лучший ответ

Это может работать для большинства случаев ..

let largeArray = [1,1,1,0,1,1,0,1,1,0,1,1,0,1,0,0,1,0,1,1,0,1];
let maxSubSize = 5;//change this value! for chunk size.
document.getElementById("input").innerHTML = JSON.stringify(largeArray);
function patternMatch(a,b){
	if(a.length == b.length){
  	let i;
  	for(i=0; i< a.length;i++){
    	if(a[i] != b[i])
    	  return false;
    }
  	return true;
  } else {
    return false;
  }
}

function checkPattern(tArray,index,pattern){
	let score = 0;
	for(let i = index;i < tArray.length-pattern.length+1;i+= pattern.length){
  
    	if( patternMatch(tArray.slice(i,i+pattern.length),pattern) )
        	score++;
        else
        	break;
    }
    return score;
}


function bakeResult(largeArray) {
  let result = [];
  for(let i = 0; i < largeArray.length;i++){
    let pattern = [];
    let bestScore = -1;
    let bestPattern;
    for(let j= i;j < i+maxSubSize;j++){
    	pattern.push(largeArray[j]);
      let score = checkPattern(largeArray,j+1,pattern);
    	if(score > bestScore) {
          bestPattern = pattern.slice(0);
          bestScore = score;
      }
    }

    i += (bestScore+1)*bestPattern.length-1;
    //console.log("start",tArray[i],i);
    result.push({pattern:bestPattern,count:bestScore+1})
  }
  return result;
}

function reverseResult(result){
  result = result.reverse();
  for(let i =0; i < result.length;i++){
    result[i].pattern = result[i].pattern.reverse();
  }
  return result;
}



function drawResult(result){
	for(let i= 0; i < result.length;i++){
    	let tstr = "";
    	let pattern = result[i].pattern;
        for(let j=0; j < pattern.length;j++){
        		tstr += pattern[j]+"";
        }
       
        tstr += " - "+ result[i].count + " times";
        document.getElementById('result').innerHTML += "<button>"+tstr+"</button>"
    }
    //document.getElementById('result').innerHTML += "<hr>"
}
let result = bakeResult(largeArray);

tresult = bakeResult(largeArray.reverse());
tresult = reverseResult(tresult);
if(result.length < tresult.length){
  drawResult(result);
}else{
  drawResult(tresult);
}
body {
  background: white;
  color: #323232;
  font-weight: 300;
  height: 100vh;
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  font-family: Helvetica neue, roboto;
}

img {
  width: 56px;
  height: 48px;
}

h1 {
  font-weight: 200;
  font-style: 26px;
  margin: 10px;
}
<div>
  <div id="input">
  </div>
  
  <h2>=</h2>
  <div id="result">

  </div>
</div>

Это решение работало для примеров случаев ...

Предварительный просмотр Codepen

2
Sankalp Bhamare 28 Май 2020 в 09:12

Вы будете перебирать массив / строку с конца и сохранять для каждого шага оптимальное решение. Наконец возьмите первый элемент массива.

Это работает и с большими данными.

function getChunks(data) {

    function same(position, size) {
        for (let i = 0; i < size; i++) {
            const right = offset + i + position * size;
            if (right >= data.length || data[offset + i] !== data[right]) return false;
        }
        return true;
    }

    function add(offset, patternSize, count) {
        let result = chunks[offset],
            temp = data.slice(offset, offset + patternSize) + '<' + count,
            product = patternSize * count,
            score = patternSize * ((count - 1) || 0.5),
            size = patternSize;

        if (offset + product < data.length) {
            let chunk = chunks[offset + product];
            score += chunk.score;
            temp += '|' + chunk.result;
            size += chunk.size;
        }

        if (!result) {
            chunks[offset] = { result: temp, score: 0.5, size };
            return;
        }
        if (result.score < score || result.score === score && size < result.size) {
            chunks[offset] = { result: temp, score, size };
        }
    }

    var chunks = [],
        offset = data.length;

    while (offset--) {
        let patternSize = data.length - offset + 1;

        while (--patternSize) {
            let count = 0;
            while (same(++count, patternSize)) add(offset, patternSize, count);
            add(offset, patternSize, count);
        }
    }
    return chunks[0].result;
}

console.log(getChunks('11101110111101111000010011110001100'));
console.log(getChunks('101101101101101101101'));
console.log(getChunks('1110110110110100101101'));
1
Nina Scholz 28 Май 2020 в 19:12

Я нашел способ сохранить порядок и сделать его более понятным для человека:

let bools = [0,0,0,1,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,1,1,0,0,1,0];
bools.push('');

let res = document.getElementById("res");

let formatted = "";
let trueOrFalse = bools[0];
let counter = 1;
let substring = "";

bools.forEach((element, index) => {
  if (trueOrFalse !== element) {
    
   if (counter === 1) {
      substring = `<span style="color: ${
        trueOrFalse === 0 ? "red" : "blue"
      }">${trueOrFalse}*1</span> `;
   }
        
    trueOrFalse = element;
    counter = 1;
    formatted += substring;
  } else {
    counter++;
    substring = `<span style="color: ${
      trueOrFalse === 0 ? "red" : "blue"
    }">${trueOrFalse}*${counter}  </span> `;
  }
});

res.innerHTML = formatted;
<div id="res">Calculating...</div>

Кроме того, создан кодовый блок: https://codepen.io/IDONNHAVE/pen/pojmdMm

Если у вас есть какие-либо вопросы относительно кода, я помогу вам.

PS: пожалуйста, прости мои именования переменных

0
Buda Örs 27 Май 2020 в 10:10