【问题标题】:Word in a java stringjava字符串中的单词
【发布时间】:2015-06-06 15:21:59
【问题描述】:

我对 Java 很陌生,作为初学者,我被提议在家里尝试一下。

编写一个程序,该程序将找出较大字符串中较小字符串的出现次数作为其一部分以及单个单词。 例如,

较大的字符串 =“我在阿姆斯特丹”,较小的字符串 =“AM”。

输出:作为字符串的一部分:3,作为单词的一部分:1。

虽然我确实确定了第二部分(作为单词的一部分),甚至在第一部分(搜索单词作为字符串的一部分),但我似乎不知道如何破解第一部分。它通过示例输入继续为我显示 1,它应该是 3。

我确实犯了一个错误-如果您能指出错误并纠正它,我将不胜感激。作为一个请求,我是好奇的学习者——所以如果可能的话(根据你的意愿)——请解释为什么会这样。

import java.util.Scanner;
public class Program {
static Scanner sc = new Scanner(System.in);
static String search,searchstring;
static int n;
void input(){
    System.out.println("What do you want to do?"); System.out.println("1.     
Search as part of string?");
    System.out.println("2. Search as part of word?");
    int n = sc.nextInt();
    System.out.println("Enter the main string"); searchstring = 
sc.nextLine();
    sc.nextLine(); //Clear buffer
    System.out.println("Enter the search string"); search = sc.nextLine();
}
static int asPartOfWord(String main,String search){
    int count = 0; 
    char c; String w = "";
    for (int i = 0; i<main.length();i++){
        c = main.charAt(i);
        if (!(c==' ')){
            w += c;
        }
        else {
            if (w.equals(search)){
                count++;
            }
            w = ""; // Flush old value of w
        }
    }
    return count;
}
static int asPartOfString(String main,String search){
    int count = 0;
    char c; String w = ""; //Stores the word 
    for (int i = 0; i<main.length();i++){
        c = main.charAt(i);
        if (!(c==' ')){
            w += c;
        }
        else {
            if (w.length()==search.length()){
                if (w.equals(search)){
                    count++;
                }
            }
            w = ""; // Replace with new value, no string
        }
    }
    return count;
}
public static void main(String[] args){
    Program a = new Program();
    a.input();
    switch(n){
        case 1: System.out.println("Total occurences: " + 
         asPartOfString(searchstring,search));
        case 2: System.out.println("Total occurences: " +  
         asPartOfWord(searchstring,search));
        default: System.out.println("ERROR: No valid number entered");
    }
  }
}

编辑:我将使用循环结构。

【问题讨论】:

  • 这个问题你会得到很多答案。如果提供者有能力,那么他们都是正确的。花时间向他们学习。有些会很简单。有些复杂。其他人会以非常不同的方式看待这个问题。
  • 感谢@BrettWalker 的建议。会尽力吸收最好的。
  • 你想自己循环字符串还是可以使用这样的解决方案:stackoverflow.com/questions/767759/…
  • 我会使用循环。谢谢。

标签: java string words


【解决方案1】:

一种更简单的方法是使用正则表达式(这可能会破坏自己编写它的想法,尽管学习正则表达式是一个好主意,因为它们非常强大:正如你所见,我的代码的核心是 4 行countMatches 方法)。

public static void main(String... args) {
  String bigger = "I AM IN AMSTERDAM";
  String smaller = "AM";

  System.out.println("Output: As part of string: " + countMatches(bigger, smaller) +
          ", as a part of word: " + countMatches(bigger, "\\b" + smaller + "\\b"));
}

private static int countMatches(String in, String regex) {
  Matcher m = Pattern.compile(regex).matcher(in);
  int count = 0;
  while (m.find()) count++;
  return count;
}

它是如何工作的?

  • 我们创建一个Matcher,它将在您的字符串中查找特定模式,然后迭代以查找下一个匹配项,直到没有剩余匹配项并增加一个计数器
  • 模式本身:"AM" 将在字符串中的任何位置找到任何出现的AM。 “\\bAM\\b”将只匹配整个单词(\\b 是一个单词分隔符)。

这可能不是您想要的,但我认为看到另一种方法会很有趣。从技术上讲,我正在使用循环:-)

【讨论】:

    【解决方案2】:

    虽然编写自己的代码并使用大量循环来解决问题可能会执行得更快(值得商榷),但如果可以的话,最好使用 JDK,因为要编写的代码更少,调试更少,并且您可以专注于高-级别的东西,而不是字符迭代和比较的低级别实现。

    碰巧,你需要解决这个问题的工具已经存在,虽然使用它们需要你不具备的知识,但它们非常优雅,每个方法只需一行代码。

    以下是我的解决方法:

    static int asPartOfString(String main,String search){
        return main.split(search, -1).length - 1;
    }
    
    static int asPartOfWord(String main,String search){
        return main.split("\\b" + search + "\\b", -1).length - 1
    }
    

    请参阅live demo 与您的示例输入一起运行的此代码,其中(可能是故意)包含边缘情况(见下文)。

    性能?可能只有几微秒——足够快。但真正的好处是代码太少,以至于完全清楚发生了什么,几乎没有出错或需要调试的地方。

    使用此解决方案需要了解的内容:

    • “单词边界”的正则表达式术语是\b
    • split() 将正则表达式作为其搜索词
    • split() 的第二个参数控制字符串末尾的行为:负数表示“在拆分末尾保留空白”,它处理以较小字符串结尾的主字符串的边缘情况。如果没有 -1,在这种极端情况下,调用 split 会丢弃尾随空白。

    【讨论】:

    • 您的方法最简单,但您不认为split(search, -1) 可以替换为split(search, 0)。对于这两种方法,我得到的结果都是 0 而不是 -1 的正确结果。
    • @Rajesh split(search, 0) 失败。 split(search, -1) 成功。 0 是默认行为,它会丢弃返回数组中的尾随空格。有关此行为的完整描述,请参阅 javadoc。当匹配位于字符串末尾时,对示例数据使用 0 会返回比正确答案少一的结果(请注意,我在最初的帖子之后稍微更改了代码 - 检查您正在运行的代码)。
    【解决方案3】:

    您可以使用正则表达式,尝试".*&lt;target string&gt;.*"(将target string 替换为您要搜索的内容。

    查看"Patterns & Regular Expressions" 的 Java 文档

    要搜索字符串中的出现,这可能会有所帮助。

    Matcher matcher = Pattern.compile(".*AM.*").matcher("I AM IN AMSTERDAM")
    int count = 0;
    
    while (matcher.find()) {
        count++;
    }
    

    【讨论】:

      【解决方案4】:

      这是使用PatternMatcher 或通常称为正则表达式的另一种(而且更短)的方法。

      import java.util.regex.Matcher;
      import java.util.regex.Pattern;
      
      public class CountOccurances {
      
          public static void main(String[] args) {
      
              String main = "I AM IN AMSTERDAM";
              String search = "AM";
      
              System.out.printf("As part of string: %d%n",
                      asPartOfString(main, search));
      
              System.out.printf("As part of word: %d%n",
                      asPartOfWord(main, search));        
          }
      
          private static int asPartOfString(String main, String search) {
      
              Matcher m = Pattern.compile(search).matcher(main);
              int count = 0;
              while (m.find()) {
                  count++;
              }
              return count;
          }
      
          private static int asPartOfWord(String main, String search) {
      
              // \b - A word boundary
              return asPartOfString(main, "\\b" + search + "\\b");
          }
      }
      

      输出:

      As part of string: 3
      As part of word: 1
      

      【讨论】:

        【解决方案5】:

        对于练习的第一部分,这应该可以:

        static int asPartOfWord(String main, String search) {
            int count = 0;
            while(main.length() >= search.length()) { // while String main is at least as long as String search
                 if (main.substring(0,search.length()).equals(search)) {  // if String main from index 0 until exclusively search.length() equals the String search, count is incremented;
                     count++;
                 }
            main = main.substring(1); // String main is shortened by cutting off the first character
            }
            return count;
        

        您可能会考虑命名变量的方式:

           static String search,searchstring;
           static int n;
        

        虽然 search 和 searchstring 会告诉我们什么意思,但您应该将第一个单词写成小写,后面的每个单词的第一个字母都应该大写。这提高了可读性。

        如果你几天后再次阅读你的代码,static int n 不会给你太多线索,你可能会在这里使用更有意义的东西。

          static String search, searchString;
          static int command;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-12-16
          • 1970-01-01
          • 2011-08-23
          • 1970-01-01
          • 2015-03-03
          相关资源
          最近更新 更多