簡體   English   中英

將數組值移到左側的Java

[英]Shifting array values to the left java

這是我關於同一方法的第二篇文章。 該方法的說明如下:

“將字符數組中2個或更多空格的所有序列減少為1個空格。如果刪除了任何空格,則相同數量的Null字符'\\ u0000'將填充數組末尾的元素。”

該方法的參數是一個char數組。 我已經成功地計算出重復空間的數量,但是,我一生都無法弄清楚在考慮此類重復空間時如何向下移動值。 最后,該方法應該用'\\ u0000'字符替換重復空格的索引數。 這是我到目前為止的內容:

// 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';
    }
}

因此,如果輸入為: char [] characters = {'a', 't', ' ', '.', ' ', ' ', 'g', ' ', ' ', 'h', ' '};

輸出應為: char [] expectedResult = {'a', 't', ' ', '.', ' ', 'g', ' ', 'h', ' ','\', '\'};

謝謝大家,這個問題似乎應該很簡單,但是我被困住了。 如果您能為您的答案提供任何解釋,我將非常感謝。 再次感謝你。

做到這一點很容易。 只需遍歷數組即可跟蹤要檢查的索引(看是否有多余的空間)和要復制到的索引。 最后,使用您的'\\ u0000'值填充數組,然后完成。

我將其設為一個簡單的狀態機,以使其易於跟蹤我們是否獲得了額外的空間。

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]);
    }
}

如果您不想使用狀態機,則可以這樣操作:

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';
    }
}

您可以一次遍歷該數組,將兩個整數指針分別用作“輸入”和“輸出”來將其復制為輸入和輸出數組的索引。

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';
}

我猜這是您的作業,您不應使用任何此類庫。 這是我使用正則表達式的解決方案。

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));
}
} 

下面的代碼應該很明顯。 您無需計算最后需要填充的字符數-僅填充符合條件的字符(=前一個和當前字符都不都是''),如果不符合條件,請不要不要復制它。 最后,只需填充數組的其余部分。

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