Конкатенация строк с "множествами" в Java - PullRequest
2 голосов
/ 10 августа 2010

Не уверен, как сформулировать этот вопрос об алгоритме, на самом деле. У меня есть кнопки переключения в приложении для Android, каждая из которых соответствует пронумерованному каналу. Каналы - это (1, n), но идентификаторы кнопок переключения - это некое неизвестное, непоследовательное (для кнопок) целое число. Мне нужно собрать номера каналов и построить командную строку. Мои навыки работы с Java в 1995 году дали мне следующее:

String ch;
int i = 1;
for (ToggleButton toggle : toggles) {
    if (toggle.isChecked()) {
        ch = String.format("+%d", i+1);
        channels = channels.concat(ch);
    }
} 

Если кнопки-переключатели 1,2,4,5,6,7,11,13,21,22,23,24,25 проверены, этот фрагмент кода успешно возвращает мне строку "+1+2+4+5+6+7+11+13+21+22+23+24+25"

Тем не менее, я хотел бы получить строку "+1/2, +4/7, +11, +13, +21/25"

Интересно, есть ли более простой способ сделать это, чем несколько операторов if:

String ch;
int it = 0;
int last = 1;
for (ToggleButton toggle : toggles ) {
    if (toggle.isChecked()) {
    if (it == last + 1) {
            // somehow continue or note that we're only adding the "/"
        } else {
            // If we're not the next one, then build the last string
            // of "n/last" and then add ", +" to start building next string
        }
    }
    last++;
}

Это похоже на алгоритм "грубой силы", поэтому я не знаю, есть ли более элегантное решение, которое Java может иметь в своем арсенале (или, что более вероятно, I должен иметь)

Спасибо.

Ответы [ 2 ]

1 голос
/ 10 августа 2010

Вкл. java.util.BitSet

Я бы использовал java.util.BitSet как для представления, так и для алгоритма поиска диапазона.Вот основная идея ( см. На ideone.com ):

    import java.util.*;
    //...

    BitSet bs = new BitSet();
    int[] onBits = new int[] { 1,2,4,5,6,7,11,13,21,22,23,24,25 };
    for (int onBit : onBits) {
        bs.set(onBit);
    }
    System.out.println(bs);
    // {1, 2, 4, 5, 6, 7, 11, 13, 21, 22, 23, 24, 25}

    StringBuilder sb = new StringBuilder();
    for (int begin, end = -1; (begin = bs.nextSetBit(end + 1)) != -1; ) {
        end = bs.nextClearBit(begin) - 1;
        if (sb.length() > 0) sb.append(", ");
        sb.append(
            (begin == end)
                ? String.format("+%d", begin)
                : String.format("+%d/%d", begin, end)
        );
    }
    System.out.println(sb);
    // +1/2, +4/7, +11, +13, +21/25

Методы nextSetBit и nextClearBit действительно удобны при поиске промежутков.


Вкл. StringBuilder вместо String с +=/concat

Алгоритм объединения StringBuilder является стандартным.Вот когда происходит рефакторинг:

    StringBuilder sb = new StringBuilder();
    for (Element e : elements) {
        if (sb.length() > 0) sb.append(SEPARATOR);
        sb.append(e);
    }

Вы должны использовать StringBuilder или StringBuffer вместо String с += / concat для построения длинных строк.

0 голосов
/ 10 августа 2010

Ваш не будет работать, есть проблема конечного случая, когда вам придется дублировать код для очистки после окончания диапазона (попробуйте его в вашем наборе данных)

Я знаю, что вы искали краткую / краткую информацию, но я предпочитаю сделать код бизнес-логики короче и чище, выполнив что-то вроде этого:

Counter counter=new Counter();

for(int i=1;i<=toggles.length;i++)
    if(toggles.get(i).isChecked())
        counter.append(i);

System.out.println(counter.getResult());

так что часть вашего кода короче, но вам нужен новый класс. Этот класс можно использовать повторно, каждый раз, когда вы захотите воссоздать тот же самый список диапазонов, вы получите его !. Оба раздела кода должны быть более понятными, потому что каждый выполняет только свою работу. Это немного дольше, но, честно говоря, я не фанат лаконичного в любом случае, формы или формы. Пока вы СУХОЙ, чем яснее, тем лучше.

PS. Я собираюсь сегодня без скобок.

Итак:

public class counter
    int a=-1;
    int b=-1;
    String result="";

    public append(int i)
        if(a == -1)
            a=i;
            b=i;
        else if(b == i-1)
            b++;
        else
            finished();

    public finished()
        if(result.length != 0 && a != -1)
            result+="+";
        if(a != -1)
            result.append(a);
            if(a != b)
                result.append("/"+b);
        a=-1;
        b=-1;

    public String getResult()
        finished();
        return result;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...