在两个奇数之间插入破折号

乡亲。 在我的程序中,我接受一个String类型的数字的用户输入,并在two odd numbers之间加上dashes 。 例如:

 Input = 99946 Output = 9-9-946 Input = 56730 Output = 567-30 

但是在我的代码中,如果我,例如,写9933444那么我得到的输出是: 9-9-9-3-3-3-344444 。 它正确地用破折号分隔奇数,但也增加了额外的数字 。 什么可能导致这个错误?

 import java.util.Arrays; import java.util.Scanner; public class DashInsert { public static void main(String[] args) { Scanner kbd = new Scanner(System.in); System.out.println("Enter the numbers: "); String myString = kbd.nextLine(); char[] numbers = myString.toCharArray(); String result = ""; for(int i = 1; i < numbers.length; i++) { int value1 = Character.getNumericValue(numbers[i]); int value2 = Character.getNumericValue(numbers[i-1]); if(value1 % 2 != 0 && value2 % 2 != 0) { result += numbers[i-1] + "-" + numbers[i] + "-"; } else result += numbers[i-1] + "" + numbers[i]; } System.out.println(result); } } 

代码可以简化一点(以及解决“双字符”错误):

 String str = "9933444"; char[] numbers = str.toCharArray(); String result = ""; for(int i = 1; i < numbers.length; i++) { int value1 = Character.getNumericValue(numbers[i-1]); int value2 = Character.getNumericValue(numbers[i]); result += value1; if(value1 % 2 != 0 && value2 % 2 != 0) { result += "-"; } } result += numbers[numbers.length - 1]; System.out.println(result); 

OUTPUT

 9-9-3-3444 

“双字符”错误的原因是每个循环都打印了地点i-1i 。 这意味着i将在下一个循环中再次打印(它将成为i-1 )。


如果你正在使用Java 8 - 你可以使用Stream做一些看起来更像你最初尝试做的事情:

 public static void main(String[] args){ String str = "9933444"; List lst = Arrays.asList(str.split("")); String res = lst.stream().reduce((a,b) -> { if (isOdd(a) && isOdd(b)) { return a + "-" + b; } else { return a + b; } }).get(); System.out.println(res); } // grep the last digit from the string and check if it's odd/even public static boolean isOdd(String x) { if (x.length() > 1) { if (x.substring(x.length()-1).equals("-")) { x = x.substring(x.length()-3, x.length()-2); } else { x = x.substring(x.length() - 1); } } return Integer.parseInt(x) % 2 == 1; } 

OUTPUT

 9-9-3-3444 

有一个简单的单线解决方案:

 str = str.replaceAll("(?<=[13579])(?=[13579])", "-"); 

这通过奇数之间进行匹配并用短划线替换(零宽度)匹配来实现。 正则表达式背后是一个outlook未来。

它可以通过捕获奇数位并使用后引用将它们放回来而无需环顾四周:

 str = str.replaceAll("([13579])([13579])", "$1-$2"); 

两种解决方案都实现了相同的结

这个错误是由于这样一个事实:即使你一次循环一个数字列表,你也会在每次循环迭代时写出两个数字。 从逻辑上讲,这种设计总会产生重复的数字。

要么将循环更改为两次迭代,要么在每次循环迭代中打印一个数字。

不要在两个奇数之间用“ – ”连接起来,在评估过程中,只需在每次迭代中检查的数字后加上“ – ”。

 public static void main(String[] args) throws Exception { Scanner kbd = new Scanner(System.in); System.out.println("Enter the numbers: "); String myString = kbd.nextLine(); char[] numbers = myString.toCharArray(); String result = ""; for(int i = 0; i < numbers.length; i++) { int value1 = Character.getNumericValue(numbers[i]); int value2 = i + 1 < numbers.length ? Character.getNumericValue(numbers[i + 1]) : 0; if(value1 % 2 != 0 && value2 % 2 != 0) { result += numbers[i] + "-"; } else { result += numbers[i]; } } System.out.println(result); } 

结果:

输入:99946输出:9-9-946

输入:56730输出:567-30

输入:9933444输出:9-9-3-3444