java 字符串中的单词
Word in a java string
我是 Java 的新手,作为初学者,我被邀请在家尝试这个。
Write a program that will find out number of occurences of a smaller string in a bigger string as a part of it as well as an individual word.
For example,
Bigger string = "I AM IN AMSTERDAM", smaller string = "AM".
Output: As part of string: 3, as a part of word: 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");
}
}
}
编辑:我将使用循环结构。
您可以使用正则表达式,尝试 ".*<target string>.*"
(将 target string
替换为您要搜索的内容。
查看 Java 文档 "Patterns & Regular Expressions"
要搜索字符串中的匹配项,这可能会有所帮助。
Matcher matcher = Pattern.compile(".*AM.*").matcher("I AM IN AMSTERDAM")
int count = 0;
while (matcher.find()) {
count++;
}
一种更简单的方法是使用正则表达式(这可能会打败自己编写它的想法,尽管学习正则表达式是一个好主意,因为它们非常强大:如您所见,我的代码的核心是 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
,它会在您的字符串中找到一个特定的模式,然后迭代以找到下一个匹配项,直到剩下 none 并递增一个计数器
- 模式本身:
"AM"
将在字符串中的任何位置找到任何出现的 AM
。 “\bAM\b
”将只匹配整个单词(\b
是单词分隔符)。
这可能不是您想要的,但我认为看到另一种方法会很有趣。从技术上讲,我正在使用循环 :-)
对于练习的第一部分,这应该有效:
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;
这是使用 Pattern and Matcher、
或更常见的正则表达式使其工作的另一种(更短的)方法。
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
虽然自己编写带有大量循环的代码来解决问题可能会执行得更快(有争议),但如果可以的话最好使用 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 运行 您的示例输入,其中(可能是故意的)包含边缘情况(见下文)。
性能?大概几微秒——足够快了。但真正的好处是代码很少,完全清楚发生了什么,几乎没有错误或需要调试的地方。
使用此解决方案需要了解的内容:
- "word boundary" 的正则表达式是
\b
split()
将正则表达式作为其搜索词
-
split()
的第二个参数控制字符串末尾的行为:负数表示 "retain blanks at end of split",它处理主字符串以较小字符串结尾的边缘情况。在没有 -1
的情况下,调用 split 会丢弃这种边缘情况下的尾随空白。
我是 Java 的新手,作为初学者,我被邀请在家尝试这个。
Write a program that will find out number of occurences of a smaller string in a bigger string as a part of it as well as an individual word. For example,
Bigger string = "I AM IN AMSTERDAM", smaller string = "AM".Output: As part of string: 3, as a part of word: 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");
}
}
}
编辑:我将使用循环结构。
您可以使用正则表达式,尝试 ".*<target string>.*"
(将 target string
替换为您要搜索的内容。
查看 Java 文档 "Patterns & Regular Expressions"
要搜索字符串中的匹配项,这可能会有所帮助。
Matcher matcher = Pattern.compile(".*AM.*").matcher("I AM IN AMSTERDAM")
int count = 0;
while (matcher.find()) {
count++;
}
一种更简单的方法是使用正则表达式(这可能会打败自己编写它的想法,尽管学习正则表达式是一个好主意,因为它们非常强大:如您所见,我的代码的核心是 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
,它会在您的字符串中找到一个特定的模式,然后迭代以找到下一个匹配项,直到剩下 none 并递增一个计数器 - 模式本身:
"AM"
将在字符串中的任何位置找到任何出现的AM
。 “\bAM\b
”将只匹配整个单词(\b
是单词分隔符)。
这可能不是您想要的,但我认为看到另一种方法会很有趣。从技术上讲,我正在使用循环 :-)
对于练习的第一部分,这应该有效:
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;
这是使用 Pattern and Matcher、
或更常见的正则表达式使其工作的另一种(更短的)方法。
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
虽然自己编写带有大量循环的代码来解决问题可能会执行得更快(有争议),但如果可以的话最好使用 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 运行 您的示例输入,其中(可能是故意的)包含边缘情况(见下文)。
性能?大概几微秒——足够快了。但真正的好处是代码很少,完全清楚发生了什么,几乎没有错误或需要调试的地方。
使用此解决方案需要了解的内容:
- "word boundary" 的正则表达式是
\b
split()
将正则表达式作为其搜索词-
split()
的第二个参数控制字符串末尾的行为:负数表示 "retain blanks at end of split",它处理主字符串以较小字符串结尾的边缘情况。在没有-1
的情况下,调用 split 会丢弃这种边缘情况下的尾随空白。