Java -- Associate data input with data output? - java

I am looking for advice on basic designs for a system with this functionality.
Let's say I have a data class like this:
Class nodeData
boolean aValue;
boolean bValue;
boolean cValue;
Using some set of business logic, I define mutually exclusive sets of titles to the node that this data represents.
For example, I define this title:
Singular.YES means Only one of aValue, bValue, cValue is true
Singular.NO means 0 or more than 1 of aValue, bValue, cValue is true
or this one:
aDefined.YES means aValue is true.
aDefined.NO means aValue is false.
or this one:
totalTrue:.0 means 0 of the values are true
totalTrue.1 means 1 of the values are true
etc.
In each of these cases, the titles are mutually exclusive among each other in that same set, and which title within a set applies to that data is based on some hard-coded business logic.
Then, each specific title is associated with some specific piece of functionality. For example, I might say that "If aDefined.YES, call methodX" or "If totalTrue.0, call methodX and then methodY".
If N is the number of title sets, then there are N! combinations of titles, and N! combinations of associated functionality. How do I accomplish: For each node data, find the set of titles associated with that data. Run the functionality associated with each of those titles.
EDIT: This isn't a boolean logic question, this is a design question. My point is that I want a robust method of associating data sets with some name or subclass given arbitrary business logic.

skipping the Value parts
I think this should help you but your question is a bit vague.
//checking if one of the 3 bools are true
if((a&&!b&&!c)||(!a&&b&&!c)||(!a&&!b&&c))
Singular = Singular.YES
else
Singular = Singular.NO
//checking if one bool is true
if(a)
aDefined = aDefined.YES
else
aDefined = aDefined.NO
//checking how many bools are true
int i = 0;
if(a)
i++;
if(b)
i++;
if(c)
i++;
TotalTrue = i;

Related

How to compare two datasets to check for missing rows which don't exist in the other dataset?

I have built a method which takes two datasets: dataset1 and retirementSimpleData.
It matches the two datasets based on a primary key/number, defined as cnum, in the code below.
I wanted to return the value of the difference between the getAssets value and the getSums value, and this is working, except for one little problem.
Some of the cnums that exist in dataset1 don't exist in retirementSimpleData. Similarly, some cnums which may exist in retirementSimpleData may not exist in
dataset1. This is resulting in no data being returned for that cnum.
I would like to implement two passes at the end which check in one direction to see if I missed anything. The second pass would check in the opposite direction.
However, not sure how I would go about implementing this.
public void getReportData(int index) {
String date1 = Util.dateTimeToShortString(reportDate);
String date2 = reportDao.getPreviousRetirementDate(date1);
List<SurveyCompareAssetsCheckData> dataset1 = reportDao.getSurveyCheckCompareAssetsData(date1);
List<RetSurveyAssets> retirementSimpleData = reportDao.findRetSurveyByDate(date1);
for (SurveyCompareAssetsCheckData surveyCompareAssetsCheckData : dataset1) {
for (RetSurveyAssets surveyCompareAssetsCheckData2 : retirementSimpleData) {
if (surveyCompareAssetsCheckData.getCnum() == surveyCompareAssetsCheckData2.getCnum()) {
surveyCompareAssetsCheckData.setRetirementsimple(surveyCompareAssetsCheckData2.getSums());
surveyCompareAssetsCheckData.setDifference(surveyCompareAssetsCheckData.getAssets() - surveyCompareAssetsCheckData2.getSums());
Caveat: dataset1 and retirementSimpledata both use existing SQL pulls which I am not allowed to touch, otherwise I would have simply defined new SQL for these methods in my "DAOImpl." Therefore, I have to work with the data I am getting, and programmatically check for this.
Below, is the report which is being generated with my code. As you can see, I am ending up with zeros, which is showing the difference (incorrectly) as zeros, because Cnum #45, in this example simply doesn't exist in the second dataset (retirementSimpleData)
What is the datatype of Cnum, if it is int then default value is Zero.
You have to add else-if condition to check for example:
else if (surveyCompareAssetsCheckData2.getCnum()== 0){
-------- logic here --------------------
}
else if (surveyCompareAssetsCheckData.getCnum() ==0){
----------logic here -----------
}

Mocking contains() with a String[][]

I have two SQL tables. After grabbing both tables in ResultSets, I've stored them in String[][]s, ordered by a common id column. These tables should contain the same data, however one may have duplicates of the same row from the other. In order to check if every String[] in table A is present at least once in table B, I need to construct a somewhat efficient contains()-esque method for String[].
This is what I have so far, but am stumped (also not sure if there's a much more efficient solution). Give it the source table and target table. It takes each String[] in the source table and (should) go through each String[] in the target table and find an instance of the source String[] somewhere in the target String[][] by checking if there's at least one String[] that matches the original String[], element by element. Can anyone point me in the right direction and/or fill in the blanks? This isn't homework or any assignment, I'm refactoring some code and am having a major brain fart. Thanks!
public boolean targetContainsSource(String[][] s, String[][] t) {
boolean result = true;
//For each String[] in String[][] s
for (int i = 0; i < s.length; i++) {
//For each String[] in String[][] t
for (int j = 0; j < t.length; j++) {
//For each String in t's String[]
for (int k = 0; k < t[0].length; k++) {
if (!s[i][k].equals(t[j][k])) {
}
}
}
}
return result;
}
Your innermost loop could be removed by using Arrays.equals().
For each element of the first array, you should define a found boolean variable, that would only be set to true once the element is found in the second array. Once the second loop is finished, if this variable is still false, you have found an element of the first array that is not in the second, and you can return immediately.
And of course, as soon as this variable is set to true, you can break out of the second loop.
Essentially, you generally need to do the following:
use a strong hash function to take a hash of each row: this gives you a single integer (probably a long to be strong enough) or single string/byte array representing the entire row
then proceed as though you were comparing two "lists" of rows. At least one of these "lists" should actually be stored in a HashSet/HashMap, whose contains() method is efficient.
For the hash function you could use MD5 (e.g. you can use this code, but use "MD5" instead of "SHA-1"). You can use MessageDigest.compare() to compare to byte arrays representing hash codes.
If you only have a small number (say, a few tens of thousands) of rows, then you could use a 64-bit hash code-- this just has the advantage that each hash is stored in a long so they're a bit easier to shufty about and compare. But 64-bit hash codes are only strong enough for guaranteeing uniqueness of hashes of tens to hundreds of thousands of objects (=different rows in your case).
P.S. If you're prepared to store all of the data in memory, then you could also just use as the "hash" of each row all of the columns concetenated together into a single string. The trick is to make the check efficient to have one of the tables' row representations stored in a HashSet/HashMap.

Using Boolean True/False with JOptionPane.YES_NO_OPTION

I have a series of four yes/no choices in four separate dialog boxes, the cumulative results of which will lead to one of twelve separate links (e.g., Yes/Yes/Yes/No -> link A, Yes/No/No/Yes -> link B, etc). The branching logic uses boolean values.
Here's what I have so far...just the first dialog box and printing the results for validation.
public class OutageGuideSelector{
public static void main(String[] args){
boolean contactServerUp;
boolean vistaUp;
boolean stormOutage;
boolean vistaCSUp;
//
int contactServerEntry = JOptionPane.showConfirmDialog(null,
"Is the contact server up", "Please select",
JOptionPane.YES_NO_OPTION);
System.out.println("result from entry " + contactServerEntry);
if(contactServerEntry==1)
contactServerUp = true;
else
if(contactServerEntry==0)
contactServerUp = false;
/* System.out.println(contactServerUp); */
}}
Right now, the results of clicking YES reults in a 0 being returned, NO results in a 1. Is this normal, seems counterintuitive, and there's nothing at docs.oracle.java that shows a clear example of the output values except this which seems to suggest that the public static final int YES_NO_OPTION default in 0.
Additionally, the line System.out.println(contactServerUp); comes back with an error that the field contactServerUp might not have been initialized when I un-comment it, so I can't see if my convert-int-to-boolean is working.
First: It appears that JOptionPane method does not include any boolean returns...except getWantsInput() which returns the value of the wantsInput property...so I assume I'm already being the most efficient I can with this. I'd like to know if there's an easier way.
Second, what am I missing that prevents my console output statement from recognizing the contactServerUp? Where's my misplaced semicolon?
According to the javadoc, when one of the showXxxDialog methods returns an integer, the possible values are:
YES_OPTION
NO_OPTION
CANCEL_OPTION
OK_OPTION
CLOSED_OPTION
You should test against those constants:
contactServerUp = (contactServerEntry == JOptionPane.YES_OPTION);
The value returned by the the JOptionPane dialogs are values defined as constant fields in the class.
Although, indeed, one could assume that 0 means false and 1 means true, the values are more ids for the different buttons a dialog can have.
To know if the user pressed yes or no, you can compare the return value to the constant fields described here. For example, in your case :
contactServerUp = (contactServerEntry == JOptionPane.YES_OPTION);
Since a dialog a JOptionPane can have more than two possible 'answers' a boolean would be a poor representation. You are forgetting about the YES, NO and CANCEL option, or what about just a OK answer.
If it would have been written today, I suspect a Enum would have been used instead of an int.
As for the second question, the compiler does not allow access to uninitialized variables.
When you do the following, there is a chance that the variable might not be initialized:
if(contactServerEntry==1)
contactServerUp = true;
else
if(contactServerEntry==0)
contactServerUp = false;
What if, for example, contactServerEntry == JOptionPane.CLOSED_OPTION? In that case, your boolean value is never initialized.
You need to add an else clause at the end of your if-else chain, or initialize contactServerUp value to a default value in the beginning.

Java searching an array for repeating pattern

I have a program that is searching a maze to find the best way out. As it searches it adds the next move to an array. My problem is that it keeps repeating the same three moves over and over. I need to find the best way to check that array of moves in order to force it to change move when a loop has been detected.
edit for clarity,
http://www.logicmazes.com/theseus.html maze three is the one I'm testing. what happens is that it gets stuck moving up and down in the column it starts in.
You could keep track of every cell your current path has already visited, and not go to those cells again (since that would create a loop).
As far as the data structure is concerned, I see two main possibilities:
keep an array -- or a set -- of coordinates that you've visited; or
have a boolean array of the same dimensions as the maze, setting the visited cells to true.
You would need to update the structure whenever you take a step, and whenever you backtrack.
It sounds like the problem is that your "state" doesn't actually contain enough state information. In every cycle, after Theseus has moved and the Minotaur has moved twice, the state consists of the following:
Theseus's x-coordinate.
Theseus's y-coordinate.
The Minotaur's x-coordinate.
The Minotaur's y-coordinate.
You can represent these as some sort of MazeState object whose equals and hashCode methods make it easy to see if two instances represent the same state.
Since the Minotaur's motion follows a very rigid program, every move that Theseus makes (left/right/up/down/delay) will move from one well-defined state to another. You then need to forbid Theseus from making any moves that:
Would cause the Minotaur's x- and y-coordinates to equal those of Theseus (since this means Theseus is dead).
Would cause the new state to be equal to a state that you've previously been in (since this means that no progress has been made).
To do this, you can store the previous states in a HashSet<MazeState>.
If you are using an Array then you should be able to use "contains" method to check if the move is already in the array.
In order to do that you may have to modify your equals method to compare two different moves to check if they are the same.
In that case, when you identify the same move, you can ignore that and look for other moves. An example pseudo code
public class Move {
int x;
int y;
public boolean equals(Object o){
if(o == null) return false;
if(!(o instanceof) Move) return false;
Move other = (Move) o;
if(this.x != other.x) return false;
if(this.y != other.y) return false;
return true;
}
}
public class SolveMaze {
List<Move> moves;
...
public boolean isValidMove(Move move) {
if (moves.contains(move)) return false;
else {
...
moves.add(move);
}
}
}

How should I find repeated word sequences

I need to detect the presence of multiple blocks of columnar data given only their headings. Nothing else is known about the data except the heading words, which are different for every set of data.
Importantly, it is not known before hand how many words are in each block nor, therefore, how many blocks there are.
Equally important, the word list is always relatively short - less than 20.
So, given a list or array of heading words such as:
Opt
Object
Type
Opt
Object
Type
Opt
Object
Type
what's the most processing-efficient way to determine that it consists entirely of the repeating sequence:
Opt
Object
Type
It must be an exact match, so my first thought is to search [1+] looking for matches to [0], calling them index n,m,... Then if they are equidistant check [1] == [n+1] == [m+1], and [2] == [n+2] == [m+2] etc.
EDIT: It must work for word sets where some of the words are themselves repeated within a block, so
Opt
Opt
Object
Opt
Opt
Object
is a set of 2
Opt
Opt
Object
If the list is made of x repeating groups such that each group contains n elements...
We know there is at least 1 group so we will see if there 2 repeating groups, test by comparing the first half of the list and the second half.
1) If the above is true we know that that the solution is a factor of 2
2) If the above is false we move to the next largest prime number which is divisible by the total number of words...
At each step we check for equality among the lists, if we find it then know we have a solution with that factor in it.
We want to return a list of words for which we have the greatest factor of the first prime number for which we find equality among sub lists.
So we apply the above formula on the sub list knowing all sub lists are equal... therefore the solution is best solved recursively. That is we only need to consider the current sub list in isolation.
The solution will be extremely efficient if loaded with a short table of primes... after this it will be necessary to compute them but the list would have to be non trivial if even a list of only a few dozen primes are taken into account.
Can the unit sequence contain repetitions of its own? Do you know the length of the unit sequence?
e.g.
ABCABCABCDEFABCABCABCDEFABCABCABCDEF
where the unit sequence is ABCABCABCDEF
If the answer is yes, you've got a difficult problem, I think, unless you know the length of the unit sequence (in which case the solution is trivial, you just make a state machine that first stores the unit sequence, then verifies that the each element rest of the sequence corresponds to each element of the unit sequence).
If the answer is no, use this variant Floyd's cycle-finding algorithm to identify the unit sequence:
Initialize pointers P1 and P2 to the beginning of the sequence.
For each new element, increment pointer P1 every time, and increment pointer P2 every other time (keep a counter around to do this).
If P1 points to an identical elements of P2, you've found a unit sequence.
Now repeat through the rest of the sequence to verify that it consists of duplicates.
UPDATE: you've clarified your problem to state that the unit sequence may contain repetitions of its own. In this case, use the cycle-finding algorithm, but it's only guaranteed to find potential cycles. Keep it running throughout the length of the sequence, and use the following state machine, starting in state 1:
State 1: no cycle found that works; keep looking. When the cycle-finding algorithm finds a potential cycle, verify that you've gotten 2 copies of a preliminary unit sequence from P, and go to state 2. If you reach the end of the input, go to state 4.
State 2: preliminary unit sequence found. Run through the input as long as the cycle repeats identically. If you reach the end of the input, go to state 3. If you find an input element that is different from the corresponding element of the unit sequence, go back to state 1.
State 3: The input is a repetition of a unit sequence if the end of the input consists of complete repetitions of the unit sequence. (If it's midway through a unit sequence, e.g. ABCABCABCABCAB then a unit sequence found, but it does not consist of complete repetitions.)
State 4: No unit sequence found.
In my example (repeating ABCABCABCDEF) the algorithm starts by finding ABCABC, which would put it in state 2, and it would stay there until it hit the first DEF, which would put it back in state 1, then probably jump back and forth between states 1 and 2, until it reached the 2nd ABCABCABCDEF, at which point it would re-enter state 2, and at the end of the input it would be in state 3.
A better answer than my other one: a Java implementation which works, should be straightforward to understand, and is generic:
package com.example.algorithms;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
interface Processor<T> {
public void process(T element);
}
public class RepeatingListFinder<T> implements Processor<T> {
private List<T> unit_sequence = new ArrayList<T>();
private int repeat_count = 0;
private int partial_matches = 0;
private Iterator<T> iterator = null;
/* Class invariant:
*
* The sequence of elements passed through process()
* can be expressed as the concatenation of
* the unit_sequence repeated "repeat_count" times,
* plus the first "element_matches" of the unit_sequence.
*
* The iterator points to the remaining elements of the unit_sequence,
* or null if there have not been any elements processed yet.
*/
public void process(T element) {
if (unit_sequence.isEmpty() || !iterator.next().equals(element))
{
revise_unit_sequence(element);
iterator = unit_sequence.iterator();
repeat_count = 1;
partial_matches = 0;
}
else if (!iterator.hasNext())
{
iterator = unit_sequence.iterator();
++repeat_count;
partial_matches = 0;
}
else
{
++partial_matches;
}
}
/* Unit sequence has changed.
* Restructure and add the new non-matching element.
*/
private void revise_unit_sequence(T element) {
if (repeat_count > 1 || partial_matches > 0)
{
List<T> new_sequence = new ArrayList<T>();
for (int i = 0; i < repeat_count; ++i)
new_sequence.addAll(unit_sequence);
new_sequence.addAll(
unit_sequence.subList(0, partial_matches));
unit_sequence = new_sequence;
}
unit_sequence.add(element);
}
public List<T> getUnitSequence() {
return Collections.unmodifiableList(unit_sequence);
}
public int getRepeatCount() { return repeat_count; }
public int getPartialMatchCount() { return partial_matches; }
public String toString()
{
return "("+getRepeatCount()
+(getPartialMatchCount() > 0
? (" "+getPartialMatchCount()
+"/"+unit_sequence.size())
: "")
+") x "+unit_sequence;
}
/********** static methods below for testing **********/
static public List<Character> stringToCharList(String s)
{
List<Character> result = new ArrayList<Character>();
for (char c : s.toCharArray())
result.add(c);
return result;
}
static public <T> void test(List<T> list)
{
RepeatingListFinder<T> listFinder
= new RepeatingListFinder<T>();
for (T element : list)
listFinder.process(element);
System.out.println(listFinder);
}
static public void test(String testCase)
{
test(stringToCharList(testCase));
}
static public void main(String[] args)
{
test("ABCABCABCABC");
test("ABCDFTBAT");
test("ABABA");
test("ABACABADABACABAEABACABADABACABAEABACABADABAC");
test("ABCABCABCDEFABCABCABCDEFABCABCABCDEF");
test("ABABCABABCABABDABABDABABC");
}
}
This is a stream-oriented approach (with O(N) execution time and O(N) worst-case space requirements); if the List<T> to be processed already exists in memory, it should be possible to rewrite this class to process the List<T> without any additional space requirements, just keeping track of the repeat count and partial match count, using List.subList() to create a unit sequence that is a view of the first K elements of the input list.
My solution, which works as desired, is perhaps naive. It does have the advantage of being simple.
String[] wta; // word text array
...
INTERVAL:
for(int xa=1,max=(wta.length/2); xa<=max; xa++) {
if((wta.length%xa)!=0) { continue; } // ignore intervals which don't divide evenly into the words
for(int xb=0; xb<xa; xb++) { // iterate the words within the current interval
for(int xc=xb+xa; xc<wta.length; xc+=xa) { // iterate the corresponding words in each section
if(!wta[xb].equalsIgnoreCase(wta[xc])) { continue INTERVAL; } // not a cycle
}
}
ivl=xa;
break;
}

Categories