英文:
I'm stuck. I need to adjust my loops so they continue to compare my two arrays but not print out all the extra characters
问题
我必须比较两个字符串数组。如果myArray中的任何字符与argArray中的字符匹配,那么我需要交换myArray中的字符的大小写。我几乎做到了,但是得到了额外的输出。
到目前为止,我的代码如下 -
```java
public class Main {
public static void main(String[] args) {
Main ob = new Main();
ob.reverse("bcdxyz@3210.");
}
public String reverse(String arg) {
String reverseCap = "";
String myStr = "abc, XYZ; 123.";
char[] argArray = arg.toCharArray();
char[] myArray = myStr.toCharArray();
for (int i =0; i < myArray.length; i++) {
for (int j =0; j < argArray.length; j++){
if (myArray[i] == argArray[j] && Character.isLowerCase(myArray[i])){
reverseCap += Character.toUpperCase(myArray[i]);
} else if (myArray[i] == argArray[j] && Character.isUpperCase(myArray[i])){
reverseCap += Character.toLowerCase(myArray[i]);
} else {
reverseCap += myArray[i];
}
}
}
System.out.println(reverseCap);
return null;
}
}
我希望reverseCap是"aBC, xyz, 123.",但我得到了以下结果 -
"aBC, xyz, 123."
我已经盯着这段代码几个小时了,所以我觉得现在是向别人寻求帮助的时候了,免得我把自己的眼睛剜出来。
<details>
<summary>英文:</summary>
I have to compare two string arrays. If the any of the characters in myArray match a character in argArray then I need to swap the case of the character in myArray. I'm almost there but am getting extra output.
This is what I have so far -
public class Main {
public static void main(String[] args) {
Main ob = new Main();
ob.reverse("bcdxyz@3210.");
}
public String reverse(String arg) {
String reverseCap = "";
String myStr = "abc, XYZ; 123.";
char[] argArray = arg.toCharArray();
char[] myArray = myStr.toCharArray();
for (int i =0; i < myArray.length; i++) {
for (int j =0; j < argArray.length; j++){
if (myArray[i] == argArray[j] && Character.isLowerCase(myArray[i])){
reverseCap += Character.toUpperCase(myArray[i]);
} else if (myArray[i] == argArray[j] && Character.isUpperCase(myArray[i])){
reverseCap += Character.toLowerCase(myArray[i]);
} else {
reverseCap += myArray[i];
}
}
}
System.out.println(reverseCap);
return null;
}
I want reverseCap to be "aBC, xyz, 123." but am getting the following -
"aaaaaaaaaaaaBbbbbbbbbbbbcCcccccccccc,,,,,,,,,,,, XXXXXXXXXXXXYYYYYYYYYYYYZZZZZZZZZZZZ;;;;;;;;;;;; 111111111111222222222222333333333333............
".
I've been staring at this for hours so I figured it was time to ask for help before I pluck my eyes out.
</details>
# 答案1
**得分**: 0
你正在每次迭代时都向`reverseCap`添加一个字符,无论字符是否匹配。在你的特定示例中,你可以直接去掉这部分,因为`myStr`中的每个字符也出现在`arg`中,但如果你想要添加字符到`reverseCap`,即使它们不在`arg`中出现,你需要一种方法来检查是否已经向`reverseCap`添加了字符。
<details>
<summary>英文:</summary>
With this part
} else {
reverseCap += myArray[i];
}
you're adding a character to `reverseCap` with every iteration, regardless if the characters match or not.
In your specific example, you could just leave that out, since every character in `myStr` also appears in `arg`, but if you want to add characters to `reverseCap`, even if they don't appear in `arg`, you'll need a way of checking if you already added a character to `reverseCap`.
</details>
# 答案2
**得分**: 0
Sure, here's the translated code:
更改
```java
String reverseCap = "";
为
char[] reverseCap = new char[myStr.length()];
然后,对于每个出现的
reverseCap +=
更改为
reverseCap[i] =
最后,将 reverseCap
转换为一个字符串:
String result = String.valueOf(reverseCap);
您目前正在返回 null
。考虑返回 result
,并将 System.out.println(...)
移入 main()
方法中。
更新:
我认为更好的方法是使用包含大写/小写字符对及其逆的查找映射来获取替换字符。嵌套的for循环有点复杂。
/**
* 示例:对于字符串 "bcdxyz@3210."
* 查找映射如下
* {B=b, b=B, C=c, c=C, D=d, d=D, X=x, x=X, Y=y, y=Y, Z=z, z=Z}
* <p>
* 使用映射来获取字符的逆比重复循环字符串要快。
* </p>
* @param arg
* @return
*/
public String reverse2(String arg) {
Map<Character, Character> inverseLookup = createInverseLookupMap(arg);
String myStr = "abc, XYZ; 123.";
String result = myStr.chars()
.mapToObj(ch -> Character.toString(inverseLookup.getOrDefault(ch, (char) ch)))
.collect(Collectors.joining());
return result;
}
private Map<Character, Character> createInverseLookupMap(String arg) {
Map<Character, Character> lookupMap = arg.chars()
.filter(ch -> Character.isLetter(ch))
.mapToObj(this::getPairs)
.flatMap(List::stream)
.collect(Collectors.toMap(Pair::key, Pair::value));
System.out.println(lookupMap);
return lookupMap;
}
private List<Pair> getPairs(int ch) {
char upperVariant = (char) Character.toUpperCase(ch);
return List.of(
new Pair(upperVariant, Character.toLowerCase(upperVariant)),
new Pair(Character.toLowerCase(upperVariant), upperVariant));
}
static record Pair(Character key, Character value) {
}
但如果不习惯Java流API,这也可能看起来有点复杂。
英文:
Change
String reverseCap = "";
to
char[] reverseCap = new char[myStr.length()];
and then for each occurrence of
reverseCap +=
change that to read
reverseCap[i] =
Finally, convert reverseCap
to a String:
String result = String.valueOf(reverseCap);
You are currently returning null
. Consider returning result
, and moving the System.out.println(...)
into the main()
method.
Update:
I think a better way to approach this is to use a lookup map containing upper/lower case pairs and their inverse to get the replacement character. The nested for loops are a bit gnarly.
/**
* Example: for the string "bcdxyz@3210."
* the lookup map is
* {B=b, b=B, C=c, c=C, D=d, d=D, X=x, x=X, Y=y, y=Y, Z=z, z=Z}
* <p>
* Using a map to get the inverse of a character is faster than repetitively
* looping through the string.
* </p>
* @param arg
* @return
*/
public String reverse2(String arg) {
Map<Character, Character> inverseLookup = createInverseLookupMap(arg);
String myStr = "abc, XYZ; 123.";
String result = myStr.chars()
.mapToObj(ch -> Character.toString(inverseLookup.getOrDefault(ch, (char) ch)))
.collect(Collectors.joining());
return result;
}
private Map<Character, Character> createInverseLookupMap(String arg) {
Map<Character, Character> lookupMap = arg.chars()
.filter(ch -> Character.isLetter(ch))
.mapToObj(this::getPairs)
.flatMap(List::stream)
.collect(Collectors.toMap(Pair::key, Pair::value));
System.out.println(lookupMap);
return lookupMap;
}
private List<Pair> getPairs(int ch) {
char upperVariant = (char) Character.toUpperCase(ch);
return List.of(
new Pair(upperVariant, Character.toLowerCase(upperVariant)),
new Pair(Character.toLowerCase(upperVariant), upperVariant));
}
static record Pair(Character key, Character value) {
}
But if one is not used to the Java streaming API, this might look a bit gnarly too.
答案3
得分: 0
Marce注意到在每次迭代中向reverseCap
添加字符的问题。以下是解决该问题并在原地执行大小写更改的解决方案。首先检查是否匹配,然后再更改大小写可以简化逻辑。请注意,在检查与arg[i]
是否匹配之前,myArray[i]
需要转换为小写,因为前者可能是大写字符;对于argArray[j]
,这不是必要的,因为这些字符都假定是小写。最后,一旦内部循环匹配,就不再需要进一步迭代。
public class Main {
public static void main(String[] args) {
Main ob = new Main();
String testStr = "abc, XYZ; 123.";
String testArg = "bcdxyz@3210.";
System.out.println(testStr + " using " + testArg + " =>");
System.out.println(ob.reverse(testStr, testArg));
}
public String reverse(String myStr, String myArg) {
char[] myArray = myStr.toCharArray();
char[] argArray = myArg.toCharArray();
for (int i = 0; i < myArray.length; i++) {
for (int j = 0; j < argArray.length; j++) {
if (Character.toLowerCase(myArray[i]) == argArray[j]) {
if (Character.isLowerCase(myArray[i])) {
myArray[i] = Character.toUpperCase(myArray[i]);
} else if (Character.isUpperCase(myArray[i])) {
myArray[i] = Character.toLowerCase(myArray[i]);
}
break;
}
}
}
return String.valueOf(myArray);
}
}
英文:
Marce noted the problem of adding characters to reverseCap
on every iteration. Here is a solution that solves that problem and performs the case changes in place. Checking for a match first and then changing the case simplifies the logic a bit. Note myArray[i]
needs to be lowercased before checking against arg[i]
because the former may be an uppercase character; this is not needed for argArray[j]
because those characters are assumed to be all lowercase. Finally, once the inner loop has matched, further iterations of it are no longer needed.
public class Main {
public static void main(String[] args) {
Main ob = new Main();
String testStr = "abc, XYZ; 123.";
String testArg = "bcdxyz@3210.";
System.out.println(testStr + " using " + testArg + " =>");
System.out.println(ob.reverse(testStr, testArg));
}
public String reverse(String myStr, String myArg) {
char[] myArray = myStr.toCharArray();
char[] argArray = myArg.toCharArray();
for (int i =0; i < myArray.length; i++) {
for (int j =0; j < argArray.length; j++) {
if (Character.toLowerCase(myArray[i]) == argArray[j]) {
if (Character.isLowerCase(myArray[i])) {
myArray[i] = Character.toUpperCase(myArray[i]);
} else if (Character.isUpperCase(myArray[i])) {
myArray[i] = Character.toLowerCase(myArray[i]);
}
break;
}
}
}
return String.valueOf(myArray);
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论