2013-06-13 2 views
0

Я пытаюсь уменьшить последовательные элементы массива в один, но не для всех значений, таких как:Удалить конкретный последовательный элемент в массиве

{3,0,0,0,3,3,3,0,0,0} => {3,0,3,0} 

но для одной конкретной, в моем примере 0:

{3,0,0,0,3,3,3,0,0,0} => {3,0,3,3,3,0} 

так уменьшены только нули (троицы нетронутыми).

У меня есть Java Строка рабочий код я написал:

public static String removeConsecutive(String str, char remove) { 
    char[] chars = str.toCharArray(); 

    int current = 0; 
    int result = current; 
    while (current < chars.length) { 
     if (chars[current] == remove) { 
      // keep the first occurrence 
      chars[result++] = chars[current++]; 

      // ignore the others 
      while (current < chars.length && chars[current] == remove) { 
       ++current; 
      } 
     } else {    
      chars[result++] = chars[current++]; 
     } 
    } 

    return new String(chars, 0, result); 
} 

и делает трюк:

public static void main(String[] args) { 
    System.out.println(removeConsecutive("000300300030303330000", '0')); 
} 

выходы: 0303030303330

Можно ли предложить какие-либо улучшения, так как считаю, код не идеален.

+3

Я думаю, что это хороший вопрос http://codereview.stackexchange.com – vidit

+0

@vidit, спасибо. Я опубликую его на codereview и вставьте ссылку на эту дискуссию. – robosoul

+0

'While' Loops - это потенциально бесконечные циклы. Избегайте их как можно больше. В этом случае вы можете заменить его операторами 'foreach'. –

ответ

1

Думаю, что это яснее, и делает работу:

public static String removeConsecutive(String str, char remove) { 
    StringBuilder sb = new StringBuilder(); 
    for(char c : str.toCharArray()) { 
     int length = sb.length(); 
     if(c != remove || length == 0 || sb.charAt(length - 1) != c) { 
      sb.append(c); 
     } 
    } 
    return sb.toString(); 
} 
+0

спасибо, используя stringbuilder эффективен, но что, если это было целым массивом? – robosoul

+0

Тогда я бы просто использовал ['LinkedList '] (http://docs.oracle.com/javase/6/docs/api/java/util/LinkedList.html) и вызвал ['toArray'] (http: //docs.oracle.com/javase/6/docs/api/java/util/LinkedList.html#toArray (T [])) в этом 'LinkedList' в конце. Вызов 'StringBuilder.length' будет заменен на [' LinkedList .size'] (http://docs.oracle.com/javase/6/docs/api/java/util/LinkedList.html#size()) и вызов 'StringBuilder.charAt' с помощью [' LinkedList .peekLast'] (http://docs.oracle.com/javase/6/docs/api/java/util/LinkedList.html#peekLast()) , – jason

-1
int len = 0; 
    do { 
     len = str.length(); 
     str = str.replace(replacement + replacement, replacement); 
    } while (len != str.length()); 
+0

Ужасно неэффективно. Это много итераций над 'str'. – jason

+0

Согласитесь, однако правильный код для задачи зависит от контекста. Если бы система выполняла тысячи запросов по очень длинным строкам, это не было бы верным ответом. Однако для простой демонстрации или проекта основной задачей является простой и понятный код. В любом случае с текущим оборудованием вы все еще говорите о разнице в микросекундах. –

+1

Привет @ shonky-linux-user, tnx для вашего ответа, но я стараюсь не использовать java replace/replaceAll. Очень неэффективно при изменении только char, поскольку оба replace/replaceAll будут скомпилировать его в Pattern, сопоставить его, заменить. – robosoul

0

Если он не должен быть на месте:

public static String removeConsecutive(String str, char remove) { 
    StringBuilder bldr = new StringBuilder(); 
    int rec = 0; 
    for(char curr : str.toCharArray()){ 
    if(curr == remove){ 
     if(rec == 0) bldr.append(curr); 
     ++rec; 
    } 
    else{ 
     rec = 0; 
     bldr.append(curr); 
    } 
    } 
    return bldr.toString(); 
} 
Смежные вопросы