#java #java-8
#java #java-8
Вопрос:
Задан массив нужной строки в порядке их создания. Поскольку две строки не могут быть равными, та, которая появится позже, будет иметь дополнение к своему имени в форме (k), где k — наименьшее положительное целое число, такое, что полученное имя еще не используется.
static String[] fileNaming(String[] names) {
List<String> newNames = new ArrayList<String>();
LinkedHashMap<String, Integer> wordCount = new LinkedHashMap<String, Integer>();
Arrays.asList(names).stream().forEach(x -> {
String str = x;
if (wordCount.containsKey(x)) {
str = x "(" String.valueOf(wordCount.get(x)) ")";
wordCount.merge(x, 1, Integer::sum);
wordCount.merge(str, 1, Integer::sum);
} else {
wordCount.put(x, 1);
}
newNames.add(str);
System.out.println(wordCount);
});
return newNames.toArray(new String[names.length]);
}
Тестирование этого кода на двух строках []
Arrays.toString(fileNaming(new String[] { "doc", "doc",
"image", "doc(1)", "doc" }))
Arrays.toString(
fileNaming(new String[] { "a(1)", "a(6)", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a" }))
Желаемый результат для них обоих должен быть
["doc", "doc(1)", "image", "doc(1)(1)", "doc(2)"].
["a(1)", "a(6)", "a", "a(2)", "a(3)", "a(4)", "a(5)", "a(7)", "a(8)", "a(9)", "a(10)", "a(11)"]
С помощью данного кода я смог правильно сопоставить первый вывод. Но для второго я получаю
[a(1), a(6), a, a(1), a(2), a(3), a(4), a(5), a(6), a(7), a(8), a(9)]
Здесь мы видим, что a(1) и a(6) повторяются. Для чего я поставил галочку, но по-прежнему не получаю желаемый результат.
Комментарии:
1. И как это связано со scala?
2. @Nosrep удалил scala. Хотя я стремился, если бы это можно было сделать в scala более просто, я бы тоже предпочел это.
3. @boilerplate.code Я прочитал заголовок вопроса 3 раза, и я все еще не могу разобрать то, что вы спрашиваете. Что вы имеете в виду, поскольку две строки не могут быть равными ? с каких пор строки не могут быть равными? что это значит -> тот, который появится позже, будет иметь дополнение к своему имени в форме (k), где k — наименьшее положительное целое число, такое, что полученное имя еще не используется. — имеется в виду?
Ответ №1:
Проблема в том, что вы не проверяете свои новые файлы, чтобы увидеть, присутствуют ли они уже. Я думаю, что это может работать так:
static String[] fileNaming(String[] names) {
List<String> newNames = new ArrayList<String>();
var usedNames = new HashSet<String>();
Arrays.asList(names).stream().forEach(x -> {
int retries = 0;
var uniqueName = x;
while (!usedNames.add(uniqueName)) {
uniqueName = x "(" retries ")";
}
newNames.add(uniqueName);
System.out.println(wordCount);
});
return newNames.toArray(new String[names.length]);
}
Если у вас много копий одной и той же строки, это будет медленнее, чем ваш исходный код … но это проще и работает, так что это сработает! В этом случае вы могли бы настроить этот код, чтобы он был быстрее, но, вероятно, оно того не стоит (если вы не знаете, что получите много копий ваших строк).
Редактировать: Черт возьми, вот версия O (n):
static String[] fileNaming(String[] names) {
List<String> newNames = new ArrayList<String>();
var usedNames = new HashSet<String>();
var counts = new HashMap<String, Integer>();
Arrays.asList(names).stream().forEach(x -> {
int retries = counts.getOrDefault(x, 0);
var uniqueName = x;
while (!usedNames.add(uniqueName)) {
uniqueName = x "(" retries ")";
}
newNames.add(uniqueName);
counts.put(x, retries);
System.out.println(wordCount);
});
return newNames.toArray(new String[names.length]);
}
Комментарии:
1. Проблема, которую я хочу в O (n), поскольку у меня может быть много копий.
2. Чтобы сделать это O (n), вам нужно иметь сопоставление от имени до целого числа; начните повторные попытки с этого целого числа, затем выполните шаг вверх и сохраните его, когда найдете уникальное имя. Это означает, что вам нужно будет перебирать usedNames только тогда, когда a (5) уже создано, и вы получите свой пятый «a», который, я думаю, по-прежнему равен O (n), потому что каждое имя может выполнить цикл не более одного раза.
3. Я пытаюсь сделать это, используя карту, но не могу достичь
4. Я отредактировал свой ответ, чтобы добавить код, который должен работать с O (n) . Я не тестировал это, но это выглядит просто.