Я выполняю следующее упражнение по программированию: Числа строки . Оператор:
Вам дана строка ввода.
Для каждого символа в строке, если это первый символ, замените его на '1', иначе замените его с количеством раз, которое вы уже видели ...
Но будет ли ваш код достаточно быстрым ? Примеры:
input = "Hello, World!"
result = "1112111121311"
input = "aaaaaaaaaaaa"
result = "123456789101112"
В строке могут содержаться символы, не являющиеся символами ascii.
Примечание. Не будет переполнения домена int (число символов будет меньше 2 миллиардов).
Я написал следующий ответ:
import java.util.*;
import java.util.stream.*;
public class JomoPipi {
public static String numericals(String s) {
System.out.println("s: "+s);
Map<String, Long> ocurrences = Arrays.stream(s.split("")).
collect(Collectors.groupingBy(c -> c,
Collectors.counting()));
System.out.println("ocurrences: "+ocurrences.toString());
StringBuilder result = new StringBuilder();
for(int i = s.length()-1; i >= 0; i--){
String c = String.valueOf(s.charAt(i));
result.append(ocurrences.get(c) + " ");
ocurrences.put(c, ocurrences.get(c)-1);
}
System.out.println("result: "+result.toString());
String[] chars = result.toString().split(" ");
Collections.reverse(Arrays.asList(chars));
String sorted = String.join("",chars);
System.out.println("sorted: "+sorted);
return sorted;
}
}
Однако время ожидания (время выполнения превышает 16000 мс), когда входная строка велика.
Кому Посмотрите, как это работает, есть трассировка с очень маленькой входной строкой:
s: Hello, World!
result: 1 1 3 1 2 1 1 1 1 2 1 1 1
sorted: 1112111121311
Кроме того, я также написал следующий альтернативный ответ:
import java.util.*;
import java.util.stream.*;
public class JomoPipi {
public static String numericals(String s) {
System.out.println("s: "+s);
Map<String, Long> ocurrences = Arrays.stream(s.split("")).
collect(Collectors.groupingBy(c -> c,
Collectors.counting()));
String[] result = new String[s.length()];
for(int i = s.length()-1; i >= 0; i--){
String c = String.valueOf(s.charAt(i));
result[i] = String.valueOf(ocurrences.get(c));
ocurrences.put(c, ocurrences.get(c)-1);
}
System.out.println("result: "+Arrays.toString(result));
return String.join("",result);
}
}
Несмотря на это, он все еще синхронизируется out.
Вот трассировка с небольшой входной строкой:
s: Hello, World!
result: [1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 3, 1, 1]
Как мы могли бы улучшить решение? Какой алгоритм будет работать лучше, чтобы обрабатывать очень большие входные строки? Где узкое место, которое мы должны отлаживать и избегать, чтобы улучшить этот ответ?
Чтобы попытаться решить его самостоятельно, я прочитал:
EDIT: Здесь у нас есть ответ, основанный на предложении @khelwood:
import java.util.*;
import java.util.stream.*;
public class JomoPipi {
public static String numericals/*?->?*/(String s) {
Map<String, Integer> ocurrences = new HashMap<String,Integer>();
StringBuilder result = new StringBuilder();
for(int i = 0; i < s.length(); i++){
String c = String.valueOf(s.charAt(i));
ocurrences.putIfAbsent(c, 0);
ocurrences.put(c,ocurrences.get(c)+1);
result.append(ocurrences.get(c));
}
return result.toString();
}
}