在原地添加字符时从数组末尾循环后无法重新索引我的数组
Having trouble re-indexing my array after looping from the end of the array while adding characters in place
我正在尝试解决这个特定的算法问题:
您将获得一个表示为字符串 S 的许可证密钥,该字符串仅包含字母数字字符和破折号。字符串被 N 个破折号分成 N+1 组。
给定一个数字 K,我们希望重新格式化字符串,使每个组恰好包含 K 个字符,除了第一组可能比 K 短,但仍然必须至少包含一个字符。此外,两组之间必须插入一个破折号,并将所有小写字母转换为大写字母。
给定一个非空字符串 S 和一个数字 K,根据上述规则格式化字符串。
示例 1:
输入:S = "5F3Z-2e-9-w", K = 4
输出:“5F3Z-2E9W”
解释:字符串S被拆分成两部分,每部分4个字符。
请注意,不需要两个额外的破折号,可以将其删除。
示例 2:
输入:S = "2-5g-3-J", K = 2
输出:“2-5G-3J”
解释:字符串S已被拆分为三部分,除第一部分外每部分有2个字符,因为它可以像上面提到的那样更短。
笔记:
字符串S的长度不会超过12000,K为正整数。
字符串 S 仅包含字母数字字符 (a-z and/or A-Z and/or 0-9) 和破折号 (-)。
字符串 S 非空。
我写了下面的代码:
const licenseKeyFormatting = (S, K) => {
//convert to array, remove special characters, and capitalize
let s = [...S.replace(/\W/g, '').toUpperCase()]
let pos = 1
//from end of array add '-' for every K
for (let i = s.length - 1; i > 0; i--) {
if (pos === K) {
s.splice(i, 0, '-')
pos = 1
i-- //re-index bc adding to the array
}
pos++
}
return s
}
console.log(licenseKeyFormatting("5F3Z-2e-9-w", 4)) //5F3Z-2E9W
console.log(licenseKeyFormatting("2-5g-3-J", 2)) //2-5G-3J
console.log(licenseKeyFormatting("a-a-a-a-", 1)) // this test case fails should be A-A-A-A, I am getting AAA-A
我很确定我的逻辑缺陷是由于重新索引造成的,但我不知道如何解决它。
我的方式....
function licenseKeyFormatting( S, K )
{
let arr = [...S.replace(/\W/g, '').toUpperCase()]
, p = 0
;
for (let i=arr.length;i--;)
{
p = ++p % K // p = (p+1) % K
if (!p&&i) arr.splice(i,0,'-') // if p===0 and i>0
}
return arr.join('')
}
console.log(licenseKeyFormatting("5F3Z-2e-9-w", 4)) // 5F3Z-2E9W
console.log(licenseKeyFormatting("2-5g-3-J", 2)) // 2-5G-3J
console.log(licenseKeyFormatting("a-a-a-a-", 1)) // A-A-A-A
OR: (more simple)
function licenseKeyFormatting( S, K )
{
let arr = [...S.replace(/\W/g, '').toUpperCase()];
for (let p=arr.length-K;p>0;p-=K) arr.splice(p,0,'-');
return arr.join('');
}
console.log( licenseKeyFormatting("5F3Z-2e-9-w", 4)) // 5F3Z-2E9W
console.log( licenseKeyFormatting("2-5g-3-J", 2)) // 2-5G-3J
console.log( licenseKeyFormatting("a-a-a-a-", 1)) // A-A-A-A
您不应更改索引。使用 splice
插入一个元素会将其他元素推回,但是因为您是从后向前迭代,所以这无关紧要。您已经处理了移位的元素。
另一个问题是在循环中设置 pos = 1
。紧随其后的是 pos++
。因此,当 pos
达到 K
时, pos
的值将在循环结束时重置为 2
。要么设置 pos = 0
(在循环中)使其在 1
结束,要么将 pos++
移动到 else
部分。
const licenseKeyFormatting = (S, K) => {
//convert to array, remove special characters, and capitalize
let s = [...S.replace(/\W/g, '').toUpperCase()]
let pos = 1
//from end of array add '-' for every K
for (let i = s.length - 1; i > 0; i--) {
if (pos === K) {
s.splice(i, 0, '-')
pos = 0
}
pos++
}
return s.join("") // <- added join for cleaner console output
}
console.log(licenseKeyFormatting("5F3Z-2e-9-w", 4)) //5F3Z-2E9W
console.log(licenseKeyFormatting("2-5g-3-J", 2)) //2-5G-3J
console.log(licenseKeyFormatting("a-a-a-a-", 1)) // this test case fails should be A-A-A-A, I am getting AAA-A
我正在尝试解决这个特定的算法问题:
您将获得一个表示为字符串 S 的许可证密钥,该字符串仅包含字母数字字符和破折号。字符串被 N 个破折号分成 N+1 组。
给定一个数字 K,我们希望重新格式化字符串,使每个组恰好包含 K 个字符,除了第一组可能比 K 短,但仍然必须至少包含一个字符。此外,两组之间必须插入一个破折号,并将所有小写字母转换为大写字母。
给定一个非空字符串 S 和一个数字 K,根据上述规则格式化字符串。
示例 1: 输入:S = "5F3Z-2e-9-w", K = 4
输出:“5F3Z-2E9W”
解释:字符串S被拆分成两部分,每部分4个字符。 请注意,不需要两个额外的破折号,可以将其删除。 示例 2: 输入:S = "2-5g-3-J", K = 2
输出:“2-5G-3J”
解释:字符串S已被拆分为三部分,除第一部分外每部分有2个字符,因为它可以像上面提到的那样更短。 笔记: 字符串S的长度不会超过12000,K为正整数。 字符串 S 仅包含字母数字字符 (a-z and/or A-Z and/or 0-9) 和破折号 (-)。 字符串 S 非空。
我写了下面的代码:
const licenseKeyFormatting = (S, K) => {
//convert to array, remove special characters, and capitalize
let s = [...S.replace(/\W/g, '').toUpperCase()]
let pos = 1
//from end of array add '-' for every K
for (let i = s.length - 1; i > 0; i--) {
if (pos === K) {
s.splice(i, 0, '-')
pos = 1
i-- //re-index bc adding to the array
}
pos++
}
return s
}
console.log(licenseKeyFormatting("5F3Z-2e-9-w", 4)) //5F3Z-2E9W
console.log(licenseKeyFormatting("2-5g-3-J", 2)) //2-5G-3J
console.log(licenseKeyFormatting("a-a-a-a-", 1)) // this test case fails should be A-A-A-A, I am getting AAA-A
我很确定我的逻辑缺陷是由于重新索引造成的,但我不知道如何解决它。
我的方式....
function licenseKeyFormatting( S, K )
{
let arr = [...S.replace(/\W/g, '').toUpperCase()]
, p = 0
;
for (let i=arr.length;i--;)
{
p = ++p % K // p = (p+1) % K
if (!p&&i) arr.splice(i,0,'-') // if p===0 and i>0
}
return arr.join('')
}
console.log(licenseKeyFormatting("5F3Z-2e-9-w", 4)) // 5F3Z-2E9W
console.log(licenseKeyFormatting("2-5g-3-J", 2)) // 2-5G-3J
console.log(licenseKeyFormatting("a-a-a-a-", 1)) // A-A-A-A
OR: (more simple)
function licenseKeyFormatting( S, K )
{
let arr = [...S.replace(/\W/g, '').toUpperCase()];
for (let p=arr.length-K;p>0;p-=K) arr.splice(p,0,'-');
return arr.join('');
}
console.log( licenseKeyFormatting("5F3Z-2e-9-w", 4)) // 5F3Z-2E9W
console.log( licenseKeyFormatting("2-5g-3-J", 2)) // 2-5G-3J
console.log( licenseKeyFormatting("a-a-a-a-", 1)) // A-A-A-A
您不应更改索引。使用 splice
插入一个元素会将其他元素推回,但是因为您是从后向前迭代,所以这无关紧要。您已经处理了移位的元素。
另一个问题是在循环中设置 pos = 1
。紧随其后的是 pos++
。因此,当 pos
达到 K
时, pos
的值将在循环结束时重置为 2
。要么设置 pos = 0
(在循环中)使其在 1
结束,要么将 pos++
移动到 else
部分。
const licenseKeyFormatting = (S, K) => {
//convert to array, remove special characters, and capitalize
let s = [...S.replace(/\W/g, '').toUpperCase()]
let pos = 1
//from end of array add '-' for every K
for (let i = s.length - 1; i > 0; i--) {
if (pos === K) {
s.splice(i, 0, '-')
pos = 0
}
pos++
}
return s.join("") // <- added join for cleaner console output
}
console.log(licenseKeyFormatting("5F3Z-2e-9-w", 4)) //5F3Z-2E9W
console.log(licenseKeyFormatting("2-5g-3-J", 2)) //2-5G-3J
console.log(licenseKeyFormatting("a-a-a-a-", 1)) // this test case fails should be A-A-A-A, I am getting AAA-A