Java TF-IDF程序文件读取失败及IntelliJ无法运行问题求助
Let's break down and solve both problems you're facing with your TF-IDF implementation:
1. File Not Found Error for arquivo.txt
Why this happens
When you use new File("arquivo.txt") in Java, the JVM looks for the file in the project root directory (the folder containing your src folder), not inside src itself. Since you placed the file in src, the program can't locate it.
Solutions
You have a few reliable options to fix this:
- Option 1 (Simplest): Move
arquivo.txtto your project's root directory (same level as thesrcfolder). - Option 2: Update the file path to point directly to the
srcfolder:String conteudo = readFile("src/arquivo.txt"); - Option 3 (Best for packaged apps): Use the class loader to read the file as a resource (works even when you package your app into a JAR):
Then call it like this:public static String readFile(String filename) { StringBuffer sb = new StringBuffer(); try (Scanner input = new Scanner(Main.class.getResourceAsStream("/" + filename))) { while (input.hasNextLine()) { sb.append(input.nextLine() + "\n"); } } catch (Exception ex) { ex.printStackTrace(); } return sb.toString(); }String conteudo = readFile("arquivo.txt"); // Works if the file is in src (resources root)
2. No Run Option in IntelliJ After Rewriting
Why this happens
The main issue is that your main method isn't static! Java requires the entry point method to follow this exact signature:
public static void main(String[] args)
Your code uses public void main(String[] args) (missing static), so IntelliJ doesn't recognize it as a runnable entry point. Additionally, there are a few other bugs that will cause compile errors:
List wordList = new ArrayList();lacks a generic type (should beList<String>)- Your loop to populate
wordListusesparts[i]instead of the loop variablepart, which can cause index issues - When calling
tfidf(wordList, wordList, "work"), the second parameter expects aList<List<String>>(collection of all documents), but you passed a singleList<String>
Fixed Code
Here's the corrected version of your rewritten code that addresses all these issues:
import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class Main { // Correct main method signature (static) public static void main(String[] args) { List<String> wordList = new ArrayList<>(); // Add proper generic type String conteudo = readFile("src/arquivo.txt"); // Adjust path if you moved the file to root String[] parts = conteudo.split("_"); // Fix loop to use the part variable directly for (String part : parts) { wordList.add(part); } System.out.println(conteudo); System.out.println("Informe o termo:"); Scanner in = new Scanner(System.in); String term = in.nextLine(); // Create a collection of documents (we'll use just one for this demo) List<List<String>> allDocuments = new ArrayList<>(); allDocuments.add(wordList); double actualTfidf = tfidf(wordList, allDocuments, term); System.out.println("O TF-IDF é: " + actualTfidf); in.close(); } // Make helper methods static to be called from the static main method private static double tfidf(List<String> doc, List<List<String>> docs, String term) { return tf(doc, term) * idf(docs, term); } public static String readFile(String filename) { StringBuffer sb = new StringBuffer(); // Use try-with-resources to auto-close the Scanner try (Scanner input = new Scanner(new File(filename))) { while (input.hasNextLine()) { sb.append(input.nextLine() + "\n"); } } catch (Exception ex) { ex.printStackTrace(); } return sb.toString(); } private static double idf(List<List<String>> docs, String term) { double n = 0; for (List<String> doc : docs) { for (String word : doc) { if (term.equalsIgnoreCase(word)) { n++; break; // Count the term only once per document } } } // Avoid division by zero if the term isn't found in any document return Math.log(docs.size() / (n == 0 ? 1 : n)); } private static double tf(List<String> doc, String term) { if (doc.isEmpty()) return 0; double result = 0; for (String word : doc) { if (term.equalsIgnoreCase(word)) result++; } return result / doc.size(); } }
Key Fixes in This Code:
- Added
staticto themainmethod and all helper methods (since static methods can't call non-static methods directly) - Fixed file path handling (adjust to
arquivo.txtif you moved the file to the project root) - Added proper generic types for lists to avoid warnings and errors
- Fixed the word list population loop to use the loop variable correctly
- Created a valid
List<List<String>>for all documents (you can add more documents to this list later) - Added a check to avoid division by zero in the IDF calculation
- Used try-with-resources to auto-close the Scanner (better practice to prevent resource leaks)
内容的提问来源于stack exchange,提问作者DogoLendario Shiba Inu-sama To

