2017-05-24 505 views
0

假设:如何合并两个字符串为一个字符串在Java中

String s1="13579"; 
String s2="2468"; 

然后输出将123456789

这里我的代码:

public class JoinString { 

    public static void main(String[] args) { 

     String s1 = "13579"; 
     String s2 = "2468"; 
     for (int i = 0; i < s1.length(); i++) { 
      for (int j = i; j < s2.length(); j++) { 

       System.out.print(s1.charAt(i) + "" + s2.charAt(j)); 
       break; 
      } 
     } 
    } 
} 
+5

什么是你的推理'break'? – Tom

+5

你并不需要两个嵌套循环。只需要一个循环跟踪两个字符串的索引就足够了。一旦你用完了较短的一个,你可以根据你得到的距离添加一个更长的子串。 – azurefrog

+0

如果我没有使用break语句,那么op将是12141618343638565878。 –

回答

3
StringBuilder buf = new StringBuilder(); 
for (int i = 0; i < Math.max(s1.length(), s2.length()); i++) { 
    if (i < s1.length()) { 
     buf.append(s1.charAt(i)); 
    } 
    if (i < s2.length()) { 
     buf.append(s2.charAt(i)); 
    } 
} 
final String result = buf.toString(); 

你只需要一个循环。另外,您可以使用StringBuilder类来逐个字符地构建您的字符串。

1

你只需要像这样结合两个循环的逻辑(如果你想用这种方式构建一个字符串,可以使用StringBuilder)。

String s1 = "13579"; 
    String s2 = "2468"; 
    int length = Math.max(s1.length(), s2.length()); 
    for (int i = 0; i < length; i++) { 
     if(i < s1.length()) 
      System.out.print(s1.charAt(i)); 

     if(i < s2.length()) 
      System.out.print(s2.charAt(i)); 
    } 
+0

这对s1的双重检查可能有点多余。length()'和's2.length()'。 –

+0

@ChrisGilardi true ...打破了这一点,以便while循环在做零件时只做很少的工作。 – Tezra

0

到@Roman Puchovskiy类似,这里是一个办法做到这一点没有StringBuilder

String s1 = "abcde"; 
    String s2 = "defgh"; 
    String combined = ""; 
    int length = s1.length() > s2.length() ? s1.length() : s2.length(); //Finds the longest length of the two, to ensure no chars go missing 
    for(int i = 0 ; i < length ; i++) { 
     if(i < s1.length()) { // Make sure there is a char in s1 where we're looking. 
      combined += s1.charAt(i); 
     } 
     if(i < s2.length()) { // Same with s2. 
      combined += s2.charAt(i); 
     } 
    } 

其中combined成为组合字符串。 ("adbecfdgeh")。

希望这会有所帮助!

+1

请注意,这会产生大量垃圾:每个'+ ='都有一个字符串对象,因此每个结果字符串都有一个对象。 GC可能不开心。 –

+0

@RomanPuchkovskiy感谢您的洞察力,我不知道这是事实。不过,我刚刚在[这个答案](https://stackoverflow.com/a/4323132/4914803)中读过它并不重要,因为Java的编译器足够聪明,可以将它变成一个StringBuilder。无论哪种方式,谢谢! –

+2

@ChrisGilardi编译器确实这样做了,但是每次循环运行时都会调用'toString',而使用'StringBuilder'时只会发生一次。在这里可能不会通知,但这确实需要比'StringBuilder'解决方案更多的内存。对于单一声明,这并不重要。但是在循环内,它会产生相当大的差异。 –

3

这个怎么样小窍门:

String s1 = "13579"; 
String s2 = "2468"; 

String s3 = (s1 + s2).codePoints() // stream of code points 
    .sorted() 
    // collect into StringBuilder 
    .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append) 
    .toString(); 

System.out.println(s3); // 123456789 
+0

但是,只有输入严格排序才有效。我们真的可以假设情况总是如此吗? – azurefrog

+0

@azurefrog我只是想知道这件事。 tbh我认为这是整个问题,以获得排序的输出。 –

+0

嗯,好的一点,回头看,OP的问题可以被解读为“每隔一个字符”或“排序后的输出”,这有点含糊不清。 – azurefrog

2

一种简单的方式来实现这一目标是做这样的事情:

String s1 = "13579"; 
String s2 = "2468"; 
char[]result = (s1+s2).toCharArray(); 
Arrays.sort(result); 
System.out.println(result); 

输出:

123456789 
+1

但是,只有在输入严格排序的情况下才有效。我们真的可以假设情况总是如此吗? – azurefrog

+0

@azurefrog你是什么意思*严格排序* ?,我用OP提到的例子。 – Yahya

+0

没错,请参阅我对@Jorn Vernee的回答的回复。 OP的问题不明确。 – azurefrog

0

类似的方式作为合并排序中的合并方法。

另外,如果将字符串转换为char数组,以便随机访问元素的时间不变,那么它会更好。 因为charAt具有O(n)时间复杂度。

public class JoinString { 

public static void main(String[] args) { 

    String s1 = "13579"; 
    String s2 = "2468"; 
    final char[] str1 = s1.toCharArray(); 
    final char[] str2 = s2.toCharArray(); 
    int i; 
    for (i = 0; i < str1.length && i < str2.length; i++) { 
     System.out.print(str1[i] + "" + str2[i]); 
    } 

    while (i < str1.length) { 
     System.out.print(str1[i] + ""); 
     i++; 
    } 

    while (i < str2.length) { 
     System.out.print(str2[i] + ""); 
     i++; 
    } 
} 

}

+0

对于'String','StringBuffer'和'StringBuilder','charAt()'是一个常量操作。 https://stackoverflow.com/questions/6461402/java-charat-and-deletecharat-performance –