我正在编写一个疯狂的libs程序,用于娱乐和编程。该程序本身非常简单,但由于游戏的性质,您将用户给出的单词放入句子中,我发现自己会使用多个连接。有没有一个优雅的工作来诉诸较少的连接,甚至消除它们更高效的东西?我知道最后如果我使用连接,它将没有任何区别,但我很好奇是否有更优雅的方式来编写这个程序。
更新:我正在使用java,但如果有一个通用的解决方案来逃避连接也会受到赞赏。
答案 0 :(得分:8)
一种解决方案可能是写出你的整个疯狂的libs文件并输入需要被所选单词替换的特殊标记。
你刚买了一个全新的$ {NOUN1}, 这将是$ {VERB1}你。
然后你可以使用例如String.replace("${NOUN1}", noun1)
来表示所有单词。
答案 1 :(得分:3)
您使用的是哪种语言?
大多数高级语言都有类似的内容:
String.Format("{0} {1} {2} {3}", word1, word2, word3, word4);
答案 2 :(得分:2)
我可以通过两种方式看到你完全避免游戏中的连接:
将故事模板存储为标记集合:不可变部分和单词占位符。然后遍历集合输出不可变部分和用户单词而不是单词占位符。
编写自定义打印类,使用charAt循环遍历模板字符串,输出单词而不是单词占位符。
答案 3 :(得分:2)
不是为每个单词调用String.replace或不断附加到StringBuilder,而是可以将单词放在有序数组中,并在jdk 1.4中使用String.format(在jdk 1.5或更新版本中)或MessageFormat.format。不幸的是,两者的模式格式不同。
String myPattern = "My %s eats your %s"; // get values from the user here String result = String.format( myPattern, (Object[])myArray );
或
String myPattern = "My {0} eats your {1}"; // get values from the user here String result = MessageFormat.format( myPattern, (Object[])myArray );
这是一个完整的程序,用命令行中的值填充字符串。
public class Format { public static void main( String[] args ) { String pattern = "My %s eats your %s"; System.out.println( String.format( pattern, (Object[])args )); } }
答案 4 :(得分:1)
你的问题有两个方面。
首先,您可能希望避免在代码中直接使用连接。然后,您可以使用运行时中的一些字符串格式化例程。这不会跳过连接,但会将它们从代码移到运行时。
其次,您可能希望更有效地进行连接。那是另一个故事。这里最重要的是为连接字符串预分配足够大的缓冲区,因为内存重新分配非常昂贵。将子字符串复制到结果字符串中通常更便宜并且是必要的恶意。
答案 5 :(得分:1)
在避免连接的一般方法方面,我没有想到任何事情。你能做的就是给自己写一些辅助类,它简化了你的串联工作。 但是我想给你的建议是不要将字符串直接连接为
String x = "Hi";
String y = x + " there!";
字符串连接的实现在Java中非常慢,因此使用StringBuffer是一种更好的做法,特别是如果你进行大量的连接:
StringBuffer myStringBuffer = new StringBuffer();
myStringBuffer.append("Hi");
myStringBuffer.append(" there!");
像这样的东西。我现在没有在编译器中检查这个,但我相信你可以自己搞清楚。
答案 6 :(得分:1)
不确定Java,但在其他语言(如PHP和Javascript)中创建数组并加入其所有元素可能会更快。
Javascript示例:
var str = str1 + str2 + str3 + "str4" + str5 + "str6" + str7;
var str = [str1, str2, str3, "str4", str5, "str6", str7].join("");
PHP示例:
$str = $str1 . $str2 . $str3 . "str4" . $str5 . "str6" . $str7;
$str = implode("", array($str1, $str2, $str3, "str4", $str5, "str6", $str7));
如果你想在每个字符串之间放置一个分隔符,这种方法最好,在这种情况下它不仅更快,而且更紧凑和可读。
答案 7 :(得分:0)
通过'避免连接'我假设你的意思是为新字符串分配空间并分配它?如果您使用的是.NET,那么StringBuilder应该对我认为有用。
答案 8 :(得分:0)
如果你有一个String需要经常修改它,使用char []数组并在完成修改后创建一个String可能会有所帮助。
答案 9 :(得分:0)
如果你愿意的话,没有连接就可以做到这一点。虽然这可能不太值得。
部分取决于您要显示结果的位置。如果它在Web或控制台上,则可以将结果直接写入输出流。
例如,如果您的模板类似于“%001跳出%002”,您可以:
1)扫描字符串以查找变量的位置。 2)在这种情况下,将字符串分解为组件列表“the”,“跳出” 3)遍历列表中的元素和结果,并将它们转储到输出中,如下所示:
PrintStream = //get output from somewhere
for(int i = 0; i < pieces.size()-1 ; i++){
ps.print(peices.get(i));
ps.print(answers.get(i));
}
ps.print(pieces.get(pieces.size()-1));//last one
现在。我不知道你是否会称之为“优雅”。它可能会有点快。就像我说的那样,如果这是一个网络服务并且它变得非常流行等,也许是合适的。
如果这是一个GUI应用程序,您可以编写代码来单独绘制字符串,但这可能需要更多时间才能连接。
但你可以做的一件事是使用ByteArrayOutputStream并预先分配足够的空间,以便它可以包含填充的madlib而无需进行额外的分配。那也很快。
答案 10 :(得分:0)
为什么你想要避免串联,如果它的清洁度很好地排列它可能最终看起来非常好。即使你担心性能你可能不需要使用字符串构建器,我相信如果你这样做简单地说是一堆串联(即“fdsfsd”+ var1 + var2 +“dsfsdf”+“tyhty”它编译成与字符串构建器相同的东西(实际上相同并且看起来更干净)。如果你正在编写一个字符串生成器,它确实有意义大量的东西在一个循环或复杂的流动。