Поиск похожих слов
Я создал этот похожий поиск слов для развлечения. (word.txt — это слова из http://www.mieliestronk.com/corncob_lowercase.txt) Есть ли способ сделать это лучше или точнее?
import java.util.*;
import java.io.*;
class Main {
public static void print(String text, int times) {
for (int i = 0; i < times; i++) {
System.out.print(text);
}
}
public static void println(String text, int times) {
for (int i = 0; i < times; i++) {
System.out.println(text);
}
}
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList();
try {
BufferedReader reader = new BufferedReader(new FileReader("word.txt"));
String line = null;
while ((line = reader.readLine()) != null) {
arrayList.add(line);
}
println("Welcome to similar word finder. This program searches 58100 different words for words that are similar to the word that you entered",1);
print("Enter a word: ", 1);
Scanner scanner = new Scanner(System.in);
String checkWord = scanner.nextLine();
for (int i = 0; i < checkWord.length(); i++) {
// checks whether the character is not a letter
// if it is not a letter ,it will return false
if ((Character.isLetter(checkWord.charAt(i)) == false)) {
println("Your word contains a not-unicode letter!",1);
System.exit(1);
}
}
ArrayList<String> similarwords = new ArrayList<>();
print("How strict do you want the search to be? (1) Very Strict (2) Normal strict (3) Not very strict: ",1);
String strict = scanner.nextLine();
//println(arrayList.toString(),1);
int minus = 0;
if (strict == "1") {
minus = 1;
} else {
if (strict=="2") {
minus = 2;
} else {
if (strict=="3") {
minus = 3;
} else {
minus =2;
}
}
}
int timesRight = 0;
int timesRight2 = 0;
if (checkWord.length() > 3) {
timesRight2 = checkWord.length()-minus;
println("Similar Words:", 1);
} else {
if (checkWord.length() > 2) {
timesRight2=checkWord.length();
}else {
timesRight=2;
}
}
checkWord = checkWord.trim();
try {
String[] letters = checkWord.split("");
for (String word3 : arrayList) {
timesRight=0;
String[] letters2 = word3.split("");
int under = 0;
if (letters.length<=letters2.length) {
under = letters.length;
} else {
under = letters2.length;
}
for(int i = 0; i < under;i++) {
if (letters2[i].equals(letters[i])) {
timesRight++;
} else {
if(i<letters2.length-2 && i<letters.length-2){
if (letters2[i+1].equals(letters[i])) {
timesRight++;
}
}
}
}
if (timesRight>timesRight2) {
if
if (word3 != checkWord) {
//System.out.println(checkWord);
similarwords.add(word3);
println(word3 +" #" + similarwords.size() , 1);
}else {
println(word3 + " (search word)",1);
}
} else {
//println("x",1);
}
}
} catch (Exception e) {
System.err.println("Error!: " + e);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
1 ответ
Если вы хотите, чтобы соответствие слов было более точным, поищите сопоставление Soundex.
Я работал над тем, чтобы сделать ваш код более читабельным для обычных людей.
Я не мог понять, как вы подбираете слова. Я предположил, что вы выбираете слова на основе количества буквенных различий.
Как правило, когда вы пишете класс Java, его следует читать как эссе. Самая важная информация находится в начале, и по мере продвижения по коду вы видите все больше и больше деталей. Детали, представленные в виде небольших кусочков, которые мы называем методами.
Почти весь ваш код был в одном основном методе. Мне было трудно следовать вашему коду, и, как я уже сказал, я отказался от попыток выяснить, как вы сравниваете слова, и просто написал свой собственный код.
Вот основной метод, который я написал, чтобы найти похожие слова.
public void findSimilarWords() {
List<String> wordList = readWordList();
Scanner scanner = new Scanner(System.in);
String checkword = readWord(scanner);
int level = readStrictLevel(scanner);
List<String> matchingWords = findMatchingWords(
wordList, checkword, level);
createOutput(checkword, matchingWords);
scanner.close();
}
Семь строк кода. Сейчас мы не знаем деталей. Мы знаем, что есть список слов, что мы получаем слово и уровень соответствия с консоли и выводим совпадающие слова. На данный момент это все, что нам нужно знать.
Подробности мы узнаем по мере чтения кода класса.
Думаю, я высказал свою точку зрения. Вот исправленный код. Я надеюсь, что вам будет легче понять этот код и, что более важно, его легче изменить. Код предназначен не только для компьютеров. Люди тоже должны читать и понимать код. Включая вас по прошествии времени.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class SimilarWordFinder {
public static void main(String[] args) {
SimilarWordFinder swf = new SimilarWordFinder();
swf.findSimilarWords();
}
public void findSimilarWords() {
List<String> wordList = readWordList();
Scanner scanner = new Scanner(System.in);
String checkword = readWord(scanner);
int level = readStrictLevel(scanner);
List<String> matchingWords = findMatchingWords(
wordList, checkword, level);
createOutput(checkword, matchingWords);
scanner.close();
}
private List<String> readWordList() {
List<String> wordList = new ArrayList<>();
try {
URL url = new URL("https://www.mieliestronk.com/"
+ "corncob_lowercase.txt");
BufferedReader reader = new BufferedReader(
new InputStreamReader(url.openStream()));
String line = reader.readLine();
while (line != null) {
wordList.add(line.trim());
line = reader.readLine();
}
reader.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return wordList;
}
private String readWord(Scanner scanner) {
println("Welcome to similar word finder. This program "
+ "searches 58,100 different words for words that "
+ "are similar to the word that you entered",
1);
boolean invalidWord = true;
String checkWord = "";
while (invalidWord) {
print("Enter a word: ", 1);
checkWord = scanner.nextLine();
invalidWord = false;
for (int i = 0; i < checkWord.length(); i++) {
// checks whether the character is not a letter
// if it is not a letter ,it will return false
if (!Character.isLetter(checkWord.charAt(i))) {
println("Your word contains a not-unicode letter!", 1);
invalidWord = true;
break;
}
}
}
return checkWord;
}
private int readStrictLevel(Scanner scanner) {
print("How strict do you want the search to be? (1) Very "
+ "Strict (2) Normal strict (3) Not very strict: ",
1);
String strict = scanner.nextLine();
return valueOf(strict);
}
private List<String> findMatchingWords(List<String> wordList,
String word, int level) {
List<String> similarWords = new ArrayList<>();
for (String matchWord : wordList) {
if (matchWord.length() == word.length()) {
int difference = calculateWordDifference(word, matchWord);
if (difference <= level) {
similarWords.add(matchWord);
}
}
}
return similarWords;
}
private int calculateWordDifference(String word, String matchWord) {
int difference = 0;
for (int i = 0; i < word.length(); i++) {
if (word.charAt(i) != matchWord.charAt(i)) {
difference++;
}
}
return difference;
}
private void createOutput(String word, List<String> matchingWords) {
println(" ", 1);
println("The following words match "" + word + """, 1);
println(" ", 1);
for (String matchingWord : matchingWords) {
println(" " + matchingWord, 1);
}
}
private void print(String text, int times) {
for (int i = 0; i < times; i++) {
System.out.print(text);
}
}
private void println(String text, int times) {
for (int i = 0; i < times; i++) {
System.out.println(text);
}
}
private int valueOf(String number) {
try {
return Integer.valueOf(number);
} catch (NumberFormatException e) {
return 2;
}
}
}