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

huangapple go评论64阅读模式
英文:

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&#39;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(&quot;bcdxyz@3210.&quot;);

}
public String reverse(String arg) {

    String reverseCap = &quot;&quot;;
    String myStr = &quot;abc, XYZ; 123.&quot;;

    char[] argArray = arg.toCharArray();
    char[] myArray = myStr.toCharArray();

    for (int i =0; i &lt; myArray.length; i++) {
        for (int j =0; j &lt; argArray.length; j++){
            if (myArray[i] == argArray[j] &amp;&amp; Character.isLowerCase(myArray[i])){
                reverseCap += Character.toUpperCase(myArray[i]);
            } else if (myArray[i] == argArray[j] &amp;&amp; Character.isUpperCase(myArray[i])){
                reverseCap += Character.toLowerCase(myArray[i]);
            } else {
                reverseCap += myArray[i];
            }
        }
    }
    System.out.println(reverseCap);
    return null;
}

I want reverseCap to be &quot;aBC, xyz, 123.&quot; but am getting the following - 

"aaaaaaaaaaaaBbbbbbbbbbbbcCcccccccccc,,,,,,,,,,,, XXXXXXXXXXXXYYYYYYYYYYYYZZZZZZZZZZZZ;;;;;;;;;;;; 111111111111222222222222333333333333............
".


I&#39;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&#39;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&#39;t appear in `arg`, you&#39;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循环有点复杂。

/**
 * 示例:对于字符串 &quot;bcdxyz@3210.&quot;
 * 查找映射如下
 * {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 = &quot;&quot;;

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 &quot;bcdxyz@3210.&quot;
* 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}
* &lt;p&gt;
* Using a map to get the inverse of a character is faster than repetitively 
* looping through the string.
* &lt;/p&gt;
* @param arg
* @return
*/
public String reverse2(String arg) {
Map&lt;Character, Character&gt; inverseLookup = createInverseLookupMap(arg);
String myStr = &quot;abc, XYZ; 123.&quot;;
String result = myStr.chars()
.mapToObj(ch -&gt; Character.toString(inverseLookup.getOrDefault(ch, (char) ch)))
.collect(Collectors.joining());
return result;
}
private Map&lt;Character, Character&gt; createInverseLookupMap(String arg) {
Map&lt;Character, Character&gt; lookupMap = arg.chars()
.filter(ch -&gt; Character.isLetter(ch))
.mapToObj(this::getPairs)
.flatMap(List::stream)
.collect(Collectors.toMap(Pair::key, Pair::value));
System.out.println(lookupMap);
return lookupMap;
}
private List&lt;Pair&gt; 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 = &quot;abc, XYZ; 123.&quot;;
String testArg = &quot;bcdxyz@3210.&quot;;
System.out.println(testStr + &quot; using &quot; + testArg + &quot; =&gt;&quot;);
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 &lt; myArray.length; i++) {
for (int j =0; j &lt; 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);
}
}

huangapple
  • 本文由 发表于 2023年2月14日 02:02:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/75439632.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定