Finite State Machine Program invalid output - java

I am working on a project and my code isn't working not sure why. Given the test program and general class I need a program that satisfies the following logical regular epxression:
L1: For alphabet {a,b}, all strings that contain an odd number of a's and exactly one b.
Test input: aabaaaa, aaabaaaa, aabaaaab, baaaaaa, aaaaabaa
What it should be:
aabaaaa False
aaabaaaa True
aabaaaab false
baaaaaa false
aaaaabaa True
Program output:
(ture, true, true, false, true)
My Test program:
import java.util.Scanner;
// Test Finite State Machine Class
public class TestFSML1
{
public static void main(String[] args){
String A = "ab";
int[][] ST = {{1,3,0},
{1,2,1},
{2,2,2},
{3,3,3}};
int[] AS = {0,0,1,0};
Scanner in = new Scanner(System.in);
String inString;
boolean accept1 = false;
FSM FSM1 = new FSM(A, ST, AS);
// Input string is command line parameter
System.out.println(" Input Accepted:");
for(int i=0;i<args.length;i++) {
inString = args[i];
accept1 = FSM1.validString(inString);
System.out.printf("%10s%13s\n",inString, accept1);
}
} // end main
} // end class
FSM Class
// Finite State Machine Class
public class FSM
{
// Instance variables
public String alphabet;
public int stateTrans[][];
public int acceptState[];
private int cstate;
// Constructor function
public FSM(String A, int[][] ST, int[] AS)
{
int NSYMBOLS = A.length();
int NSTATES = AS.length;
// Alphabet
alphabet = "" + A;
// State transition table
stateTrans = new int[NSTATES][NSYMBOLS];
for(int r = 0; r < NSTATES; r++)
for(int c = 0; c < NSYMBOLS; c++)
stateTrans[r][c] = ST[r][c];
// Accept states
acceptState = new int[NSTATES];
for(int r = 0; r < NSTATES; r++)
acceptState[r] = AS[r];
// Start state
cstate = 0;
}
// Methods
public int getState()
{
return cstate;
}
public void setState(int state)
{
cstate = state;
return;
}
public int nextState(char symbol)
{
int nstate = -1;
int col = alphabet.indexOf(symbol);
if(col >= 0)
nstate = stateTrans[cstate][col];
return nstate;
}
public boolean accept(int state)
{
if(state < 0)
return false;
return (acceptState[state] != 0);
}
public boolean validString(String word)
{
cstate = 0;
for(int k = 0; k < word.length(); k++){
cstate = nextState(word.charAt(k));
System.out.print(cstate);
System.out.println(" " + word.charAt(k));
if(cstate < 0)
return false;
}
return accept(cstate);
}
} // end class
Thanks!

Here's a simple method I typed up to perform the task you wanted.
public static boolean validWord(String s) {
int aCounter = 0;
int bCounter = 0;
char c;
for (int i = 0; i < s.length(); i++) {
c = s.charAt(i);
if ((int) c == (int) 'a') {
aCounter++;
} else {
bCounter++;
}
}
return (aCounter % 2 == 1 && bCounter == 1);
}
I had trouble understanding how you were implementing your method, and I think it could be much simpler. I'm sure the instance variables you included in the FSM class serve some other use, but I you don't really need any of them to analyze the string. Just use something like this, it should be easy enough to integrate into your code as all it takes is the string. Hope this helps!

Related

How do I avoid making methods and variables static in this code?

I was solving past exams for my java class and I'm struggling with one of them. I keep getting wrong result and I think its because all of classes and instance variables are static. How do I avoid making them static? Also this question basically wants you to find same letters of the location given in args[1] and convert them to the "S" if they are near of the given location (Args are "K,K,K,Y-K,Y,M,M-K,Y,Y,Y 2,1 S" if you need)
public class MatrixRefill {
public static String[][] matrix;
public static int rows;
public static int cols;
public static String enemy;
public static String target;
public static void main(String[] args) {
target = args[2];
rows = Integer.parseInt(args[1].substring(0,1));
cols = Integer.parseInt(args[1].substring(2));
matrix = matrixCreator(args[0]);
enemy = matrix[rows][cols];
recursive(rows, cols, target);
printer(matrix);
}
public static String[][] matrixCreator(String mx) {
int ro = 0;
int co = 0;
for (int i = 0; i < mx.length(); i++) {
if (mx.substring(i,i+1).equals(","))
co++;
if (mx.substring(i,i+1).equals("-"))
ro++;
}
String[][] matriks = new String[ro+1][co/3+1];
ro = 0;
co = 0;
for (int j = 0; j < mx.length(); j++) {
if (mx.substring(j,j+1).equals(","))
co++;
else if (mx.substring(j,j+1).equals("-")) {
ro++;
co = 0;
}
else
matriks[ro][co] = mx.substring(j,j+1);
}
return matriks;
}
public static void recursive(int row, int col, String target) {
if (valid(row,col)) {
recursive(row+1,col, target);
recursive(row,col+1, target);
recursive(row,col-1, target);
recursive(row-1,col, target);
matrix[row][col] = target;
}
}
public static boolean valid(int row, int col) {
boolean result = false;
if (row >= 0 && row < matrix.length && col >= 0 && col < matrix[row].length)
if (matrix[row][col] == enemy)
result = true;
return result;
}
public static void printer(String[][] owo) {
for(int i = 0; i < owo.length; i++) {
for(int j = 0; j < owo[i].length; j++) {
System.out.print(owo[i][j]);
if(j < owo[i].length - 1)
System.out.print(" ");
}
System.out.println();
}
}
}
Remove the static keyword from your methods and instance fields. But to call them from within main you need to create an instance of the containing class (in this case the one that contains the main method) and use that to call the other methods. What I do sometimes is to create an instance method (i.e. non-static) and call that to start the process. Then everything that would be in main I would put in that method. Here is an example.
public static void main(String[] args) {
MatrixRefill mr = new MatrixRefill();
mr.start();
}
public void start() {
target = args[2];
rows = Integer.parseInt(args[1].substring(0,1));
cols = Integer.parseInt(args[1].substring(2));
matrix = matrixCreator(args[0]);
enemy = matrix[rows][cols];
recursive(rows, cols, target);
printer(matrix);
}
// rest of code here
}
By putting what was in main in the start method you can call the other instance methods and access instance fields without qualifying them with a reference to the class (i.e. in this case prefixing with mr.)

How does the scope of this private method work?

My question is: how can I see the Tuple result in the process method if it was created in the check method? How am I able to use it there, if it was created in a private method?
public class Problem13 {
private Tuple<Integer> costs;
private Tuple<String> names;
private Tuple<Integer> result;
private int budget;
private int minDelta, minCost, totalCost;
public void process(String fileName) {
if (!read(fileName))
return;
if (budget >= totalCost) {
System.out.println("You can buy all items");
return;
}
if (budget < minCost) {
System.out.println("You cannot buy items");
return;
}
minDelta = -1;
int n = costs.getLength();
Set<Integer> interval = new IntegerInterval(0, n - 1);
for (int k = n - 1; k > 0; --k) {
Combinations<Integer> combinations = new Combinations<Integer>(interval, k);
combinations.produce((tuple) -> !check(tuple));
if (minDelta == 0)
break;
}
if (result == null)
System.out.println("No solution found");
else {
int k = result.getLength();
for (int j = 0; j < k; ++j)
System.out.printf("%s ", names.get(result.get(j)));
System.out.printf("(%d)\n", minDelta);
}
}
public static void main(String[] args) {
new Problem13().process("data/input13.txt");
}
private boolean check(Tuple<Integer> tuple) {
int k = tuple.getLength();
int currentCost = 0;
for (int i = 0; i < k; ++i) {
int j = tuple.get(i);
currentCost += costs.get(j);
if (currentCost > budget)
return false;
}
int d = budget - currentCost;
if (minDelta < 0 || d < minDelta) {
minDelta = d;
result = new ArrayTuple<>(k);
for (int i = 0; i < k; ++i)
result.set(i, tuple.get(i));
}
return minDelta == 0;
}
private means private to the class. So Problem13 can see anything defined in that class, whether private, public, protected or package private.
Also, the access modifier of the method only affects who can call it, not where the results can be seen. For instance, if result was defined as a public field, any class (not just Problem13) could see it.
You can find many good breakdowns of access modifiers out there on the Interwebs. Here's one.

How do I call a private method with arguments

I'm having an extremely difficult time getting a private method with arguments to be usable in my toString method but have no idea how to get the two methods to cooperate.
main class:
import static java.lang.System.*;
public class Triples
{
private int number;
public Triples()
{
//this(0);
}
public Triples(int num)
{
number = num;
}
public void setNum(int num)
{
number = num;
}
private int greatestCommonFactor(int a, int b, int c)
{
int max = number;
for(int n = 1; n <= max; n++)
{
for(a = n; a <= max; a++)
{
a = n;
for(b = a +1; b <= max; b++)
{
b =n;
for(c = b + 1; c <= max; c++)
{
c = n;
if(Math.pow(a, 2)+ Math.pow(b, 2)== Math.pow(c, 2))
{
if((a%2==1 && b%2==0)|| (a%2==0 && b%2==1))
{
if(a%2<=1 && b%2<=1 && c%2<=1)
{
String last = a + "" + b + c;
}
}
}
}
}
}
}
return 1;
}
public String toString()
{
String output="";
output = output + this.greatestCommonFactor( ) + " \n";
return output;
}
}
and for cross-referencing my runner class:
import static java.lang.System.*;
import java.util.Scanner;
public class Lab11j
{
public static void main(String args[])
{
Scanner keyboard = new Scanner(System.in);
String choice="";
do{
out.print("Enter the max number to use : ");
int big = keyboard.nextInt();
//instantiate a TriangleThree object
Triples triple = new Triples(big);
//call the toString method to print the triangle
out.println( triple );
System.out.print("Do you want to enter more data? ");
choice=keyboard.next();
}while(choice.equals("Y")||choice.equals("y"));
}
}
if you find you need clarification of this lab, here's a Google docs of the labsheet: https://docs.google.com/open?id=0B_ifaCiEZgtcX08tbW1jNThZZmM
The variables a, b & c can be used as local variables here. This would allow you to remove them from the argument list of greatestCommonFactor:
private int greatestCommonFactor() {
int a = 0;
int b = 0;
int c = 0;
...
as they are only required within the scope of the method.
Well, yeah. You're not passing anything to greatestCommonFactor. I'm not sure what you expected to happen in your toString() method when you didn't pass enough arguments to a method.
you need to pass them like
output = output + this.greatestCommonFactor(1,2,3) + " \n";
the thing is, unless you are passing parameters to toString, without this, this code seems very limited. Alternatively you need to set some fields on the class with what will be passed into your function.

ADT LinkedList intersecting set error

I have a test code for an ADT of LinkedList, which implements interface NumList.java, and is implemented in a NumLinkedList.java, and am using it in a NumSet.java.
I am trying to make it so that my NumSet has methods where I can create a set from a double array input, and use intercept/union and print methods to use and print the data.
but my test code is showing that my test NumSet values are empty, namely testProof and testProof2.
So now my testProof is returning an empty variable, which means nothing is saving into it.
static public NumSet intersect(NumSet S1, NumSet S2) //check 2nd for and if//
{
NumSet intersectAnswer = new NumSet();
for (int i = 0; i < S1.set.size()-1; i++)
{
for(int j = 0; j < S2.set.size()-1; j++)
{
double FUZZ = 0.0001;
if (Math.abs(S1.set.lookup(i) - S2.set.lookup(j)) < FUZZ) // double values, this is more precise than ==.
{
intersectAnswer.set.insert(1, S1.set.lookup(i));
}
}
}
return intersectAnswer;
}
is the method for testProof, and the following is where testProof is defined.
public static void main(String[] args)
{
double[] a = {1.3,2,3,4,101.9};
double[] b = {3,7,13,901,-29.1,0.05};
NumArrayList test;
test = new NumArrayList();
test.printTest(); //runs test code in NumList
//ok below is running. what is wrong with intersect?
NumSet test2;
test2 = new NumSet(a);
NumSet test4;
test4 = new NumSet(b);
NumSet testProof;
NumSet testProof2;
test2.print(); //print out test 2
System.out.println();
test4.print();
System.out.println();
testProof = intersect(test2,test4);
I have initialized as
public class NumSet
{
private NumList set;
public NumSet(double[] sth)
{
//moves elements of sth into set.
set = new NumLinkedList();
for(int i = 0; i < sth.length; i++)
{
set.insert(0,sth[i]);
}
set.removeDuplicates();
}
public NumSet()
{
set = new NumLinkedList();
}
int numSet = 0;
and my intercept, union and print are below:
public NumSet intersect(NumSet S1, NumSet S2) //check 2nd for and if//
{
NumSet intersectAnswer = new NumSet();
for (int i = 0; i < S1.set.size()-1; i++)
{
for(int j = 0; j < S2.set.size()-1; j++)
{
if (S1.set.lookup(i) == S2.set.lookup(j))
{
intersectAnswer.set.insert(0, S1.set.lookup(i));
}
}
}
// intersectAnswer.set.removeDuplicates(); unnecessary, sets are already removed of duplicates
return intersectAnswer;
}
public NumSet union(NumSet S1, NumSet S2)
{ //check logic.
NumSet unionAnswer = new NumSet();
for (int i = 1; i < S1.set.size()+1; i++)
{
unionAnswer.set.insert(1, S1.set.lookup(i));
}
for (int i = 1; i < S2.set.size()+1; i++)
{
unionAnswer.set.insert(1, S2.set.lookup(i));
}
unionAnswer.set.removeDuplicates();
return unionAnswer;
}
public void print()
{
for (int i = 0; i < set.size()-1; i++)
{
System.out.print(set.lookup(i) + ",");
}
System.out.print(set.lookup(set.size()-1));
}
the lookup and size are referred to from my NumLinkedList.java and are as below
public int size() // measure size of list by counting counter++;
{
return nItem;
}
public double lookup(int i)
{
if( i <0 || i >= size()) //cannot lookup nonexistant object
{
System.out.println("out of bounds " + i + " < 0 or > " + size() );
//how do I break out of this loop?
System.out.println("just returning 0 for the sake of the program");
return 0;
}
if(i == 0)
{
return head.value;
}
double answer = 0;
Node currNode = head;
for(int j = 0; j < i+1; j++) //move to ith node and save value
{
answer = currNode.value;
currNode = currNode.next;
}
return answer;
}
and finally my test code is as below, where testProof and testProof2 are.
public static void main(String[] args)
{
double[] a = {1.3,2,3,4,101.9};
double[] b = {3,7,13,901,-29.1,0.05};
NumArrayList test;
test = new NumArrayList();
test.printTest(); //runs test code in NumList
//ok below is running. what is wrong with intersect?
NumSet test2;
test2 = new NumSet(a);
NumSet test4;
test4 = new NumSet(b);
NumSet testProof;
NumSet testProof2;
test2.print();
System.out.println();
testProof = test2.intersect(test2, test4);
System.out.println("tried intersect");
testProof.print();
System.out.println();
System.out.println("tried test.print()");
testProof2 = test2.union(test2,test4);
System.out.println("tried union");
testProof2.print();
System.out.println();
System.out.println("NumSet ran fully.");
I'd suggest you implement you NumSet Class with integer values rather than double values while you debug because comparing two double values tends to add some unneeded complexity to your code at this debug stage.
You might want to look at your removeDuplicates() method, I think that might hold the answer to your problem. Unfortunately I don't see it within the code you posted.
Actually, this part of code within the intersect() method is destined to fail from the start,
if (S1.set.lookup(i) == S2.set.lookup(j))
Because of your use of doubles, == is a very imprecise method of comparing two different values, a better way would be to allow for a certain amount of precision error, i.e.
double final FUZZ = 0.0001
if (Math.abs(S1.set.lookup(i) - S2.set.lookup(j)) < FUZZ )
//...

Method not working?

Updated code:
import java.util.*;
public class Main {
/**
* #param args
*/
static int[] C;
static int[] D;
static String P;
public static void main(String[] args) {
C = new int[10];
D = new int[10];
getNumber();
}
private static void getNumber() {
System.out
.println("Enter your first number with spaces in between digits.");
Scanner S = new Scanner(System.in);
String O = S.nextLine();
String[] A = new String[10];
A = O.split(" ");
for (int X = 0; A.length > X; X++) {
C[X] = toNumber(A[X]);
}
String P = S.nextLine();
String[] B = new String[10];
B = P.split(" ");
for (int Y = 0; B.length > Y; Y++) {
C[Y] = toNumber(A[Y]);
}
System.out.print(C[0]);
remainders();
}
private static void remainders() {
for (int A = 0; C.length > A; A++) {
if (D[1] * C[A] >= 10) {
Integer B = new Integer(D[1] * C[A]);
Character E = B.toString().charAt(0);
P.concat(E.toString());
}
}
for (int A = 0; C.length > A; A++) {
if (D[0] * C[A] >= 10) {
Integer B = new Integer(D[1] * C[A]);
Character E = B.toString().charAt(0);
P.concat(E.toString());
}
}
System.out.print(P);
}
private static int toNumber(String string) {
if (string.equals("0")) {
return 0;
} else if (string.equals("1")) {
return 1;
} else if (string.equals("2")) {
return 2;
} else if (string.equals("3")) {
return 3;
} else if (string.equals("4")) {
return 4;
} else if (string.equals("5")) {
return 5;
} else if (string.equals("6")) {
return 6;
} else if (string.equals("7")) {
return 7;
} else if (string.equals("8")) {
return 8;
} else if (string.equals("9")) {
return 9;
} else {
return 0;
}
}
}
For some reason, the last thing it prints is null. I am pretty sure the problem is the toNumber method, but I can't figure out what's wrong. If there are other problems with the code other than this, please let me know. Please help.
Edit: Problem seems to be with remainder method, please help
Use the string.equals(n) method to test if string is n
String constants are compared this way: "0".equals(string). String literals are actual String objects and You can call any String method on them. And you should prefer to call methods on constants, because it's guaranteed they exists, whereas variables can be null.
You don't need to reinvent the wheel. Java has rich SDK.
Simply use
int x = Integer.valueOf(a[X]);
If you want only numbers 0-9, then simply test
if (0 <= x && x <= 9) {
//valid continue
} else {
//invalid state handling
}

Categories