Iterate 3 vectors split contents and assign - java

I have 3 vectors with similar format like the following..
Vector1:
start:231 stop:234 name:xyz
start:331 stop:334 name:abc
start:431 stop:434 name:fds
Vector2 and vector3 also have same format.
I have to iterate the 3 vectors and split the contents and assign to strings or integers.
I have done like the following:
public static Tokens getTokens( Vector<NameBuffer> vc1 ) {
Tokens tokens=new Tokens();
Iterator it1=vc1.iterator();
while(it1.hasNext())
{
String onerecord= it1.next().toString();
StringTokenizer stringTokenizer = new StringTokenizer(onerecord);
while (stringTokenizer.hasMoreElements()) {
String tmp = stringTokenizer.nextToken();
if ( tmp.startsWith("start=")) {
tmp = tmp.substring("start=".length());
try {
int begin = Integer.parseInt(tmp);
tokens.setbegin(begin);
}
catch ( NumberFormatException nfe ) {
nfe.printStackTrace();
}
}
else {
System.err.println("Wrong format");
}
String tmp1 = stringTokenizer.nextToken();
if ( tmp1.startsWith("stop=")) {
tmp1 = tmp1.substring("stop=".length());
try {
int end = Integer.parseInt(tmp1);
tokens.setend(end);
//System.out.println(end);
}
catch ( NumberFormatException nfe ) {
nfe.printStackTrace();
}
}
else {
System.err.println("Wrong format");
}
String tmp2 = stringTokenizer.nextToken();
if ( tmp2.startsWith("name=")) {
tmp2 = tmp2.substring("name=".length());
String name = tmp2;
tokens.setname(name);
}
}
else {
System.err.println("Wrong format");
}
}//while(stringtokenizer.hasmoreElements
System.out.println(tokens);// At this point i was able to print all records
}//while(it1.hasNext()
return tokens; //Is the problem with this return?
}//getTokens
Note:Tokens is a simple Java class with setters and getters like setstart() and gerstart()
In the main method
public static void main(String[] args) {
Tokens fnTokens=getTokens(vector1);
for(i=0;i<firstname.size();i++)
{
System.out.println(fnTokens);// it is printing only last record in my vector
}
}
If I print in the getTokens method itself I was able to get all records, but here only the last record.
My final intention is iterate all 3 vectors and compare the elements like vector1.getstart(),vector1.getend() and vector1.getname()
vector2.getstart(),vector2.getend() and vector2.getname()
vector3.getstart(),vector3.getend() and vector3.getname()
Can some one help me to solve this problem?

You keep overwriting the single Tokens instance you have... In your original code:
Tokens tokens=new Tokens();//create Tokens instance
while(it1.hasNext())
{
// init
while (stringTokenizer.hasMoreElements()) {
// set tokens fields
}
System.out.println(tokens);// You print the current Tokens instance
}//while(it1.hasNext()
return tokens; //only return one, at the last state.
And in the loop, you always print the current state of the Tokens instance, but return only the last.
To solve, change the method around a bit to return all instances, for example in a List:
public static List<Tokens> getTokens( Vector<NameBuffer> vc1 ) {
List<Tokens> tokenList=new ArrayList<Tokens>();//create Tokens list to return
while(it1.hasNext())
{
// init
Tokens tokens=new Tokens();//create Tokens instance inside loop
tokenList.add(tokens); //add to list to return
while (stringTokenizer.hasMoreElements()) {
// set tokens fields -- unchanged
}
System.out.println(tokens);// You print the current Tokens instance
}//while(it1.hasNext()
return tokenList; //only return the last one....
}
And then in the main method:
public static void main(String[] args) {
//...
List<Tokens> fnTokens=getTokens(vector1);
for(Tokens t: fnTokens)
{
System.out.println(t);
}
}

public static Tokens getTokens( Vector<NameBuffer> vc1 ) {
Iterator it1=vc1.iterator();
while(it1.hasNext()) {
String onerecord= it1.next().toString();
//String onerecord="start:231 stop:234 name:xyz";
String ss[]=onerecord.split(":|\\s");
System.out.println(ss[0]+" = "+ss[1]);
System.out.println(ss[2]+" = "+ss[3]);
System.out.println(ss[4]+" = "+ss[5]);
}
}

Related

Sorting names and storing them to an Array cell with LinkedList

So the idea is to get an input which is a String(a name to be specific), then store it in an Array with the size of 26 to its respective cell. The sorting goes this way: names that start with 'A' goes to cell 0, names that start with 'B' goes to cell 1 and so on. Now, a cell contains a LinkedList where the names are sorted again alphabetically.
So far, the approach I made is by using the switch case.
private void addDataAList(AuthorList[] aL, String iN) {
char nD = Character.toUpperCase(iN.charAt(0));
switch(nD){
case 'A':
AuthorList[0] = iN;
break;
case 'B':
AuthorList[1] = iN;
break;
//and so on
}
}//addData
is there a more efficient way to do this?
Assuming that AuthorList class may look like this:
private class AuthorList{
private LinkedList<String> nameList;
public AuthorList() {
}
public AuthorList(LinkedList<String> nameList) {
this.nameList = nameList;
}
public LinkedList<String> getNameList() {
return nameList;
}
public void setNameList(LinkedList<String> nameList) {
this.nameList = nameList;
}
#Override
public String toString() {
final StringBuilder sb = new StringBuilder("AuthorList{");
sb.append("nameList=").append(nameList);
sb.append('}');
return sb.toString();
}
}
I'd make it like this:
private static void addDataAList(AuthorList[] aL, String iN) {
int index = Character.toUpperCase(iN.trim().charAt(0)) - 'A';
try {
AuthorList tmpAuthorList = aL[index];
if(tmpAuthorList == null) aL[index] = tmpAuthorList = new AuthorList(new LinkedList<>());
if(tmpAuthorList.getNameList() == null) tmpAuthorList.setNameList(new LinkedList<>());
tmpAuthorList.getNameList().add(iN);
} catch (ArrayIndexOutOfBoundsException aioobe){
throw new IllegalArgumentException("Name should start with character A - Z");
}
}
And additional main method for test purposes:
public static void main (String[] args){
AuthorList[] aL = new AuthorList[26];
addDataAList(aL, " dudeman");
for (AuthorList list : aL) System.out.println(list);
}

JAVA- Error reading file 1 (error)

I am trying to read a txt file and trying to save it in an array.
following is the format of the txt file:
A B 5
A C 2
A D 4
.....
public class search {
public static void main(String[] args) throws ParseException {
try {
Scanner user_input = new Scanner(System.in); // for user input
System.out.println("Enter the file name: ");
String filename1 = user_input.next();
File file = new File(filename1);
search bd = new search();
Node[] nodes;
nodes = bd.getNodes(file);
bd.printNodes(nodes);
}
catch(Exception e) {
System.out.println("Error reading file " + e.getMessage());
}
}
public Node[] getNodes(File file) throws IOException {
FileReader bd = new FileReader(file);
BufferedReader bufferReader = new BufferedReader(bd);
String line;
ArrayList<Node>list = new ArrayList<Node>();
while ((line = bufferReader.readLine()) != null) {
String[] token = line.split(" "); // create string of tokens
list.add(new Node(token[0], token[1], Integer.parseInt(token[2])));
}
bufferReader.close();
return list.toArray(new Node[list.size()]); // converting list to array
}
public void printNodes(Node[] nodes) {
System.out.println("======================");
for(Node node : nodes) {
System.out.println(node);
}
System.out.println("======================");
}
Following is my Node class
class Node {
String leftchild;
String rightchild;
int cost;
public Node(){
}
public Node(String firstchild, String secondchild, int cost){
this.leftchild = firstchild;
this.rightchild = secondchild;
this.cost = cost;
}
public Node(String firstchild, String secondchild) {
this.leftchild = firstchild;
this.rightchild = secondchild;
}
public ArrayList<String> getChildren(){
ArrayList<String> childNodes = new ArrayList<String>();
if(this.leftchild != null)
{
childNodes.add(leftchild);
}
if(this.rightchild != null) {
childNodes.add(rightchild);
}
return childNodes;
}
public boolean removeChild(Node n){
return false;
}
#Override
public String toString() {
return leftchild +" "+ rightchild;
}
}
I have no compiling issues, but when I run my code, it is giving me error as
error reading file 1
Not sure why. I have tried to change my code in many ways but none of them worked. Could anyone please figure this out for me?
Thanks
If you get an ArrayIndexOutOfBoundsException: 1, it means that you have at least one line in your test input file that doesn't contain any spaces.
Indeed in your code you do String[] token = line.split(" ") which will extract all the tokens separated by a space and put them into an array of String, so if you get this error it means that the length of the array is 1 such that you cannot access to token[1] as it refers to the second element of your array that only contains one element.
So in your case you should test first if the length of the array has the right length as next:
String[] token = line.split(" "); // create string of tokens
if (token.length >= 3) {
list.add(new Node(token[0], token[1], Integer.parseInt(token[2])));
}

Do-While Loop goes infinite

I have an abstract class that contains a variable of type String declared moneyString
String moneyString;
It contains data something like $123,456,789
So inside the abstract class I have function
void convertToInt(){
remove(',');
remove('$');
empMoney = Integer.parseInt(moneyString.substring(0, moneyString.length()) );
}
And my remove function
void remove(char character){
boolean moreFound = true;
String tempString;
int index;
do{
index = moneyString.indexOf(character);
tempString = moneyString;
if(index!=-1){
//From beggining to the character
moneyString = moneyString.substring(0,index);
//After the character to the end
tempString = tempString.substring(index,tempString.length());
moneyString += tempString;
}
else{
moreFound = false;
}
} while(moreFound);
} //END remove()
Isn't it supposed to get out of the loop when when moreFound = false?
The issue with your code is here,
tempString = tempString.substring(index,tempString.length());
Should be index + 1 because you don't want to include that character.
tempString = tempString.substring(index + 1,tempString.length());
But, I suggest you use a DecimalFormat and parse(String) the value. Like,
public static int convertToInt(String money) throws ParseException {
NumberFormat df = new DecimalFormat("$#,###");
return df.parse(money).intValue();
}
Then you can call it like
public static void main(String[] args) {
try {
System.out.println(convertToInt("$123,456,789"));
} catch (ParseException e) {
e.printStackTrace();
}
}
Output is
123456789
Indeed you have to change the line:
tempString = tempString.substring(index,tempString.length());
to:
tempString = tempString.substring(index+1,tempString.length());
The assignment could be done to a variable of type Long:
moneyString="$123,456,789,101";
long empMoney;
remove('$');
remove(',');
empMoney = Long.parseLong(moneyString.substring(0, moneyString.length()) );

Extending my program to report frequency of word in list and its line number?

I've gotten my Java code below to this point. Now what I'm attempting to do is add to it so that it can report, for each word in the list, its frequency (number of times it exists) along with the line numbers where the word occurs.
CODE:
// Concordance
import java.util.*;
// A concordance is a listing of words from a text, with each word being followed the line/page numbers on which the word appears.
public class Concordance
{
private Dictionary dict = new Hashtable();
private boolean allowDupl = true;
public Concordance (boolean allowDupl )
{
this.allowDupl = allowDupl;
} // end Concordance()
public Concordance ( ) { this(true); }
public void enterWord (Object word, Integer line)
{
Vector set = (Vector) dict.get(word);
if (set == null) // word not in dictionary
{
set = new Vector( );
dict.put(word, set); // enter word and empty Vector
}
if (allowDupl || !set.contains(line))
{
set.addElement(line);
}
} // end enterWord()
public Enumeration keys( )
{
return dict.keys( );
} // end keys()
public Enumeration getNumbers (Object word)
{
return ((Vector)dict.get(word)).elements( );
} // end getNumbers()
} // end class Concordance
This is something I've been dabbling with, but Java is not at all my strong-language. Can anyone offer advice on how to proceed?
EDIT:
I've updated my code with the below. For those more familiar with Java, does this look correct?
CODE:
// Concordance
import java.util.*;
// A concordance is a listing of words from a text, with each word being followed the line/page numbers on which the word appears.
public class Concordance
{
private Dictionary dict = new Hashtable();
private boolean allowDupl = true;
public Concordance (boolean allowDupl )
{
this.allowDupl = allowDupl;
} // end Concordance()
public Concordance ( ) { this(true); }
public void enterWord (Object word, Integer line)
{
Vector set = (Vector) dict.get(word);
if (set == null) // word not in dictionary
{
set = new Vector( );
dict.put(word, set); // enter word and empty Vector
}
if (allowDupl || !set.contains(line))
{
set.addElement(line);
}
} // end enterWord()
public void generateOutput(PrintStream output)
{
Enumeration e = dict.keys();
while (e.hasMoreElements())
{
String word = (String) e.nextElement();
Vector set = (Vector) dict.get(word);
output.print(word + ": ");
Enumeration f = set.elements();
}
while (f.hasMoreElements())
{
output.print(f.nextElement() + " ");
output.println("");
}
}
public Enumeration keys( )
{
return dict.keys( );
} // end keys()
public Enumeration getNumbers (Object word)
{
return ((Vector)dict.get(word)).elements( );
} // end getNumbers()
} // end class Concordance
Create a Class DictionaryEntry that has all the attributes you need and then put that into your Dictionary instead of just a set of int for the line numbers.

Trying to get java program to add items to an unaccepted ArrayList

I've written a java picnic game (very basic), the only thing I don't know how to do is get the program not to accept items of the same letter. I also want the program to list how many times the user entered a rejected item. Note that this allows any ordering of items, as long as no two items start with the same letter (dis-
regarding case). An acceptable sequence of inputs would be
mustard
,
ketchup
,
tofu
,
anchovies
.
However,
mustard
,
ketchup
,
tofu
, and
Kettle corn
would not work since \
Kettle corn
" begins
with the same letter as \
ketchup
" (ignoring case).
import java.util.*;
public class PlayPicnic
{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
Picnic picnic = new Picnic();
ArrayList<String> unaccepted = new ArrayList<>();`enter code here`
while (picnic.numberOfItems() < 5)
{
System.out.print("What do you want to bring on the picnic? ");
String item = scan.nextLine();
if (picnic.okayToBring(item))
{
picnic.add(item);
}
else
{
if(!unaccepted.contains(item)) unaccepted.add(item);
System.out.println("Sorry, you can't bring " + item);
}
}
System.out.println("\nHere's what we'll have at the picnic:");
picnic.show();
System.out.println(Arrays.toString(unaccepted.toArray()));
}
}
corresponding class
import java.util.*;
public class Picnic
{
// INSTANCE VARIABLES:
private ArrayList<String> stuffToBring; // items to bring on the picnic
// CONSTRUCTOR:
//-----------------------------------------------------
// Construct a new Picnic.
//-----------------------------------------------------
public Picnic()
{
stuffToBring = new ArrayList<String>(); // initialize list
}
//-----------------------------------------------------
// Given an item s, see if it's okay to add it to the list.
// Return true if it is, false otherwise:
//-----------------------------------------------------
public boolean okayToBring(String s)
{
// "Secret rule" -- s can't be an item already in the list:
if (stuffToBring.contains(s)) // "contains" is in the ArrayList class
{
return false;
}
else
{
return true;
}
}
//-----------------------------------------------------
// Given an item s, add it to the list (if it's okay to add it)
//-----------------------------------------------------
public void add(String s)
{
if (okayToBring(s)) // this test keeps people from cheating!
{
stuffToBring.add(s);
}
}
//-----------------------------------------------------
// Print the items in the list
//-----------------------------------------------------
public void show()
{
for (int i = 0; i < stuffToBring.size(); i++)
{
String s = stuffToBring.get(i);
System.out.println(s);
}
}
//-----------------------------------------------------
// Returns the number of items in the list:
//-----------------------------------------------------
public int numberOfItems()
{
return stuffToBring.size();
}
}
Make a custom Set to remove duplicate, if first char is same(ignoring the case).
Set<String> unaccepted =new TreeSet<>(new Comparator<String>() {
#Override
public int compare(String o1, String o2) {
Character first=Character.toLowerCase(o1.charAt(0));
Character second=Character.toLowerCase(o2.charAt(0));
return first.compareTo(second);
}
});
Now, add the value to this Set. It will ignore the same first Character data.
Change the while loop like below,
while (unaccepted.size()<5){
System.out.print("What do you want to bring on the picnic? ");
String item = scan.nextLine();
unaccepted.add(item);
}
Here is logic for checking for items in list with first char
public boolean checkItem(String input, List<String> items) {
String inputFirstChar = input.substring(0, 1);
boolean exist = false;
for (String item : items) {
String itemFirstChar = item.substring(0, 1);
if(itemFirstChar.equalsIgnoreCase(inputFirstChar)) {
exist = true;
break;
}
}
return exist;
}
private ArrayList<String> stuffToBring;
make your reference variable type with interface not the ArrayList implementation, do like this one
private List<String> stuffToBring;
To reject words with a used first letter, you put a simple String in class "Picnic":
private String usedLetters = "";
Then in method "okayToBring" you check if the letter is already used:
public boolean okayToBring(String s) {
return (usedLetters.indexOf(s.toLowerCase().charAt(0)) == -1); // letter not contained in String
}
and in method "add" you append the new word's first character to this String:
public void add(String s)
{
if (okayToBring(s))
{
stuffToBring.add(s);
usedLetters += s.toLowerCase().charAt(0);
}
}
Regarding your second question, your phrasing is a bit unclear. If you want to count how many times a specific item has been unsuccessfully entered, you could use a Hashmap to store rejected Strings and their count:
private HashMap<String, int> unaccepted = new HashMap<String, int>();
Then your program's "else" clause looks like follows:
int newcount = (unaccepted.containsKey(item) ? unaccepted.get(item)++ : 1);
unaccepted.put(item, newcount);
System.out.println("Sorry, you can't bring " + item + "(" + unaccepted.get(item) + " unsuccessful tries)");
If you just want to count the total number of unsuccessful entries, use a Set and println(unaccepted.size());

Categories

Resources