Как считать символы по порядку в строке? - PullRequest
0 голосов
/ 06 мая 2018

У меня есть String для редактора в игре на 2D-платформе, где пользователь нажимает на прямоугольную доску 16x60, чтобы создать собственную доску. Я перебираю эти прямоугольники и получаю строку, которую хочу обрезать. X - это блоки, а A - это пустое пространство. Мне нужно это, чтобы нарисовать уровень.

String s = "x1x1x1x1a1a1x1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1";

Я хочу обрезать это до x4a2x1a54. По сути, складываются буквы «х» и «а», которые появляются сразу после друг друга.

Как мне это сделать?

Ответы [ 5 ]

0 голосов
/ 06 мая 2018

Вы можете сделать это так, как написал Фабиан, и это прекрасно работает.Тем не менее, я понял это, просто имея три простых if.

    StringBuilder sb = new StringBuilder();

    List<String> values = new ArrayList<>();

    String s = "x1x1x1x1a1a1x1x1a1a1a1";
    String[] splitString = s.split("1");
    // "xxxxaaxxaaa"
    // to x4a2x2a3

    String current = splitString[0];
    int occ = 0;

    for(int i = 0; i < splitString.length;i++){

        if(!splitString[i].equals(current)){
            values.add(current+occ);
            occ = 0;
            current = splitString[i];
        }

        if(splitString[i].equals(current)){
            occ++;
        }

        if(i == splitString.length-1){
            values.add(current+occ);
        }

    }

    for (String str: values
         ) {
        sb.append(str);
    }

    System.out.println(sb);
}
0 голосов
/ 06 мая 2018

Зацикливание символов и сохранение последнего буквенного символа. Для каждого из этих символов проанализируйте число, следующее за ним. Если буквенный символ совпадает с последним, вы можете добавить это число к счетчику, в противном случае запишите старые результаты в вывод:

public static String compress(String input) {
    if (input == null || input.isEmpty()) {
        return input;
    }
    char type = ' ';
    int count = 0;
    StringBuilder output = new StringBuilder();
    int index = 0;
    final int length = input.length();
    while (index < length) {
        char elementType = input.charAt(index);

        // parse number
        int elementCount = 0;
        char c;
        for (index++; index < length && Character.isDigit(c = input.charAt(index)); index++) {
            elementCount = 10 * elementCount + (c - '0');
        }

        if (elementType == type) {
            count += elementCount;
        } else {
            // finish counting last type
            output.append(type).append(count);
            type = elementType;
            count = elementCount;
        }
    }
    output.delete(0, 2); // remove substring added for the initial count/type
    output.append(type).append(count); // append last entry
    return output.toString();
}

Это позволяет выводить числа, отличные от 1, например,

compress("a22a20x9")
0 голосов
/ 06 мая 2018

Первое, что я хотел бы предложить, это разбить эту строку на более легкие в управлении разделы, подобные этому:

    String s = "x1x1x1x1a1a1x1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1";
    String[] splitS = s.split("1");
    //Contents of the array are: [x, x, x, x, a, a, x, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a]
    //We can now loop through each string in the string array and count how many we have of what
    ArrayList<String> values = new ArrayList<String>();
    int start = 0, end = 0, grandCounter = 0;
    String current = splitS[0];
    for(int i = 1; i < splitS.length-1; i++){
        if(!splitS[i].equals("x") && current.equals("x")){
            end = i;
            values.add("x" + (end - start));
            grandCounter += (end-start);
            start = end;
            end = 0;
            current = "a";
        } else if(!splitS[i].equals("a") && current.equals("a")){
            end = i;
            values.add("a" + (end - start));
            start = end;
            end = 0;
            current = "x";
            grandCounter += (end-start);
        }
    }
    values.add( "a" + (splitS.length-grandCounter) + "");
    System.out.println(values.toString().replace("[", "").replace(",", "").replace("]", "").replace(" ", ""));

Приведенный выше код в точности вернул следующее, когда было сказано печатать в консоли: x4a2x1a58

Пожалуйста, дайте мне знать, если у вас есть дополнительные вопросы или проблемы с вашей работой!

0 голосов
/ 06 мая 2018

Вот более простой метод, чем те, которые уже публиковались:

 public static String customTrim(String s){

String res = "";
String last = "";
int count = 0;

for (int i = 0; i < s.length() - 1; i+=2){

  String curr = "" + s.charAt(i) + s.charAt(i+1);

  if(!curr.equals(last)){
      count = 1;
      res += "" + s.charAt(i) + count;
  }

  else{
    int subLength = ("" + count).length();
    count++;
    res = res.substring(0, res.length()- subLength) + count;
  }

  last = curr;

}
return res;
}
0 голосов
/ 06 мая 2018

Просто чтобы сообщить вам, stackoverflow - это не форум для получения кода, а для того, чтобы помочь вам с вашим кодом и указать на ошибки или дать предложения.

Мне скорее не нравится спрос, но поскольку эта проблема меня немного зацепила, вот моя версия. К сожалению, мне не удалось использовать только потоки, и мне пришлось добавить к нему Arraylist (возможно, с помощью метода уменьшения и сбора потоков это возможно в одну строку), но он работает как задумано.

    String s = "x1x1x1x1a1a1x1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1";
    ArrayList<String[]> map = new ArrayList<>();
    for(String c:s.split("(?<=\\G..)")){
        if(map.isEmpty()||!map.get(map.size()-1)[0].equals(c.substring(0,1))){
            map.add(new String[]{c.substring(0,1),c.substring(1)});
        } else{
            map.get(map.size()-1)[1]=(Integer.parseInt(map.get(map.size()-1)[1])+Integer.parseInt(c.substring(1)))+"";
        }
    }
    StringBuilder sb = new StringBuilder();
    map.forEach(x-> sb.append(x[0]).append(x[1]));
    System.out.println(sb.toString());

РЕДАКТИРОВАТЬ: я изменил код так, чтобы другие числа, кроме 1, также были добавлены в строку, и я пока не использовал потоки, но для циклов

...