提问人:Miles 提问时间:12/30/2022 最后编辑:user3840170Miles 更新时间:12/30/2022 访问量:71
如何在 Java 中设置参数?
How can I have out parameters in Java?
问:
我的目标是递归地迭代一个 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 中并不适合我。一个通用树会具有这些属性,这很奇怪。longest
timesUsed
那我该怎么办?所有这些选项中哪个是最好的?还有什么比这三个更好的呢?我不确定哪种方法是最好的传统和实用方法,除了第一种不节省空间。
答:
你遇到的问题并不是因为 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);
}
}
}
评论
longest
String
String[]
String[] longest = { "" };
评论
StringBuilder
java.util.concurrent.atomic
AtomicInteger