Use of Vectors in java
I've been working on this problem and it involves the implementation of the markov chain algorithm in java. It gives me an error when I assign the variable r the value of a vector's element. (Line 54).The error reads "array required but java.unit.Vector found). The code is pasted below.
import java.io.*;
import java.util.*;
class Chain {
static final int NPREF = 2; // size of prefix
static final String NONWORD = "\n";
// "word" that can't appear
Hashtable statetab = new Hashtable();
// key = Prefix, value = suffix Vector
Prefix prefix = new Prefix(NPREF, NONWORD);
// initial prefix
//Random rand = new Random();
// Chain build: build State table from input stream
void build(BufferedReader in) throws IOException
{
StreamTokenizer st = new StreamTokenizer(in);
st.resetSyntax(); // remove default rules
st.wordChars(0, Character.MAX_VALUE); // turn on all chars
st.whitespaceChars(0, ' '); // except up to blank
while (st.nextToken() != st.TT_EOF)开发者_C百科
add(st.sval);
add(NONWORD);
}
// Chain add: add word to suffix list, update prefix
void add(String word)
{
Vector suf = (Vector) statetab.get(prefix);
if (suf == null) {
suf = new Vector();
statetab.put(new Prefix(prefix), suf);
}
suf.addElement(word);
prefix.pref.removeElementAt(0);
prefix.pref.addElement(word);
}
// Chain generate: generate output words
void generate(int nwords, PrintWriter out, Vector <Integer> random_num)
{
prefix = new Prefix(NPREF, NONWORD);
for (int i = 0; i < nwords; i++) {
Vector s = (Vector) statetab.get(prefix);
if (s == null) {
System.err.println("Markov: internal error: no state");
System.exit(1);
}
final int r = (random_num.get(i) % s.size());
String suf = (String) s.elementAt(r);
if (suf.equals(NONWORD))
break;
out.println(suf);
prefix.pref.removeElementAt(0);
prefix.pref.addElement(suf);
}
}
}
class Prefix {
public Vector pref; // NPREF adjacent words from input
static final int MULTIPLIER = 31; // for hashCode()
// Prefix constructor: duplicate existing prefix
Prefix(Prefix p)
{
pref = (Vector) p.pref.clone();
}
// Prefix constructor: n copies of str
Prefix(int n, String str)
{
pref = new Vector();
for (int i = 0; i < n; i++)
pref.addElement(str);
}
// Prefix hashCode: generate hash from all prefix words
public int hashCode()
{
int h = 0;
for (int i = 0; i < pref.size(); i++)
h = MULTIPLIER * h + pref.elementAt(i).hashCode();
return h;
}
// Prefix equals: compare two prefixes for equal words
public boolean equals(Object o)
{
Prefix p = (Prefix) o;
for (int i = 0; i < pref.size(); i++)
if (!pref.elementAt(i).equals(p.pref.elementAt(i)))
return false;
return true;
}
}
class Markov {
static final int MAXGEN = 10000; // maximum words generated
static Vector <Integer> random_num = new Vector <Integer>();
static BufferedReader random_reader;
public static void main(String[] args) throws IOException
{
BufferedReader in = new BufferedReader (new FileReader ("../alice30.txt"));
PrintWriter out = new PrintWriter (new FileWriter ("../output/markov_java_out.txt"));
BufferedReader random_reader = new BufferedReader (new FileReader ("../random_num.txt"));
String s;
s= random_reader.readLine();
while(s != null)
{
int element = Integer.parseInt(s.trim());
random_num.addElement(new Integer(element));
s = random_reader.readLine();
}
Chain chain = new Chain();
int nwords = MAXGEN;
chain.build(in);
in.close();
chain.generate(nwords,out, random_num);
out.close();
}
}
Did you mean random_num.elementAt(i)
?
The code that you pasted will not compile because you use array syntax on a Vector
. In Markov declare the Vector
like this:
static Vector<Integer> random_num = new Vector<Integer>();
Also change the parameters to method generate(...)
to match, and finally fix this method by treating random_num
like a Vector
, not an array:
final int r = (random_num.get(i) % s.size());
As a side note, I noticed you aren't taking advantage of Java 5's ability to type your collections. This can prevent the need for explicit casting, and it's generally considered good practice. Try declaring your Hashtable like this:
Hashtable<Prefix, Vector<String>> statetab = new Hashtable<Prefix, Vector<String>>();
Read this for reference
Here's the code with everything fixed up except the copy constructor, which you need to give more thought to:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.Hashtable;
import java.util.List;
import java.util.Vector;
class Chain {
static final int NPREF = 2;
static final String NONWORD = "\n";
Hashtable<Prefix, Vector<String>> statetab = new Hashtable<Prefix, Vector<String>>();
Prefix prefix = new Prefix(NPREF, NONWORD);
void build(final BufferedReader in)
throws IOException {
final StreamTokenizer st = new StreamTokenizer(in);
st.resetSyntax(); // remove default rules
st.wordChars(0, Character.MAX_VALUE); // turn on all chars
st.whitespaceChars(0, ' '); // except up to blank
while (st.nextToken() != StreamTokenizer.TT_EOF) {
add(st.sval);
}
add(NONWORD);
}
// Chain add: add word to suffix list, update prefix
void add(final String word) {
Vector<String> suf = this.statetab.get(this.prefix);
if (suf == null) {
suf = new Vector<String>();
this.statetab.put(new Prefix(this.prefix), suf);
}
suf.addElement(word);
this.prefix.pref.removeElementAt(0);
this.prefix.pref.addElement(word);
}
// Chain generate: generate output words
void generate(final int nwords, final PrintWriter out, final List<Integer> random_num) {
this.prefix = new Prefix(NPREF, NONWORD);
for (int i = 0; i < nwords; i++) {
final Vector<String> s = this.statetab.get(this.prefix);
if (s == null) {
System.err.println("Markov: internal error: no state");
System.exit(1);
}
final int r = (random_num.get(i) % s.size());
final String suf = (String) s.elementAt(r);
if (suf.equals(NONWORD)) {
break;
}
out.println(suf);
this.prefix.pref.removeElementAt(0);
this.prefix.pref.addElement(suf);
}
}
}
class Prefix {
public Vector<String> pref; // NPREF adjacent words from input
static final int MULTIPLIER = 31; // for hashCode()
// Prefix constructor: duplicate existing prefix
Prefix(final Prefix p) {
//this.pref = p.pref.clone();
}
// Prefix constructor: n copies of str
Prefix(final int n, final String str) {
this.pref = new Vector<String>();
for (int i = 0; i < n; i++) {
this.pref.addElement(str);
}
}
// Prefix hashCode: generate hash from all prefix words
@Override
public int hashCode() {
int h = 0;
for (int i = 0; i < this.pref.size(); i++) {
h = MULTIPLIER * h + this.pref.elementAt(i).hashCode();
}
return h;
}
// Prefix equals: compare two prefixes for equal words
@Override
public boolean equals(final Object o) {
final Prefix p = (Prefix) o;
for (int i = 0; i < this.pref.size(); i++) {
if (!this.pref.elementAt(i).equals(p.pref.elementAt(i))) {
return false;
}
}
return true;
}
}
public class Markov {
static final int MAXGEN = 10000; // maximum words generated
static List<Integer> random_num = new Vector<Integer>();
static BufferedReader random_reader;
public static void main(final String[] args)
throws IOException {
final BufferedReader in = new BufferedReader(new FileReader("../alice30.txt"));
final PrintWriter out = new PrintWriter(new FileWriter("../output/markov_java_out.txt"));
final BufferedReader random_reader = new BufferedReader(new FileReader("../random_num.txt"));
String s;
s = random_reader.readLine();
while (s != null) {
final int element = Integer.parseInt(s.trim());
random_num.add(new Integer(element));
s = random_reader.readLine();
}
final Chain chain = new Chain();
final int nwords = MAXGEN;
chain.build(in);
in.close();
chain.generate(nwords, out, random_num);
out.close();
}
}
Try this:
import java.io.*;
import java.util.Hashtable;
import java.util.Vector;
class Chain
{
static final int NPREF = 2; // size of prefix
static final String NONWORD = "\n";
// "word" that can't appear
Hashtable statetab = new Hashtable();
// key = Prefix, value = suffix Vector
Prefix prefix = new Prefix(NPREF, NONWORD);
// initial prefix
//Random rand = new Random();
// Chain build: build State table from input stream
void build(BufferedReader in) throws IOException
{
StreamTokenizer st = new StreamTokenizer(in);
st.resetSyntax(); // remove default rules
st.wordChars(0, Character.MAX_VALUE); // turn on all chars
st.whitespaceChars(0, ' '); // except up to blank
while (st.nextToken() != st.TT_EOF)
{
add(st.sval);
}
add(NONWORD);
}
// Chain add: add word to suffix list, update prefix
void add(String word)
{
Vector suf = (Vector) statetab.get(prefix);
if (suf == null)
{
suf = new Vector();
statetab.put(new Prefix(prefix), suf);
}
suf.addElement(word);
prefix.pref.removeElementAt(0);
prefix.pref.addElement(word);
}
// Chain generate: generate output words
void generate(int nwords, PrintWriter out, Vector random_num)
{
prefix = new Prefix(NPREF, NONWORD);
for (int i = 0; i < nwords; i++)
{
Vector s = (Vector) statetab.get(prefix);
if (s == null)
{
System.err.println("Markov: internal error: no state");
System.exit(1);
}
int r = ((Integer)random_num.get(i) % s.size());
String suf = (String) s.elementAt(r);
if (suf.equals(NONWORD))
{
break;
}
out.println(suf);
prefix.pref.removeElementAt(0);
prefix.pref.addElement(suf);
}
}
}
class Prefix
{
public Vector pref; // NPREF adjacent words from input
static final int MULTIPLIER = 31; // for hashCode()
// Prefix constructor: duplicate existing prefix
Prefix(Prefix p)
{
pref = (Vector) p.pref.clone();
}
// Prefix constructor: n copies of str
Prefix(int n, String str)
{
pref = new Vector();
for (int i = 0; i < n; i++)
{
pref.addElement(str);
}
}
// Prefix hashCode: generate hash from all prefix words
public int hashCode()
{
int h = 0;
for (int i = 0; i < pref.size(); i++)
{
h = MULTIPLIER * h + pref.elementAt(i).hashCode();
}
return h;
}
// Prefix equals: compare two prefixes for equal words
public boolean equals(Object o)
{
Prefix p = (Prefix) o;
for (int i = 0; i < pref.size(); i++)
{
if (!pref.elementAt(i).equals(p.pref.elementAt(i)))
{
return false;
}
}
return true;
}
}
class Markov
{
static final int MAXGEN = 10000; // maximum words generated
static Vector random_num = new Vector();
static BufferedReader random_reader;
public static void main(String[] args) throws IOException
{
BufferedReader in = new BufferedReader(new FileReader("../alice30.txt"));
PrintWriter out = new PrintWriter(new FileWriter("../output/markov_java_out.txt"));
BufferedReader random_reader = new BufferedReader(new FileReader("../random_num.txt"));
String s;
s = random_reader.readLine();
while (s != null)
{
int element = Integer.parseInt(s.trim());
random_num.addElement(new Integer(element));
s = random_reader.readLine();
}
Chain chain = new Chain();
int nwords = MAXGEN;
chain.build(in);
in.close();
chain.generate(nwords, out, random_num);
out.close();
}
}
I'd recommend trying ArrayList<Integer>
instead of Vector
.
I can't run your code because I don't have files like "alice30.txt", but this snippet runs fine as written:
import java.util.Arrays;
import java.util.List;
import java.util.Vector;
public class Junk
{
public static void main(String[] args)
{
Vector random_num = new Vector()
{{
add(4);
add(3);
add(1);
}};
int i = 1;
List<Integer> s = Arrays.asList(new Integer []{1, 2, 3, 4, 5});
// The next line looks just like the one I gave you
int r = ((Integer)random_num.get(i) % s.size());
System.out.println(r);
}
}
精彩评论