Как убедиться, что оператор печати выполняется только тогда, когда символы различны?

#java #string

#java #строка

Вопрос:

Итак, я пишу программу для сжатия строк. если ввод есть aabbccc , вывод должен быть a2b2c3 .

Но в моей программе мой вывод a2a2b2b2c3c3c3 . Это потому, что мой оператор Print находится в цикле for . Которого там не должно быть.

Как я могу выполнить оператор печати только тогда, когда два символа в строке не равны? чтобы я получил правильный вывод?

Я пробовал другие способы выполнения программы сжатия строк, но этот способ использования коллекций кажется мне самым простым.

 public class Compress {

   static int i;
   static int freq;

public static void main(String args[]) {
  System.out.println("Enter a String");
  Scanner sc= new Scanner(System.in);
  String  str=sc.nextLine();
   List<Character> arrlist = new ArrayList<Character>();
   for(int i=0; i<str.length();i  ){
       arrlist.add(str.charAt(i));
   }
   for(int i=0; i<str.length();i  ){
       freq = Collections.frequency(arrlist, str.charAt(i));
           System.out.print(str.charAt(i) "" freq);
   }
 }
}
  

Желаемый результат

 Input: aabbccc
Output: a2b2c3
  

Что я получаю

 Input: aabbccc
Output: a2a2b2b2c3c3c3
  

Ответ №1:

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

 class Compress {

  public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    System.out.print("Enter a string: ");
    String inputString = scanner.nextLine();
    scanner.close();
    System.out.println("Compressed Input: "   compressInput(inputString));
  }

  private static String compressInput(String str) {
    if(str.isEmpty())
        return "";
    if(str.length() == 1)
        return str   "1";

    StringBuilder result = new StringBuilder();
    int cmpt = 1;
    for (int i = 1; i < str.length(); i  ) {
      if(str.charAt(i - 1) == str.charAt(i))
          cmpt  ;
      else {
          result.append(str.charAt(i-1));
          result.append(cmpt);
          cmpt=1;
      }
    } 
    result.append(str.charAt(str.length()-1));
    result.append(cmpt);
    return result.toString();
  }

}
  

Пример вывода:

 Enter a string: aaabbbbccddddeeeefg
Compressed Input: a3b4c2d4e4f1g1
  

Ответ №2:

Collections.frequency дает вам количество, которое вы можете видеть в своем выводе, но проблема здесь в том, что вам нужно группировать по каждому символу в строке.

Используйте карту:

 Map<Character, Long> countMap = new HashMap<>();
for (int i = 0; i < inputString.length(); i  ) {
    countMap.merge(Character.valueOf(inputString.charAt(i)), 1L, (k, v) -> k   v);
}

countMap.forEach((k, v) -> System.out.print(k   ""   v));
  

Комментарии:

1. Вы также можете использовать ту же логику после использования Collections.frequency(arrlist, str.charAt(i))

Ответ №3:

Вы также можете сделать это аналогичным образом, как показано ниже. Я использовал карту, в которой ключ — это символ, а значение — частота появления.

 public class Compress {

    static int i;
    static int freq;

    public static void main(String args[]) {
        System.out.println("Enter a String");
        Scanner sc = new Scanner(System.in);
        HashMap<Character, Integer> hmap = new HashMap<>();
        String str = sc.nextLine();
        List<Character> arrlist = new ArrayList<Character>();
        for (int i = 0; i < str.length(); i  ) {
            arrlist.add(str.charAt(i));
        }
        for (int i = 0; i < str.length(); i  ) {
            freq = Collections.frequency(arrlist, str.charAt(i));
            hmap.put(str.charAt(i), freq);
        }

        for (Character c : hmap.keySet()) {
            System.out.print(c   ""   hmap.get(c));
        }
    }
}