0

私は以前にこの質問をし(スレッドで個別の単語を数える)、コードをより適切にしました。最初の質問で説明したように、ファイルから個別の単語を数える必要があります。

De-Bugは、すべての単語が正しく保存およびソートされていることを示していますが、問題は、すべての単語を読んだ後も継続するTestクラスの無限の「while」ループです(De-bugはいくつかのポイントを理解するのに本当に役立ちました。 ..)。現在、10語以内の小さなファイルでコードをテストしています。

DataSetクラスはほとんど変更されています。

ループから抜け出す方法についてアドバイスが必要です。

テストは次のようになります。

package test;

import java.io.File;
import java.io.IOException;

import junit.framework.Assert;
import junit.framework.TestCase;
import main.DataSet;
import main.WordReader;

public class Test extends TestCase
{

   public void test2() throws IOException
   {
      File words = new File("resources" + File.separator + "test2.txt");

      if (!words.exists())
      {
         System.out.println("File [" + words.getAbsolutePath()
               + "] does not exist");
         Assert.fail();
      }

      WordReader wr = new WordReader(words);
      DataSet ds = new DataSet();

      String nextWord = wr.readNext();
      // This is the loop
      while (nextWord != "" && nextWord != null)
      {
         if (!ds.member(nextWord))
         {
            ds.insert(nextWord);
         }
         nextWord = wr.readNext();
      }
      wr.close();
       System.out.println(ds.toString());
       System.out.println(words.toString() + " contains " + ds.getLength()
       + " distinct words");

   }

}

これが私の更新されたDataSetクラス、特にmember()メソッドですが、ある時点でNullPointerExeptionを取得していたため(理由はわかりません...)、まだわかりません。

package main;

import sort.Sort;

public class DataSet
{

   private String[] data;
   private static final int DEFAULT_VALUE = 200;
   private int nextIndex;
   private Sort bubble;

   public DataSet(int initialCapacity)
   {
      data = new String[initialCapacity];
      nextIndex = 0;
      bubble = new Sort();
   }

   public DataSet()
   {
      this(DEFAULT_VALUE);
      nextIndex = 0;
      bubble = new Sort();
   }

   public void insert(String value)
   {
      if (nextIndex < data.length)
      {
         data[nextIndex] = value;
         nextIndex++;
         bubble.bubble_sort(data, nextIndex);
      }
      else
      {
         expandCapacity();
         insert(value);
      }
   }

   public int getLength()
   {
      return nextIndex + 1;
   }


   public boolean member(String value)
   {
      for (int i = 0; i < data.length; i++)
      {

         if (data[i] != null && nextIndex != 10)
         {
            if (data[i].equals(value))
               return true;
         }
      }
      return false;
   }

   private void expandCapacity()
   {
      String[] larger = new String[data.length * 2];
      for (int i = 0; i < data.length; i++)
      {
         data = larger;
      }
   }
}

WordReaderクラスはあまり変わりませんでした。ArrayListは単純な配列に置き換えられ、保存方法も変更されました。

package main;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class WordReader
{

   private File file;

   private String[] words;

   private int nextFreeIndex;

   private BufferedReader in;

   private int DEFAULT_SIZE = 200;

   private String word;

   public WordReader(File file) throws IOException
   {
      words = new String[DEFAULT_SIZE];
      in = new BufferedReader(new FileReader(file));
      nextFreeIndex = 0;
   }

   public void expand()
   {
      String[] newArray = new String[words.length * 2];
      // System.arraycopy(words, 0, newArray, 0, words.length);
      for (int i = 0; i < words.length; i++)
         newArray[i] = words[i];
      words = newArray;
   }

   public void read() throws IOException
   {

   }

   public String readNext() throws IOException
   {
      char nextCharacter = (char) in.read();

      while (in.ready())
      {
         while (isWhiteSpace(nextCharacter) || !isCharacter(nextCharacter))
         {
            // word = "";
            nextCharacter = (char) in.read();

            if (!in.ready())
            {
               break;
            }
         }

         word = "";
         while (isCharacter(nextCharacter))
         {
            word += nextCharacter;
            nextCharacter = (char) in.read();
         }
         storeWord(word);

         return word;
      }

      return word;
   }

   private void storeWord(String word)
   {
      if (nextFreeIndex < words.length)
      {
         words[nextFreeIndex] = word;
         nextFreeIndex++;
      }
      else
      {
         expand();
         storeWord(word);
      }

   }

   private boolean isWhiteSpace(char next)
   {
      if ((next == ' ') || (next == '\t') || (next == '\n'))
      {
         return true;
      }
      return false;
   }

   private boolean isCharacter(char next)
   {
      if ((next >= 'a') && (next <= 'z'))
      {
         return true;
      }
      if ((next >= 'A') && (next <= 'Z'))
      {
         return true;
      }
      return false;
   }

   public boolean fileExists()
   {
      return file.exists();
   }

   public boolean fileReadable()
   {
      return file.canRead();
   }

   public Object wordsLength()
   {
      return words.length;
   }

   public void close() throws IOException
   {
      in.close();
   }

   public String[] getWords()
   {
      return words;
   }

}

また、文字列のバブルソートクラスが変更されました。

package sort;

public class Sort
{
   public void bubble_sort(String a[], int length)
   {
      for (int j = 0; j < length; j++)
      {
         for (int i = j + 1; i < length; i++)
         {
            if (a[i].compareTo(a[j]) < 0)
            {
               String t = a[j];
               a[j] = a[i];
               a[i] = t;
            }
         }
      }
   }
}
4

1 に答える 1

0

実際にブロックする方法は。だと思いますWordReader.readNext()。私の提案では、Scannerの代わりにを使用することをお勧めBufferedReaderします。これは、ファイルを単語に解析するのに適しています。

あなたのreadNext()方法はそのようにやり直すことができます(スキャンがスキャナーである場合):

public String readNext() {
    if (scan.hasNext()) {
        String word = scan.next();
        if (!word.matches("[A-Za-z]+"))
            word = "";
        storeWord(word);
        return word;
    }
    return null;
}

これは、コードと同じ機能を持ちます(isCharacter()またはを使用せずにisWhitespace()-正規表現(内部matches())は、単語に文字のみが含まれていることを確認します。このisWhitespace()機能は、単語を区切るメソッドに組み込まれnext()ています。追加された機能は、存在する場合にnullを返すことです。ファイルにこれ以上の単語はありません。

これを正しく機能させるには、Testクラスのwhileループを変更する必要があります。そうしないとNullPointerException、ループ定義の2つの条件を切り替えるだけです(常にnullを確認するか、最初の条件でNPEを指定します。 nullチェックは役に立ちません)。

スキャナーを作成するにはBufferedReader、パラメーターとして、またはFile直接使用することができます。

Scanner scan = new Scanner(file); 
于 2013-03-23T15:00:21.477 に答える