如何在 Java 中设置参数?

How can I have out parameters in Java?

提问人:Miles 提问时间:12/30/2022 最后编辑:user3840170Miles 更新时间:12/30/2022 访问量:71

问:

我的目标是递归地迭代一个 R-way trye,并找到至少为两个字符串添加前缀的最长通用前缀,以及它涉及多少个字符串。我已经编写了各种方法来解决这个问题,但我对它们的技术方面不满意。

输入示例:

figure, fight, finger, english, entail

输出:

Longest prefix: fig

Number of Strings: 2

以下是我实施解决方案的方式:

节点具有一个属性,每次访问该节点时,在向 trie 插入新字符串时,该属性都会递增。timesUsed

    public void allPrefixes() {
        ArrayList<String> list = new ArrayList<>();
        ArrayList<Integer> timesUsed = new ArrayList<>();

        allPrefixesUtil(list, timesUsed, root, "");

        int longestPrefixIndex = getLongestIndex(list);

        System.out.println("Longest common prefix: " + list.get(longestPrefixIndex));
        System.out.println("Number of strings: " + timesUsed.get(longestPrefixIndex));
    }

    public void allPrefixesUtil(ArrayList<String> list, ArrayList<Integer> timesUsed, Node x, String s) {
        for (int i = 0; i < x.next.length; i++) {
            if (x.next[i] != null && x.next[i].timesUsed >= 2) {
                list.add(s + (char) (i + 'a'));
                timesUsed.add(x.next[i].timesUsed);
                allPrefixesUtil(list, timesUsed, x.next[i], s + (char) (i + 'a'));
            }
        }
    }

此处的代码会添加多次出现的每个前缀,因此列表如下所示:。然后,我从这些字符串中找到最长的字符串,并将其与相应的 timesUsed 索引一起打印出来。这个解决方案占用了很多空间,所以我决定尝试其他方法。e, en, f, fi, fig

接下来,我尝试了这个:

    public void allPrefixes2() {
        String longest = "";
        int timesUsed = 0;

        allPrefixesUtil2(longest, timesUsed, root, "");

        System.out.println("Longest common prefix: " + longest);
        System.out.println("Number of strings: " + timesUsed);
    }

    public void allPrefixesUtil2(String longest, int timesUsed, Node x, String s) {
        for (int i = 0; i < x.next.length; i++) {
            Node nextNode = x.next[i];
            if (nextNode != null && nextNode.timesUsed >= 2) {
                String str = s + (char) (i + 'a');
                if (str.length() > longest.length()) {
                    longest = new String(str);
                    timesUsed = nextNode.timesUsed;
                }
                allPrefixesUtil2(longest, timesUsed, nextNode, str);
            }
        }
    }

我没有将每个前缀添加到列表中并计算最长的前缀,而是决定在遇到更长的字符串时重新分配最长的字符串。这显然是行不通的,因为 Java 是按值传递的。为了解决这个问题,我将字符串和整数更改为单元素数组。

    public void allPrefixes2() {
        String[] longest = { "" };
        int[] timesUsed = { 0 };

        allPrefixesUtil2(longest, timesUsed, root, "");

        System.out.println("Longest common prefix: " + longest[0]);
        System.out.println("Number of strings: " + timesUsed[0]);
    }

这有效,但是......我不确定这是聪明的还是愚蠢的。如果我想使用临时变量,我找不到更好的方法。

然而,我最后确实做到了,使 trie 具有 a 和 a 属性,并直接将它们传递到方法中。它奏效了,但这一次,将这些属性添加到 trie 中并不适合我。一个通用树会具有这些属性,这很奇怪。longesttimesUsed

那我该怎么办?所有这些选项中哪个是最好的?还有什么比这三个更好的呢?我不确定哪种方法是最好的传统和实用方法,除了第一种不节省空间。

Java Pass-by-Reference out-参数

评论

0赞 tevemadar 12/31/2022
是的,这是常见的伎俩。在这种特殊情况下,你可以滥用 和 ,比如 ,但在一般情况下,你需要一个包装器,就像你发明中的数组一样。虽然点击在某种程度上是个性化的,但我必须指出,google.com/search?q=java+out+parameter 让我得到了许多可能的重复:stackoverflow.com/questions/2806545 stackoverflow.com/questions/1403921 stackoverflow.com/questions/2824910 stackoverflow.com/questions/4455693StringBuilderjava.util.concurrent.atomicAtomicInteger
0赞 tevemadar 1/7/2023
这回答了你的问题吗?Java 是否有类似 C# 的 ref 和 out 关键字?

答:

-1赞 egeorge 12/30/2022 #1

你遇到的问题并不是因为 Java 是“按值传递”的。

您遇到的问题是 Strings 是不可变的,当您为名为 Local Parameter 的新值赋值时,一旦超出范围,它就会消失。longest

你可以通过传递一个长度为 1 的数组来相对容易地解决这个问题。

 public void allPrefixes2() {
        String[] longest = {""};
        int timesUsed = 0;

        allPrefixesUtil2(longest, timesUsed, root, "");

        System.out.println("Longest common prefix: " + longest);
        System.out.println("Number of strings: " + timesUsed);
    }

    public void allPrefixesUtil2(String[] longest, int timesUsed, Node x, String s) {
        for (int i = 0; i < x.next.length; i++) {
            Node nextNode = x.next[i];
            if (nextNode != null && nextNode.timesUsed >= 2) {
                String str = s + (char) (i + 'a');
                if (str.length() > longest[0].length()) {
                    longest[0] = new String(str);
                    timesUsed = nextNode.timesUsed;
                }
                allPrefixesUtil2(longest, timesUsed, nextNode, str);
            }
        }
    }

评论

0赞 kaya3 12/30/2022
请阅读以下内容: stackoverflow.com/a/40523/12299000
0赞 egeorge 12/30/2022
谢谢你,@kaya3指出我的语义错误。但是,我确实相信我的解决方案将适用于这个问题。
0赞 Slaw 12/30/2022
这难道不是 OP 在他们的解决方案之一中已经在做的事情吗?
0赞 egeorge 12/30/2022
@Slaw,我将变量从 更改为 .longestStringString[]
0赞 Slaw 12/31/2022
是的,但 OP 说,“为了解决这个问题,我将字符串和整数更改为单元素数组”。然后,在紧随其后的代码块中,他们有.String[] longest = { "" };