Как уже упоминалось, важно научиться решать эти проблемы самостоятельно. Домашнее задание не для наказания, а для того, чтобы научить вас самостоятельно осваивать новые вещи, что является важной чертой ученого-компьютерщика.
Тем не менее, поскольку кажется, что вы действительно приложили некоторые усилия, чтобы решить его самостоятельно, вот мое решение, а затем приведем некоторые пояснения.
Общие понятия
Первое, что я чувствую, что вы не поняли, это концепция классов и объектов. Класс подобен «чертежу» объекта, а объект - как только вы его создали.
По сравнению с чем-то вроде автомобиля класс будет описанием того, как построить автомобиль, а объект будет автомобилем.
Вы описываете, что такое класс с public class Car { ... }
, и создаете экземпляр объекта с помощью Car myCar = new Car();
.
Класс может иметь методы (= функции) и переменные-члены (= данные).
Я просто повторяю эти концепции, потому что код, который вы написали, выглядит так, как будто вы еще не полностью поняли эту концепцию. Пожалуйста, попросите другого студента, который понял это, помочь вам в этом.
Фильтр класс
public class Filter{
String letters;
public Filter(String letters) {
this.letters = letters;
}
public boolean contains (char character){
for(int i = 0; i < letters.length(); i++) {
if(letters.charAt(i) == character)
return true;
}
return false;
}
public String toString (){
return "Filter(" + letters + ")";
}
}
Хорошо, давайте затормозим.
public class Filter{
...
}
Я думаю, вы уже получили эту часть. Здесь вы описываете структуру вашего класса.
String letters;
Это переменная члена класса. Он уникален для каждого объекта, который вы создаете для этого класса. Снова, для деталей, спросите других студентов, которые поняли это.
public Filter(String letters) {
this.letters = letters;
}
Это конструктор. Когда вы создаете свой объект, вызывается эта функция.
В этом случае все, что он делает - это принимает аргумент letters
и сохраняет его в переменной класса letters
. Поскольку они имеют одинаковые имена, вам нужно явно указать java, что левая переменная класса. Вы делаете это, добавляя this.
.
public boolean contains (char character){
for(int i = 0; i < letters.length(); i++) {
if(letters.charAt(i) == character)
return true;
}
return false;
}
Это берет символ и смотрит, содержится ли оно в this.letters
или нет.
Поскольку здесь нет конфликта имен, вы можете опустить this.
.
Если я правильно понял, пропавший static
был одной из ваших проблем. Если у вас static
, функция привязана к классу и не привязана к объекту, то есть вы можете вызывать ее без объекта. Опять же, важно, чтобы вы понимали разницу, а если нет, спросите кого-то. (Чтобы быть точным, спросите разницу между классом, объектом, статическим и нестатическим). Это займет слишком много времени, чтобы объяснить это подробно здесь.
Но в двух словах: если функция не статическая, ее необходимо вызывать для работы объекта. Посмотрите дальше в другом классе, чтобы узнать, как это выглядит.
public String toString (){
return "Filter(" + letters + ")";
}
Эта функция также не является статичной. Он используется всякий раз, когда объект должен быть преобразован в строку, как при вызове System.out.println()
. Опять же, здесь важно понимать разницу между классом и объектом.
QueryResolver класс
public class QueryResolver {
Filter filter;
String query;
public QueryResolver where(String queryStr) {
this.query = queryStr;
return this;
}
public QueryResolver matches(String filterStr) {
this.filter = new Filter(filterStr);
return this;
}
public int count() {
int result = 0;
for(int i = 0; i < query.length(); i++) {
if(filter.contains(query.charAt(i))){
result++;
}
}
return result;
}
}
Опять, давайте разберемся с этим.
public class QueryResolver {
...
}
Тело нашего класса.
Обратите внимание, что у нас здесь нет конструктора. Желательно иметь его, но в этом случае это будет пустая функция без аргументов, которая ничего не делает, поэтому мы можем просто оставить ее, и компилятор автоматически сгенерирует ее.
public QueryResolver where(String queryStr) {
this.query = queryStr;
return this;
}
Это интересная функция. Возвращает указатель this
. Поэтому вы можете использовать результат функции для выполнения другого вызова, что позволит вам объединить несколько вызовов функций вместе, например resolver.where(query).matches(filter).count()
.
Чтобы понять, как это работает, вы должны понимать разницу между классами и объектами и то, что именно делает указатель this
.
Короче говоря, указатель this
- это указатель на объект, в котором в настоящее время живет наша функция.
public QueryResolver matches(String filterStr) {
this.filter = new Filter(filterStr);
return this;
}
Это почти то же самое, что и функция where
.
Интересная часть - new Filter(...)
. Это создает ранее обсужденный Filter
-объект из описания класса и помещает его в переменную QueryResolver
объекта this.filter
.
public int count() {
int result = 0;
for(int i = 0; i < query.length(); i++) {
if(filter.contains(query.charAt(i))){
result++;
}
}
return result;
}
Итерация по переменной query
объекта и проверка каждой буквы, содержится ли она в filter
.Он хранит счет того, сколько раз это происходит, и возвращает счет.
Эта функция требует, чтобы были установлены filter
и query
.Поэтому важно, чтобы, прежде чем кто-то позвонит count()
, он ранее позвонит where(..)
и matches(..)
.В нашем случае все это происходит в одной строке: resolver.where(query).matches(filter).count()
.
main function
Я написал две разные функции main
.Вы хотите как можно больше тестировать свой код во время разработки, поэтому первый, который я написал, был фиксированным, в котором вам не нужно вводить что-то вручную, просто нажмите «Выполнить», и оно работает:
public static void main(String[] args) {
String filter="kjasd";
String query="kjg4t";
QueryResolver resolver = new QueryResolver();
int count = resolver.where(query).matches(filter).count();
System.out.println(count);
}
Как только вы поймете разницу между классами и объектами, это должно быть прямо.Но повторим:
QueryResolver resolver = new QueryResolver();
Это создаст ваш объект QueryResolver и сохранит его в переменной resolver
.
int count = resolver.where(query).matches(filter).count();
Затем эта строка использует объект resolver
для первого вызоваwhere
, matches
и, наконец, count
.Опять же, эта цепочка работает только потому, что мы возвращаем this
в where
и matches
функциях.
Теперь, наконец, интерактивная версия, которую вы создали:
public static void main(String[] args) {
Scanner in =new Scanner(System.in);
System.out.println("please enter the query string! ");
String query= in.next();
System.out.println("please enter the filter stirng!");
String filter= in.next();
System.out.println("the query string is : [" + query+ "]");
System.out.println("the filter string is : [" + filter+ "]");
QueryResolver resolver = new QueryResolver();
int count = resolver.where(query).matches(filter).count();
System.out.println("the characters of the String ["+filter+"] has been found in the forworded string ["+query+"] exactly "+count+" times!" );
in.close();
}