1

现在我想存储一个像这样的文本文件:

1个苹果

2根香蕉

3橙

4 猞猁

5 卡布奇诺

等等变成一个数据结构。最好的方法是以某种方式将 int 映射到字符串,还是我应该创建一个数组列表?当我存储单词本身时,我应该忽略 int 和任何空格,只保留单词本身。成行阅读时如何忽略 int?这是我现在破解的代码:

  public Dictionary(String filename) throws IOException {
  if (filename==null)
      throw new IllegalArgumentException("Null filename");
  else{
      try {
            BufferedReader in = new BufferedReader(new FileReader(filename));
            String str;
            int numLines=0;
            while ((str = in.readLine()) != null) {
                numLines++;
            }
            String[] words=new String[numLines];
            for (int i=0; i<words.length;i++){
                words[i]=in.readLine();
            }

            in.close();
        } catch (IOException e) {
    }
  }

}

提前感谢您的帮助!!

4

7 回答 7

2

I suggest you use a List of items to store the results parsed from the file. One way to parse every text line is to use the String.split(String) method. Also note that you should handle exceptions in the code properly and do not forget to close the Reader when you are done (no matter whether flawlessly or with an exception => use a finally block). The following example should put you on track... Hope this helps.


package test;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;


public class Main {

  public static void main(String[] args) throws IOException {
    Main m = new Main();
    m.start("test.txt");
  }

  private void start(String filename) throws IOException {
    System.out.println(readFromFile(filename));
  }

  private final class Item {
    private String name;
    private int id;
    public Item(String name, int id) {
      this.name = name;
      this.id = id;
    }
    public int getId() {
      return id;
    }
    public String getName() {
      return name;
    }
    @Override
    public String toString() {
      return "Item [name=" + name + ", id=" + id + "]";
    }
  }

  private List<Item> readFromFile(String filename) throws IOException {
    List<Item> items = new ArrayList<Item>();
    Reader r = null;
    try {
      r = new FileReader(filename);
      BufferedReader br = new BufferedReader(r);
      String line = null;
      while ((line = br.readLine()) != null) {
        String[] lineItems = line.split(" ");
        if (lineItems.length != 2) {
          throw new IOException("Incorrect input file data format! Two space separated items expected on every line!");
        }
        try {
          int id = Integer.parseInt(lineItems[0]);
          Item i = new Item(lineItems[1], id);
          items.add(i);
        } catch (NumberFormatException ex) {
          throw new IOException("Incorrect input file data format!", ex); // JDK6+
        }
      }
    } finally {
      if (r != null) {
        r.close();
      }
    }
    return items;
  }

}

于 2012-04-08T18:33:30.687 回答
2

这将不起作用,因为您已经在文件末尾,因此 in.readLine() 方法将返回 null。

我会使用 Map 来存储名称和数量......像这样:

HashMap<String, Integer> map = new HashMap<String, Integer>();

while( (line = br.readLine() !=null){
    //also check if the array is null and the right size, trim, etc.
    String[] tmp = line.split(" ");
    map.put(tmp[1], Integer.parseInt(tmp[0]) );
}

否则,您可以使用 Scanner 类进行尝试。祝你好运。

于 2012-04-08T18:14:34.990 回答
2

只需实现正则表达式的强大功能:

List texts<String> = new ArrayList<String>();
Pattern pattern = Pattern.compile("[^0-9\\s]+"); 
String text = "1 apple 2 oranges 3 carrots"; 
Matcher matcher = pattern.matcher(text); 

while (matcher.find()) { 
  texts.add(matcher.group(0)); 
} 

如今,正则表达式非常流行。compile 方法用于编译您的搜索模式,您在参数中看到的数字是为了防止它们出现在您的搜索中。所以它是完全安全的。使用 apache 的 IOUtilities 将文本文件转换为字符串

于 2012-04-08T18:22:55.930 回答
2

你可以regular expressions试一试。

Pattern p = Pattern.compile("[^0-9\\s]+");
String s = "1 apple 2 oranges";

Matcher m = p.matcher(s);

while (m.find()) {
  System.out.println(m.group(0));
}

输出 =

苹果

橘子

了解正则表达式Java regex tutorial

于 2012-04-08T18:16:39.590 回答
0

如果您的单词不包含空格,则可以使用String.split( " " )将其拆分为由空格分隔String的数组。Strings

然后只取数组的第二个元素(第一个元素是数字)。

此外,该String.trim( )方法将删除String.

注意:可能有一些您想要执行的错误检查(如果String没有按照您的预期格式化怎么办)。但是这个代码片段给出了基本的想法:

...
String s = in.readLine( );
String[] tokens = s.split( " " );
words[i] = tokens[1].trim( );
...
于 2012-04-08T18:12:50.640 回答
0

如果您想做一些简单的事情,只需通过计算数字来对原始工作进行子串:

int t = 0;
while (word.charAt(t) >= '0' && word.charAt(t) <= '9')
  ++t;

word = word.substring(t);

如果单词从不包含空格,您也可以使用word.split(" ")[1]

于 2012-04-08T18:13:50.427 回答
0

不使用缓冲区读取器,而是使用 Scanner 类,而不是使用 Array,而是使用 ArrayList,如下所示:

import java.util.Scanner;
import java.util.ArrayList;

public class Dictionary {
  private ArrayList strings = new ArrayList();

code...

public Dictionary(String fileName) throws IOException {

code...

try {
  Scanner inFile = new Scanner(new fileRead(fileName));

  ArrayList.add("Dummy"); // Dummy value to make the index start at 1
  while(inFile.hasNext()) {
    int n = inFile.nextInt(); // this line just reads in the int from the file and
                              // doesn't do anything with it
    String s = inFile.nextLine().trim();

    strings.add(s);
    }
  inFile.close(); // don't forget to close the file
}

然后由于您的数据为 1、2、3、4、5,您可以只使用索引来检索每个项目的编号。

通过做这个:

for(int i = 1; i < strings.size(); i++) {
int n = i;
String s = n + " " + strings.get(i);
System.out.println(s);
}
于 2012-04-08T18:41:08.353 回答