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