使用循环替换字符串中的数字

时间:2018-02-02 21:23:51

标签: javascript loops for-loop

我正在做任务,我遇到了问题。我想在n = 5时实现这种效果:

* 2 3 4 5
* * 3 4 5
* * * 4 5
* * * * 5
* * * * *
* * * * *
* * * * 5
* * * 4 5
* * 3 4 5
* 2 3 4 5

我在练习的第二部分堆叠。我现在的代码:

var n = 5;
var numbers = '';

for (var i = 1; i <= n; i++) {
    numbers += i;
}

for (var i = 0; i < n; i++) {
    numbers = numbers.replace(numbers[i], '*');
    console.log(numbers);

到目前为止,我有这样的结果:

*2345
**345
***45
****5
*****

所以现在我需要在数字/星星之间添加空格,并进行反向循环。我不知道该怎么做。 此外,这项任务的解决方案可能比我更快。

4 个答案:

答案 0 :(得分:2)

坚持类似于你的方法:

var n = 5;
var numbers = '';

for (var i = 1; i <= n; i++) {
    numbers += i + ' ';
}

for (var i = 0; i < n; i++) {
    numbers = numbers.substr (0, i * 2) + '*' + numbers.substr (i * 2 + 1);
    console.log(numbers);
};

for (var i = n - 1; i >= 0; i--) {
    console.log(numbers);
    numbers = numbers.substr (0, i * 2) + (i + 1) + numbers.substr (i * 2 + 1);
};

这种方法的缺点是它只适用于0-9,因为当数字不是单个数字时,字符串位置会中断。

答案 1 :(得分:1)

您可以将生成的每个数字保存在堆栈(数组)中,然后以相反的顺序从堆栈中弹出它们:

&#13;
&#13;
var n = 5;
var numbers = '';
var stack = []; // <--- add this

for (var i = 1; i <= n; i++) {
    numbers += i;
}

for (var i = 0; i < n; i++) {
    numbers = numbers.replace(numbers[i], '*');
    console.log(numbers);
    stack.push(numbers); // <--- push on stack
}
    
while (stack.length > 0) {
    numbers = stack.pop(); // <--- pull in reverse order
    console.log(numbers); // <--- and print
}    
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
&#13;
&#13;

类似的方式,不使用堆栈,延迟输出,并收集两个较长的字符串中的所有字符串,每个字符串将有多行输出:

&#13;
&#13;
var n = 5;
var numbers = '';
var stack = [];
var output1 = ''; // <-- add this
var output2 = ''; //

for (var i = 1; i <= n; i++) {
    numbers += i;
}
numbers += '\n'; // <-- add a newline character

for (var i = 0; i < n; i++) {
    numbers = numbers.replace(numbers[i], '*');
    output1 += numbers;
    output2 = numbers + output2; //  <-- add reversed
}

console.log(output1 + output2); // <-- output both
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
&#13;
&#13;

答案 2 :(得分:1)

我可能解决问题的方法是使用一个变量来跟踪哪个数字需要是星号,执行前半部分,然后使用全新的for循环来执行下半部分。

例如,

String result = '';
String line = '';
int counter = 1;

for (int line = 1; line =< 5; line++) {
  for (int i = 1; i =< 5; i++) { // note that we start at 1, since the numbers do
    if (i <= counter) {
      line += '*'; // use asterisk for positions less than or equal to counter
    else {
      line += i; // otherwise use the number itself
    }
    line += ' '; // a space always needs to be added
  }
  result += line + '\n'; // add the newline character after each line
  counter++; // move the counter over after each line
}

然后你可以做同样的循环,但让计数器倒退。为此,请在开始循环之前将counter设置为5(因为字符串为零索引)并在每行之后执行counter--

或者,如果您不想写两个循环,可以将外部for循环的限制增加到10,并使用if语句检查是否应该从计数器中减去而不是根据{{​​1}}

的值添加

答案 3 :(得分:0)

决定以此为借口,通过不可变映射和减少来获得更多练习。我使用一个数组来保存所有行,并将它们最后减少为一个字符串。每行以一个包含1到n的数组开始,然后每个列号根据大小写映射到星号:

if rowIndex <= number:
    rowIndex.
else:
    rowIndex - (2 * (rowIndex - number) - 1)

基本上,[n + 1,n * 2]映射到(1,3,5,...,n - 3,n - 1),从原始范围中减去变为[n,1]。对于该行,检查当前选定的列是否小于或等于其行的已翻译索引,并返回星号或数字。

&#13;
&#13;
// expansion number (n by 2n)
const maxNum = 5;

// make an array to size to hold all the rows
const result = Array(maxNum * 2)
    // Fill each row with an array of maxNum elements
    .fill(Array(maxNum).fill())

    // iterate over each row
    .map((row, rowIndex) =>
        // iterate over each column
        row.map((v, column) => (

            // check if the column is less than the translated rowIndex number (as mentioned above)
            column < ((rowIndex <= maxNum) ?
                rowIndex + 1 :
                2 * maxNum - rowIndex
            // if it is, replace it with an asterisk
            )) ? "*" : column + 1)

        // combine the row into a string with each column separated by a space
        .reduce((rowAsString, col) => rowAsString + " " + col)
    // combine all rows so they're on new lines
    ).reduce((rowAccum, row) => rowAccum + "\n" + row);
    
console.log(result);
&#13;
&#13;
&#13;