首页 > 解决方案 > 按照创建顺序给定一个所需字符串的数组。由于两个字符串不能相等,因此替换它对它们进行版本控制

问题描述

按照创建顺序给定一个所需字符串的数组。由于两个字符串不能相等,所以后面的字符串将以 (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) 正在重复。我对此进行了检查,但仍然没有得到所需的输出。

标签: javajava-8

解决方案


问题是您没有检查新文件以查看它们是否已经存在。我认为它可以像这样工作:

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

推荐阅读