【问题标题】:Java Beginner, comparing strings in nested for loopJava初学者,比较嵌套for循环中的字符串
【发布时间】:2023-03-25 04:35:02
【问题描述】:

这里是问题陈述:编写一个函数,比较两个字符串以根据两个字符串是否包含相同的字母来返回真或假。顺序无关紧要。

我不知道如何正确比较嵌套 for 循环中的字符数组。我希望我能更具体地说明我的问题是什么,但我是一个真正的新手,不明白为什么这不起作用。我确实相信它没有在嵌套的 for 循环中做我想做的事情。提前致谢!

import java.util.Scanner;

public class PracticeProblems { 

public static boolean stringCompare(String word1, String word2) {
    char[] word1b = new char[word1.length()];
    char[] word2b = new char[word2.length()];
    boolean compareBool = false;

    for(int i = 0; i < word1.length(); i++) {
        word1b[i] = word1.charAt(i);
        word2b[i] = word2.charAt(i);
    }   

    for(int i = 0; i < word1.length(); i++) {
        for(int j = 0; j < word2.length(); j++) {
            if(word1b[i] == word2b[j]) {
                compareBool = true;
                break;
            } else {
                compareBool = false;
                break;
            }
        }
    }   
    return compareBool;
}

public static void main(String []args) {
    Scanner scan = new Scanner(System.in);
    System.out.println("Word 1?");
    String word1 = scan.nextLine();
    System.out.println("Word 2?");
    String word2 = scan.nextLine();

    if(PracticeProblems.stringCompare(word1, word2) == true) {
        System.out.println("Same Letters!");
    } else {
        System.out.println("Different Letters...");
    }

}

【问题讨论】:

  • 你总是break 第一次通过循环。删除if 中的break 并保留else 中的那个。
  • 为什么不只是char[] word1b = word1.toCharArray();? (或者,比较word1.charAt(i)word2.charAt(j),这样可以避免创建新数组)。
  • 将每个String的字符放入一个Set。然后比较集合。
  • @AndyTurner,这并不是我提到的问题的重复。这是一个新手级别的问题,但不是关于==equals()。我的错。
  • 另外,请注意您正在检查word1 中的所有字母是否都在word2 中;并非word2 中的所有字母都在word1 中。

标签: java loops anagram


【解决方案1】:

下面的代码将完成这项工作。这本质上是弗兰克上述评论的扩展。我们将这两个字符串转换为两组,然后进行比较。

import java.util.*;

public class SameChars {

    // Logic to convert the string to a set
    public static Set<Character> stringToCharSet(String str) {
       Set<Character> charSet = new HashSet<Character>();
       char arrayChar[] = str.toCharArray();
       for (char aChar : arrayChar) {
          charSet.add(aChar);
       }

       return charSet;
    }

    // Compares the two sets
    public static boolean hasSameChars(String str1, String str2) {
       return stringToCharSet(str1).equals(stringToCharSet(str2));
    }

    public static void main(String args[]){
        // Should return true
        System.out.println(hasSameChars("hello", "olleh"));
        // Should returns false
        System.out.println(hasSameChars("hellox", "olleh"));
    }

}

【讨论】:

  • 你能想到不使用set怎么做吗? :)
  • 首先检查字符串是否相同长度,如果它们是然后从字符串创建两个数组,排序然后比较索引。剩下的就是功课了:)
  • 这不是更好的答案吗?
  • 暗示剩下的都是作业?对于替代方法:在编程中有很多方法可以做事。如果它完成了工作并且性能可以接受,那么是时候处理剩余的积压工作了。一旦积压为空或非常关键,您就可以进行优化。
【解决方案2】:

我在比较之前对数组进行了排序。

    //import statement for Arrays class
    import java.util.Arrays;
    import java.util.Scanner;

    public class PracticeProblems { 

    public static boolean stringCompare(String word1, String word2) {
        char[] word1b = new char[word1.length()];
        char[] word2b = new char[word2.length()];

        boolean compareBool = true;

        for(int i = 0; i < word1.length(); i++) {
            word1b[i] = word1.charAt(i);
        }   
        //sort the new char array
        Arrays.sort(word1b);


        // added a second loop to for the second world
        for(int i = 0; i < word2.length(); i++) {
            word2b[i] = word2.charAt(i);
        } 

        Arrays.sort(word2b);

        for(int i = 0; i < word1.length(); i++) {

            //removed second for loop. 
    //        for(int j = 0; j < word2.length(); j++) {

            // if the two strings have different length, then they are different
            if((word1.length()!=word2.length())){
                compareBool = false;
                break;

            }
            //changed to not equal  
            if( (word1b[i] != word2b[i]) ) {
                compareBool = false;
                break;

            } 
            //removed else statment
    //      else {
    //                compareBool = false;
    //                break;
    //
    //        }
        }   
        return compareBool;
    }

    public static void main(String []args) {
        Scanner scan = new Scanner(System.in);
        System.out.println("Word 1?");
        String word1 = scan.nextLine();
        System.out.println("Word 2?");
        String word2 = scan.nextLine();

        if(PracticeProblems.stringCompare(word1, word2) == true) {
            System.out.println("Same Letters!");
        } else {
            System.out.println("Different Letters...");
        }
        //resource leak.  use close() method.
        scan.close();
    }
    }

【讨论】:

  • 很好的解释。如果用户输入easeseas,我有点怀疑您的版本是否正确。它们包含相同的字母,即 a、e 和 s,只是每个字母的数量不相等。如果是学校作业,那么任何一个结果都可能是可以接受的,只要它指定了程序的作用。
【解决方案3】:

请允许我将您的 boolean 变量重命名为 letterFound(或者甚至可能是 letterFoundInWord2),因为这是您在双循环中检查的内容。解释性命名更容易让思路清晰。

由于您一次检查来自word1 的一封信,您可以将letterFound 的声明移动到外部for 循环中并将其初始化为false,因为每次您从word1 你还没有在 word2 中找到它。在for 循环内的if 语句中,如果字母相同并且将letterFound 设置为true,则break 是正确的。在相反的情况下,不要中断,继续检查下一个字母。事实上你可以完全删除else 部分。

在内部for循环之后,如果letterFound仍然不是true,我们知道来自word1的字母不在word2中。所以stringCompare() 应该返回 false:

if (! letterFound) {
    return false;
}

通过此更改,在外部for 循环之后,我们知道来自word1 的所有字母都在word2 中找到,因此您可以在此处输入return true;

除了:

  • 您似乎假设字符串具有相同的长度。如果没有,您的程序将无法正常工作。
  • 正如安迪·特纳所说,您还应该检查word2 中的所有字母是否都在word1 中;它不是来自word1word2 中的信件。
  • 是否应该只考虑字母?您是否应该忽略空格、数字、标点符号……?

希望你能弄清楚。随时在 cmets 中跟进或提出新问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多