英文:
Given an array of desired String in the order of their creation. Since two strings cannot be equal replace it versioning them
问题
给定一个按创建顺序排列的所需字符串数组。由于两个字符串不能相等,后出现的字符串将在其名称后面以 (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) 被重复了。我已经进行了检查,但仍然没有得到期望的输出。
英文:
Given an array of desired String in the order of their creation. Since two strings cannot be equal , the one which comes later will have an addition to its name in a form of (k), where k is the smallest positive integer such that the obtained name is not used yet.
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]);
}
Testing this code against two string[]'s
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" }))
The desired output for both of them should be
["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)"]
With the given code I was able to match the first output correctly. But for the second one I am getting
[a(1), a(6), a, a(1), a(2), a(3), a(4), a(5), a(6), a(7), a(8), a(9)]
Here we can see that a(1) and a(6) are being repeated. For which I have put a check but still no getting the desired output.
答案1
得分: 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]);
}
英文:
The problem is that you aren't checking your new files to see if they are already present. I think it can work like this:
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]);
}
If you have a lot of copies of the same string, this will be slower than your original code...but it is simpler and it works, so it has that going for it! You could tweak this code to be faster in that case but it probably isn't worth it (unless you know you'll get lots of copies of your strings).
Edit: Oh heck, here's the O(n) version:
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]);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论