Первая очевидная ошибка, которую я вижу, это let repeatCount = s.match(/[repeatRegex]/gi).length;
. То, что вы действительно хотите сделать, это:
let repeatRegex = new RegExp(repeatingChar(s)[0], 'g');
let repeatCount = s.match(repeatRegex).length;
Следующим является то, что вы смотрите только на один из повторяющихся символов, а не на всех, поэтому вы не получите блоки правильной формы, поэтому вам нужно l oop над ними.
let repeatedChars = repeatingChar(s);
for(let c of repeatedChars)
{
//figure out blocks
}
Когда вы строите блок, вы решили сосредоточиться на всем, что не "а". Я предполагаю, что это не то, что вы изначально написали, а какой-то отладочный код для работы с этим одним примером ввода.
Если я правильно понимаю ваше желание, вы хотите взять все неповторяющиеся символы и smoo sh их вместе, затем возьмите первый экземпляр первого повторяющегося символа и прочее, что находится впереди, а затем втисните оставшиеся экземпляры повторяющегося символа сзади, разделенные -
.
Проблема здесь является то, что первый повторяющийся символ может не быть тем, который должен быть первым в результате. По сути, вам повезло с повторяющимся символом a
.
Исправляя ваш код, я бы создал массив и собрал блоки по отдельности, а затем соединил бы их все вместе в конце.
let repeatedChars = repeatingChar(s);
let blocks = []
for(let c of repeatedChars)
{
let repeatRegex = new RegExp(c, 'g');
let repeatCount = s.match(repeatRegex).length;
for(let i = 1; i <= repeatCount; i++)
{
if(blocks.length < i)
{
let newBlock = [c];
blocks.push(newBlock);
}
else
{
block[i - 1].push(c);
}
}
}
let tailBlocks = blocks.map(block => block.join('')).join('-');
Однако, это оставляет меня с проблемой, как построить окончательную строку с включенными неповторяющимися символами, все в правильном порядке.
Итак, для начала давайте сделаем начальную строку , Для этого нам понадобится пользовательская функция сортировки (извините, она довольно многословна. Если бы мы только могли использовать регулярное упорядочение ASCII):
function lowerUpperNumber(a, b)
{
if(a.match(/[a-z]/) && b.match(/[A-Z0-9]/))
{
return -1;
}
else if(a.match(/[A-Z]/) && (b.match(/[0-9]/) || b.match(/[a-z]/)))
{
if(b.match(/[0-9]/))
{
return -1;
}
else if(b.match(/[a-z]/))
{
return 1;
}
}
else if(a.match(/[0-9]/) && b.match(/[a-zA-Z]/))
{
return 1;
}
else if(a > b)
{
return 1;
}
else if(a < b)
{
return -1;
}
return 0;
}
Затем создайте заголовок конечного результата:
let firstBlock = [...(new Set(s))].sort(lowerUpperNumber);
Set
создает набор уникальных элементов, т.е. не повторяется.
Поскольку мы создали строку заголовка, при создании блоков повторяющихся символов нам понадобится на один меньше, чем вышеприведенное l oop дает нам, поэтому мы будем использовать s.match(repeatRegex).length-1
.
У меня возникает желание замкнуть сложный бит и вернуться быстро, когда нет повторяющихся символов, но я собираюсь чтобы убрать этот бит для краткости, а также я не хочу иметь дело с неопределенными значениями (например, попробуйте '123'
в качестве ввода).
Давайте соединим все вместе:
function lowerUpperNumber(a, b)
{
if(a.match(/[a-z]/) && b.match(/[A-Z0-9]/))
{
return -1;
}
else if(a.match(/[A-Z]/) && (b.match(/[0-9]/) || b.match(/[a-z]/)))
{
if(b.match(/[0-9]/))
{
return -1;
}
else if(b.match(/[a-z]/))
{
return 1;
}
}
else if(a.match(/[0-9]/) && b.match(/[a-zA-Z]/))
{
return 1;
}
else if(a > b)
{
return 1;
}
else if(a < b)
{
return -1;
}
return 0;
}
function makeBlocks(s)
{
if (s.length === 0)
{
return '';
}
let firstBlock = [...(new Set(s))].sort(lowerUpperNumber);
let firstString = firstBlock.join('');
let blocks = [];
for(let c of firstString)
{
let repeatRegex = new RegExp(c, 'g');
let repeatCount = s.match(repeatRegex).length - 1;
for(let i = 1; i <= repeatCount; i++)
{
if(blocks.length < i)
{
let newBlock = [c];
blocks.push(newBlock);
}
else
{
blocks[i - 1].push(c);
}
}
}
blocks.unshift(firstBlock);
return blocks.map(block => block.join('')).join('-');
}
console.log(makeBlocks('21AxBz'));
console.log(makeBlocks('abacad'));
console.log(makeBlocks('Any9Old4String22With7Numbers'));
console.log(makeBlocks(''));
Вы увидите, что я не потрудился генерировать повторяющиеся символы, потому что я могу просто пропустить те, которые этого не делают.