简体   繁体   English

将数组值移到左侧的Java

[英]Shifting array values to the left java

This is my second post on this same method. 这是我关于同一方法的第二篇文章。 The description of the method is as follows: 该方法的说明如下:

"Reduces all sequences of 2 or more spaces to 1 space within the characters array. If any spaces are removed then the same number of Null character '\' will fill the elements at the end of the array." “将字符数组中2个或更多空格的所有序列减少为1个空格。如果删除了任何空格,则相同数量的Null字符'\\ u0000'将填充数组末尾的元素。”

The parameter for the method is a char array. 该方法的参数是一个char数组。 I've succeeded in counting the amount of duplicate spaces, however, I cannot for the life of me figure out how to shift values down while accounting for such duplicate spaces. 我已经成功地计算出重复空间的数量,但是,我一生都无法弄清楚在考虑此类重复空间时如何向下移动值。 At the end, the method is supposed to replace the number of indexes of duplicate spaces with '\' characters. 最后,该方法应该用'\\ u0000'字符替换重复空格的索引数。 This is what I have so far: 这是我到目前为止的内容:

// Calculate duplicate count before changing the array
    int duplicateCount = 0;
    for(int i = 0; i + 1 < characters.length; i++){
        if(characters[i] == ' ' && characters[i + 1] == ' '){
            duplicateCount++;
        }
    }

    // Shift the array down however much is needed
    for(int j = 0; j + 1 < characters.length; j++){
        if(characters[j] == ' ' && characters[j + 1] == ' '){
            for(int a = j, b = a + 1; b < characters.length; a++, b++){
                characters[a] = characters[b];
            }
        }
    }
    for(int replace = characters.length - duplicateCount; replace < characters.length; replace++){
        characters[replace] = '\u0000';
    }
}

Thus, if the input was: char [] characters = {'a', 't', ' ', '.', ' ', ' ', 'g', ' ', ' ', 'h', ' '}; 因此,如果输入为: char [] characters = {'a', 't', ' ', '.', ' ', ' ', 'g', ' ', ' ', 'h', ' '};

The output should be: char [] expectedResult = {'a', 't', ' ', '.', ' ', 'g', ' ', 'h', ' ','\', '\'}; 输出应为: char [] expectedResult = {'a', 't', ' ', '.', ' ', 'g', ' ', 'h', ' ','\', '\'};

Thank you folks, this problem seems like it should be so simple yet I'm stuck. 谢谢大家,这个问题似乎应该很简单,但是我被困住了。 If you can offer any explanation to your answer, I'd very much appreciate it. 如果您能为您的答案提供任何解释,我将非常感谢。 Thank you again. 再次感谢你。

It's easy enough to do it in place. 做到这一点很容易。 Just iterate through the array keeping track of both the index you're checking (to see if it is an extra space) and the index you're copying to. 只需遍历数组即可跟踪要检查的索引(看是否有多余的空间)和要复制到的索引。 In the end, fill the array out with your '\' value and you're done. 最后,使用您的'\\ u0000'值填充数组,然后完成。

I made it a simple state machine to make it easy to keep track of whether we're getting extra spaces or not. 我将其设为一个简单的状态机,以使其易于跟踪我们是否获得了额外的空间。

public void squeezeMe(char[] characters) {
    SqueezeState state = SqueezeState.START;

    int p = 0;
    for (int i = 0; i < characters.length; i++) {
        SqueezeState newState = SqueezeState.START;

        // Evaluate input based on current state
        switch (state) {
        case START:
        case NOT_A_SPACE: {
            if (Character.isWhitespace(characters[i])) {
                newState = SqueezeState.FIRST_SPACE;
            } else {
                newState = SqueezeState.NOT_A_SPACE;
            }
            break;
        }
        case FIRST_SPACE:
        case EXTRA_SPACE: {
            if (Character.isWhitespace(characters[i])) {
                newState = SqueezeState.EXTRA_SPACE;
            } else {
                newState = SqueezeState.NOT_A_SPACE;
            }
        }
        }

        // Transition to new state
        switch (newState) {
        case NOT_A_SPACE:
        case FIRST_SPACE: {
            if (i > p) {
            characters[p] = characters[i];
            }
            p++;
            break;
        }
        }

        state = newState;
    }

    for (int i = p; i < characters.length; i++) {
        characters[i] = '\u0000';
    }

}

private enum SqueezeState {
    START, NOT_A_SPACE, FIRST_SPACE, EXTRA_SPACE;
}

@Test
public void test1() {
    char[] result = { 'a', 't', ' ', '.', ' ', ' ', 'g', ' ', ' ', 'h', ' ' };
    char[] expected = { 'a', 't', ' ', '.', ' ', 'g', ' ', 'h', ' ', '\u0000', '\u0000' };
    squeezeMe(result);
    assertEquals(expected.length, result.length);
    for (int i = 0; i < expected.length; i++) {
        assertEquals("Index " + i, expected[i], result[i]);
    }
}

If you'd rather not use the state machine, you could do it like this: 如果您不想使用状态机,则可以这样操作:

public void squeezeMe(char[] characters) {
    boolean copyThis = false;
    boolean wasLastASpace = false;

    int p = 0;
    for (int i = 0; i < characters.length; i++) {
        if (Character.isWhitespace(characters[i])) {
            copyThis = !wasLastASpace;
            wasLastASpace = true;
        } else {
            copyThis = true;
            wasLastASpace = false;
        }

        if (copyThis) {
            if (i != p) {
                characters[p] = characters[i];
            }
            p++;
        }
    }

    for (int i = p; i < characters.length; i++) {
        characters[i] = '\u0000';
    }
}

You can copy it in a single pass through the array, using two integer pointers for "input" and "output", as indexes into the input and output arrays respectively. 您可以一次遍历该数组,将两个整数指针分别用作“输入”和“输出”来将其复制为输入和输出数组的索引。

char[] output = new char[input.length];
output[0] = input[0];  // Copy the first character, it's not a repeated space.
int ip = 1;
int op = 1;
while (ip < input.length) {
  if (input[ip] != ' ' || input[ip - 1] != ' ') {
    output[op++] = input[ip++];
  } else {
    ip++;
  }
}
while (op < output.length) {
  output[op++] = '\0';
}

I'm guessing this is your homework and you are not supposed to use any libraries and such. 我猜这是您的作业,您不应使用任何此类库。 Here is my solution using a regular expression. 这是我使用正则表达式的解决方案。

import java.util.Arrays;
import java.util.regex.Pattern;
public class ReplaceMultipleWhiteSpace(){
public static void main(String[] args){
    char[] array = new char[]{'a', ' ', ' ', ' ', ' ', ' ', 'b', ' ', 'c'};
    String s = new String(array);
    int length = s.length();
    Pattern twoOrMoreWhiteSpace = Pattern.compile("( {2,})");
    String replaced = twoOrMoreWhiteSpace.matcher(s).replaceAll(" ");
    int diff = length - replaced.length();
    char[] charArray = replaced.toCharArray();
    char[] finalArray = Arrays.copyOf(charArray, replaced.length() + diff);
    for (int i = replaced.length(); i < finalArray.length; i++) {
        finalArray[i] = '\u0000';
    }
    System.out.println(Arrays.toString(array));
    System.out.println(Arrays.toString(finalArray));
}
} 

The code below should be pretty obvious. 下面的代码应该很明显。 You do not need to count the number of characters you need to fill at the end - just fill those that meet the criteria (=the previous and the current character are not both ' '), if it doesn't meet the criteria, don't copy it. 您无需计算最后需要填充的字符数-仅填充符合条件的字符(=前一个和当前字符都不都是''),如果不符合条件,请不要不要复制它。 At the end, just fill the remaining part of the array. 最后,只需填充数组的其余部分。

char[] result = new char[characters.length];

// copy the first character
result[0]=characters[0];
int resultIndex=1;

for(int i=1; i<characters.length; i++) {
    // if the current character and the last character are not both spaces
    if(!(result[resultIndex-1]==' ' && characters[i]==' ')) {
        result[resultIndex++]=characters[i];
    }
}

// fill the rest of the array with '\u0000'
while (resultIndex<characters.length) {
    result[resultIndex++]='\u0000';
}

return result;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM