Dynamic List of lists in Java [closed] - java

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I want to read a file which has the following information:
4 //no. of machines
1,3,6,1 //timings for machine 1
1,3,6,1 //timings for machine 2
1,3,6,1 //timings for machine 3
1,3,6,1 //timings for machine 4
2,4,8,10 //cost for machine 1
2,4,8,10 //cost for machine 2
2,4,8,10 //cost for machine 3
2,4,8,10 //cost for machine 4
The no. of timing arrays and cost arrays depends on the no. of machines. An element in index 'i' of timing array is associated with the same index in cost array. For example, timing 1 for machine 1 incurs cost of 2, and timing 3 costs 4. Can anyone please suggest what data structure would be perfect for this scenario and how should I proceed with it?
Thanks in advance.

You can use a Map to define the relationship between timing and cost. Alternatively you can have a class TimeCost for time cost relationship.
public class TimeCost{
private Integer time;
private Integer cost;
}
public class Machine{
// private Map<Integer,Integer> timeCost; //possible alternative
private List<TimeCost> timeCost;
}

First, you should probably use a Pair to conserve the relationship between a timing and a cost:
class Pair {
int timing;
int cost;
}
Then, I'm assuming you don't receive information about how many pieces of timing/cost you get, so you'll have to use an ArrayList to represent a machine's information:
class Machine {
ArrayList<Pair> timingAndCost;
}
Then, since the number of machines is specified for you, use a fixed-size array to store the machines:
Machine[] machines = new Machine[numberOfMachines];
If you're considering just storing the ArrayLists in an array, like this:
ArrayList<Pair>[] machines = new ArrayList<Pair>[numberOfMachines];
It doesn't work, because Java doesn't allow you to declare a generic array. But if you really don't like to have the Machine class, then you can just use an ArrayList to store the ArrayList<Pair>:
ArrayList<ArrayList<Pair>> machines = new ArrayList<>(numberOfMachines);

import java.util.ArrayList;
class DaMachine {
private final int mMachineIndex;
private final int[] mTimings;
private final int[] mCosts;
public DaMachine(final int pMachineIndex, final int[] pTimings, final int[] pCosts) {
mMachineIndex = pMachineIndex;
mTimings = pTimings;
mCosts = pCosts;
}
#Override public String toString() {
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < mTimings.length; i++) {
sb.append(mTimings[i] + ":" + mCosts[i] + " ");
}
return "Machine [#" + mMachineIndex + ": " + sb + "]";
}
}
class CrazyFile {
static public String CRAZY = "4 //no. of machines \r\n" + //
"1,3,6,1 //timings for machine 1\r\n" + //
"1,3,6,1 //timings for machine 2\r\n" + //
"1,3,6,1 //timings for machine 3\r\n" + //
"1,3,6,11 //timings for machine 4\r\n" + //
"2,4,8,10 //cost for machine 1\r\n" + //
"2,4,8,10 //cost for machine 2\r\n" + //
"2,4,8,10 //cost for machine 3\r\n" + //
"2,4,8,111 //cost for machine 4";
}
public class ReadCrazyFile {
public static void main(final String[] args) {
final String[] lines = CrazyFile.CRAZY.replace("\r\n", "\n").replace("\r", "\n").split("\n");
final int numberOfMachines = Integer.parseInt(cleanString(lines[0]));
final ArrayList<String> timingStrings = new ArrayList<>(numberOfMachines);
final ArrayList<String> costStrings = new ArrayList<>(numberOfMachines);
int offset = 1;
// add timings
for (int relIndex = 0; relIndex < numberOfMachines; relIndex++) {
timingStrings.add(cleanString(lines[offset + relIndex]));
}
offset += numberOfMachines;
// add costs
for (int relIndex = 0; relIndex < numberOfMachines; relIndex++) {
costStrings.add(cleanString(lines[offset + relIndex]));
}
offset += numberOfMachines; // not necessary unless used later
// convert into objects
final ArrayList<DaMachine> machines = new ArrayList<>(numberOfMachines);
for (int machineIndex = 0; machineIndex < timingStrings.size(); machineIndex++) {
final String timingString = timingStrings.get(machineIndex);
final String costsString = costStrings.get(machineIndex);
final int[] timings = convertToIntArr(timingString);
final int[] costs = convertToIntArr(costsString);
final DaMachine terminator = new DaMachine(machineIndex, timings, costs);
machines.add(terminator);
}
for (final DaMachine m : machines) {
System.out.println("" + m);
}
}
static private String cleanString(final String pString) {
return pString.split("//")[0].trim();
}
static private int[] convertToIntArr(final String pTimingString) {
final String[] words = pTimingString.split(",");
final int[] ret = new int[words.length];
for (int i = 0; i < words.length; i++) {
ret[i] = Integer.parseInt(words[i].trim());
}
return ret;
}
}

This is the structure that you need to resolve the issue.
ArrayList<ArrayList<Integer>> listOLists = new ArrayList<ArrayList<Integer>>();
ArrayList<Integer> list1= new ArrayList<Integer>();
list1.add(4);
listOLists.add(list1)
ArrayList<Integer> list2= new ArrayList<Integer>();
list2.add(1);
list2.add(3);
list2.add(6);
list2.add(1);
listOLists.add(list2);
ArrayList<Integer> list3= new ArrayList<Integer>();
list3.add(1);
list3.add(3);
list3.add(6);
list3.add(1);
listOLists.add(list3);
Like this wise you can proceed. Its just a rough idea please optimize this code according to your need.

Related

Copy Three Dimensional ArrayList as Pass-By-Value

Java Version 8
IntelliJ IDEA 2016.1.4
Build #IC-145.2070, built on August 2, 2016
JRE: 1.8.0_77-b03 x86
JVM: Java HotSpot(TM) Server VM by Oracle Corporation
I need to be able to copy this ArrayList for when changes are made to values in the ArrayList (added, removed, edited)... And these changes made, must only be made in the copied ArrayList without Affecting the original ArrayList.
Example Code Provided Below:
Line 61: is where the copy of pass-by-value should happen.
Lines 19-23: is where I was thinking of creating the copy pass-by-value method, and then just using the method call on line#61.
package Main;
import java.util.ArrayList;
public class QuickTest {
private static void printHpMpLvlsValues(ArrayList<ArrayList<ArrayList<Integer>>> hpMpLvlsValues, int hpValuesIndex, int mpValuesIndex){
int currentLvl = 1;
for (int lvlIndex = 0; lvlIndex < hpMpLvlsValues.get(hpValuesIndex).size(); lvlIndex++, currentLvl++){
System.out.println("****************** LVL(" + currentLvl + ") Possible Values ******************");
System.out.println("HP Values = " + hpMpLvlsValues.get(hpValuesIndex).get(lvlIndex));
System.out.println("MP Values = " + hpMpLvlsValues.get(mpValuesIndex).get(lvlIndex));
System.out.println();
}
System.out.println("*************************************************************");
System.out.println("*************************************************************");
System.out.println("*************************************************************");
System.out.println();
}
private static ArrayList<ArrayList<ArrayList<Integer>>> getCopyThreeDimArrListPassByValue(ArrayList<ArrayList<ArrayList<Integer>>> origThreeDimArrList){
ArrayList<ArrayList<ArrayList<Integer>>> copiedThreeDimArrList = new ArrayList<>();
//ToDo: fill in code to copy the Three Dimensional ArrayList as pass-by-value.
return copiedThreeDimArrList;
}
public static void main(String[] args) {
int hpValuesIndex = 0;
int mpValuesIndex = 1;
// Setup originalHpMpLvlsValues ArrayList...
ArrayList<ArrayList<ArrayList<Integer>>> originalHpMpLvlsValues = new ArrayList<>();
ArrayList<ArrayList<ArrayList<Integer>>> copiedHpMpLvlsValues = new ArrayList<>();
ArrayList<ArrayList<Integer>> hpLvlsValues = new ArrayList<>();
ArrayList<ArrayList<Integer>> mpLvlsValues = new ArrayList<>();
int maxLvl = 10;
int lvlTotalNumOfValuesPerLvl = 5;
int currentHpValue = 50;
int IncreaseHpValue = 50;
int currentMpValue = 10;
int IncreaseMpValue = 10;
for (int lvlIndex = 0; lvlIndex < maxLvl; lvlIndex++){
hpLvlsValues.add(new ArrayList<>());
mpLvlsValues.add(new ArrayList<>());
for (int valueNum = 1; valueNum <= lvlTotalNumOfValuesPerLvl; valueNum++){
hpLvlsValues.get(lvlIndex).add(currentHpValue);
mpLvlsValues.get(lvlIndex).add(currentMpValue);
currentHpValue += IncreaseHpValue;
currentMpValue += IncreaseMpValue;
}
}
originalHpMpLvlsValues.add(hpLvlsValues);
originalHpMpLvlsValues.add(mpLvlsValues);
// End Setup originalHpMpLvlsValues ArrayList...
// Print multiple hp/mp possible level results to system output
System.out.println("************************************************************");
System.out.println("Original HP/MP Levels Results:");
printHpMpLvlsValues(originalHpMpLvlsValues, hpValuesIndex, mpValuesIndex);
// Attempt to copy originalHpMpLvlsValues ArrayList as pass-by-value
copiedHpMpLvlsValues = originalHpMpLvlsValues; // <--------- Insert how to copy pass-by-value here
// Change hpValue for 5th level from 1150 to 1175
// ... this change should only affect "copiedHpMpLvlsValues" ArrayList and NOT the "originalHpMpLvlsValues" ArrayList
int lvlFiveIndex = 4;
copiedHpMpLvlsValues.get(hpValuesIndex).get(lvlFiveIndex).set(2, 1175);
// Print change made to copiedHpMpLvlsValues ArrayList
System.out.println("************************************************************");
System.out.println("Copied HP/MP Levels Results with change(s):");
printHpMpLvlsValues(copiedHpMpLvlsValues, hpValuesIndex, mpValuesIndex);
// Print originalHpMpLvlsValues ArrayList to ensure NO changes were made to this ArrayList
System.out.println("************************************************************");
System.out.println("Original HP/MP Levels Results without change(s):");
printHpMpLvlsValues(originalHpMpLvlsValues, hpValuesIndex, mpValuesIndex);
}
}
As a side-note, I got help with how to copy two dimensional ArrayLists as pass-by-value here -> Copy Two Dimensional ArrayList as new (read sweepers answer at the bottom done with 1 line of code)
Filled in the copy method on lines 19-23 in original post...
private static ArrayList<ArrayList<ArrayList<Integer>>> getCopyThreeDimArrListPassByValue(ArrayList<ArrayList<ArrayList<Integer>>> origThreeDimArrList){
ArrayList<ArrayList<ArrayList<Integer>>> copiedThreeDimArrList = new ArrayList<>();
ArrayList<ArrayList<Integer>> copiedArr;
for (ArrayList<ArrayList<Integer>> origArr: origThreeDimArrList){
copiedArr = new ArrayList<>(origArr.stream().map(x -> new ArrayList<>(x)).collect(Collectors.toList()));
copiedThreeDimArrList.add(copiedArr);
}
return copiedThreeDimArrList;
}
Then I just use this method call on line#61(now 67)...
copiedHpMpLvlsValues = getCopyThreeDimArrListPassByValue(originalHpMpLvlsValues);
However... I was wondering if there was a better way to do this or a built-in library I could use for this??

Generate list of names or words and output them in groups [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I am looking to take a list of words or names and output them into groups in a specific order via php or Java but have no idea how to do so. I will give an example with the order: (To clarify, this isn't homework. I am doing this for a tournament that I am hosting, and it would make it easy to generate seeds during the event)
Amount of names: 12
Size of Groups: 3
Hilde Frankum
Earlie Uphoff
Rich Laclair
Vicenta Baskin
Herminia Lakin
Hermelinda Hostetter
Bernice Sylva
Blossom Nesby
Lashon Kwan
Esther Farraj
Tana Olguin
Pamula Davin
Output:
Group 1:
Hilde Frankum
Herminia Lakin
Lashon Kwan
Group 2:
Earlie Uphoff
Hermelinda Hostetter
Esther Farraj
Group 3:
Rich Laclair
Bernice Sylva
Tana Olguin
Group 4:
Vicenta Baskin
Blossom Nesby
Pamula Davin
The list takes the name next in line and inserts it into a new group in the order that it is listed in until there are no more groups left and then restarts until there isn't any names left.
PFB sample code. I have created a Group class which holds an group(array of String objects). An ArrayList which holds random number of Group objects.
Program is dynamic based on input names and Size of Groups:
import java.util.ArrayList;
import java.util.List;
public class Group {
String group[];
public Group(int groupSize) {
this.group = new String[groupSize];
}
#Override
public String toString() {
StringBuilder strBuilder = new StringBuilder();
for (int i = 0; i < group.length; i++) {
if (i != 0)
strBuilder.append(", ");
strBuilder.append(group[i]);
}
return strBuilder.toString();
}
public static void main(String[] args) {
String[] inputArray = { "Hilde Frankum", "Earlie Uphoff",
"Rich Laclair", "Vicenta Baskin", "Herminia Lakin",
"Hermelinda Hostetter", "Bernice Sylva", "Blossom Nesby",
"Lashon Kwan", "Esther Farraj", "Tana Olguin", "Pamula Davin" };
int numGroups = 4;
createGroup(inputArray, numGroups);
}
public static void createGroup(String inputArray[], int numGroups) {
int groupSize = inputArray.length / numGroups;
List<Group> lists = new ArrayList<Group>();
for (int i = 0; i < numGroups; i++)
lists.add(new Group(groupSize));
for (int i = 0, x = 0; i < groupSize; i++)
for (int j = 0; j < numGroups; j++)
lists.get(j).group[i] = inputArray[x++];
for (Group groups : lists)
System.out.println(groups.toString());
}
}
Here's a Java method that should do it.
String[][] groupThem(ArrayList<String> /*could be an array without many changes*/ things, int sizeOfGroups){
int qtyOfThings = things.size();
int qtyOfGroups = qtyOfThings / sizeOfGroups;
String[][] groups = new String[qtyOfGroups][sizeOfGroups];
int counter = 0;
while(counter < qtyOfThings){
groups[counter%qtyOfGroups][counter%sizeOfGroups] = things.get(counter);
counter++;
}
return groups;
}
$arrayOfNames = array(
'Hilde Frankum',
'Earlie Uphoff',
'Rich Laclair',
'Vicenta Baskin',
'Herminia Lakin',
'Hermelinda Hostetter',
'Bernice Sylva',
'Blossom Nesby',
'Lashon Kwan',
'Esther Farraj',
'Tana Olguin',
'Pamula Davin'
);
sort($arrayOfNames);
$ar = array_chunk($arrayOfNames, 3);
foreach($ar as $key => $groups){
echo "Group #" . ($key + 1) .' '. implode(' ',$groups) . "\n";
}

Issue with NullPointerException

I am continuing to get this error. Now I have gotten it for my SortSearchUtil. I've tried to do some debugging but can fix the issue. The error reads:
----jGRASP exec: java PostOffice
Exception in thread "main" java.lang.NullPointerException
at SortSearchUtil.selectionSort(SortSearchUtil.java:106)
at PostOffice.sortLetters(PostOffice.java:73)
at PostOffice.main(PostOffice.java:15)
----jGRASP wedge: exit code for process is 1.
----jGRASP: operation complete.
line 106 of selection Sort is:
if (array[indexSmallest].compareTo(array[curPos]) > 0)
I don't know what could be wrong with my method. It's a standard method that was given to me by my instructor. I've tried to debug my program but I'm pretty stuck. Here is the method that the error is originating from, selectionSort:
public static void selectionSort(Comparable[] array)
{
int curPos, indexSmallest, start;
Comparable temp;
for (start = 0; start < array.length - 1; start++)
{
indexSmallest = start;
for (curPos = start + 1; curPos < array.length; curPos++)
if (array[indexSmallest].compareTo(array[curPos]) > 0)
{
indexSmallest = curPos;
}
// end for
temp = array[start];
array[start] = array[indexSmallest];
array[indexSmallest] = temp;
} // end for
}
The sort method is at the bottom which calls SortSearchUtil.selectionSort of this Post Office Method:
import java.util.*;
import java.io.*;
public class PostOffice
{
private final int max = 1000;
private Letter [] ltrAra = new Letter[max];
private int count;
public static void main(String [] args)
{
PostOffice postOffice = new PostOffice();
postOffice.readLetters("letters.in");
postOffice.sortLetters();
postOffice.printLetters();
}
public PostOffice()
{
Letter [] Letters = ltrAra;
this.count = 0;
}
public void readLetters(String filename)
{
int count = 0;
int iWork = 0;
Scanner fin = new Scanner(filename);
String toName, toStreet, toCity, toState, toZip;
String fromName, fromStreet, fromCity, fromState, fromZip, temp;
double weight;
String sWork;
fin = FileUtil.openInputFile(filename);
if (fin != null)
{
while (fin.hasNext())
{
toName = fin.nextLine();
toStreet = fin.nextLine();
sWork = fin.nextLine();
iWork = sWork.indexOf(",");
toCity = sWork.substring(0, iWork);
iWork = iWork + 2;
toState = sWork.substring(iWork, iWork + 2);
iWork = iWork + 3;
toZip = sWork.substring(iWork);
fromName = fin.nextLine();
fromStreet = fin.nextLine();
sWork = fin.nextLine();
iWork = sWork.indexOf(",");
fromCity = sWork.substring(0, iWork);
iWork = iWork + 2;
fromState = sWork.substring(iWork, iWork + 2);
iWork = iWork + 3;
fromZip = sWork.substring(iWork);
sWork = fin.nextLine();
weight = Double.parseDouble(sWork);
ltrAra[count] = new Letter(toName, toStreet, toCity, toState, toZip, fromName, fromStreet, fromCity, fromState, fromZip, weight);
count++;
}
fin.close();
}
}
public void sortLetters()
{
SortSearchUtil.selectionSort(ltrAra);
}
public void printLetters()
{
for (Letter ltr : ltrAra)
{
System.out.println(ltr);
System.out.println();
}
}
}
My file looks like this "letters.in":
Stu Steiner
123 Slacker Lane
Slackerville, IL 09035
Tom Capaul
999 Computer Nerd Court
Dweebsville, NC 28804-1359
0.50
Tom Capaul
999 Computer Nerd Court
Dweebsville, NC 28804-1359
Chris Peters
123 Some St.
Anytown, CA 92111-0389
1.55
Obviously you get a NPE because:
You initialize ltrAra as array of 1000 items, but you read in less than 1000 items within method readLetters(). So at the end of this array some null references remain un-initialized (remember array-creation does itself not set the single items to any objects). Therefore following sorting-method gets some null-references => NPE.
Suggested solution:
You should use an ArrayList instead of an array because that will automatically prevent you from accessing too much items due to internal range check.
In addition to the above answer that Meno has well stated, you need to understand when you get a Null pointer Exception.
your error-line : if (array[indexSmallest].compareTo(array[curPos]) > 0)
If we get NPE in this line, it is obvious that array[indexSmallest] is null
And when you invoke an action on null, you get NPE. Hope this helps you to debug, down the line.
Also, One of the main reasons when we choose ArrayList over Arrays is when we do not know the length of the array.
One more suggestion, you can create an ArrayList and then convert to Arrays if you want to stick with Arrays
To convert ArrayList of any class into array, Convert T to the respective class. For eg: if you want String array, convert T to 'String'
List<T> list = new ArrayList<T>();
T [] students = list.toArray(new T[list.size()]);

Java "2D-array" issues

I have a table on a mySQL server that has data stored like this
Name Goal New Used Total Pace
Jill 5 6 1 7 0
Bob 5 2 3 5 0
Ann 5 1 2 3 0
It can have many more than that in it. What I need to do is read in the data from the mySQL server and load it into a 2D String array. I already know how to load sql data...the issue is I can not, for the life of me, figure out how to load it into the array.
After the data is loaded into the array, it will be sent off to a table to be loaded for viewing.
So basically the output of the array would need to be:
Jill 5 6 1 7 0
Bob 5 2 3 5 0
Ann 5 1 2 3 0
here is the code I have:
public String[][] fillInTableForStoreFromArchive(String Person, String DateTable) throws SQLException{
stmt = con.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
rs = stmt.executeQuery("SELECT * FROM `" +DateTable+ "` WHERE name = '" +Person+"'");
int rows = 0; //column number
int columns = 6; //row number
rows = getAmountOfSalesPeople(DateTable).length;
String[][] data = new String[rows][columns];
String name = null;
int goal = 0, New = 0, used = 0,total = 0,pace = 0;
while(rs.next()){
name = rs.getString("Name");
goal = rs.getInt("Goal");
New = rs.getInt("New");
used = rs.getInt("Used");
// total = rs.getInt("total");
// pace = rs.getInt("pace");
String[] mData = { name, new Integer(goal).toString(),
new Integer(New).toString(), new Integer(used).toString(),
new Integer(New + used).toString(),new Integer(pace).toString() };
for(int row = 0; row >data.length; row ++){
data[row] = mData;
}
}
for(int row = 0; row < data.length; row++){
for(int col = 0; col <data[row].length; col++){
System.out.print(data[row][col] + " ");
}
System.out.println();
}
return data;
}
Looking at your example I'll make the assumption that name is unique. Since you've got mixed types, Strings and ints, you can't put them all into one array unless you store the ints as Strings. One solution would be to make an Object that holds a name and its associated data...that is, after all, something one does in object oriented programming.
Barring that I would store the data in a Map, where name is the key and an int array is the value:
HashMap<String, int[]> myMap = new HashMap<String, int[]>();
String name;
int[] myData;
while(rs.next())
{
myData = new int[5];
name = rs.getString("Name");
myData[0] = rs.getInt("Goal");
myData[1] = rs.getInt("New");
myData[2] = rs.getInt("Used");
myData[3] = rs.getInt("total");
myData[4] = rs.getInt("pace");
myMap.put(name, myData);
}
It is then trivial to iterate over the map when needed (hint: use a Map.Entry<String, int[]>), such as in toString(). Arrays don't have "output" so you'll either need to use an object or a separate method to get the data formatted as needed.
Also, avoid variable names like New...no good can come of names that are the same as keywords yet capitalized differently.
Your problem is that youre trying to deal with array rows as independent entities, by setting a row ton other array...
... 2D arrays cannot be set at the "row" level - because they are not managed using row level pointers --- in order to set an 2D array row, you have to explicitly set and define the row and column 'for' each column in the row, in a proper "for" loop.
Once you have the mdata array you want to use it as one of the rows in data. Instead you are using a cycle and assigning to several positions.
You should use a counter to keep track of how many rows have you added and then use that counter to put mdata in the right position.
As a corolary to #Paul's solution you can describe your table in a class and access it through normal OO principle. That would completely eliminate the need for arrays.
Say for example :
public class Player {
private String name;
private int goal;
private int _new; //As #Paul pointed out you should not use reserved keywords
private int used;
private int total;
private int pace;
public Player(String name, int goal, int _new, int used, int total, int pace) {
this.name = name;
this.goal = goal;
this._new = _new;
this.used = used;
this.total = total;
this.pace = pace;
}
public String getName() {
return name;
}
public int getGoal() {
return goal;
}
public int get_new() {
return _new;
}
public int getUsed() {
return used;
}
public int getTotal() {
return total;
}
public int getPace() {
return pace;
}
}
your initialization loop then becomes a much more readable :
List<Player> players = new ArrayList<Player>();
while (rs.next()) {
players.add(new Player(rs.getString("Name"),
rs.getInt("Goal"),
rs.getInt("New"),
rs.getInt("Used"),
rs.getInt("total"),
rs.getInt("pace")));
}
If you want to print information from your data good approach here would be to overload the toString of Player or to add a new method, say dumpToString().
public String dumpTostring() {
StringBuilder sb = new StringBuilder();
sb.append("Player ");
sb.append(name);
sb.append(" Goal=");
sb.append(goal);
sb.append(" New=");
sb.append(_new);
sb.append(" Used=");
sb.append(used);
sb.append(" Total=");
sb.append(total);
sb.append(" Pace=");
sb.append(pace);
return sb.toString();
}
and then just call in as part of a for each loop iterating through the list.

Encoding codes in Java

Over the past couple of weeks I've read through the book Error Control Coding: Fundamentals and Applications in order to learn about BCH (Bose, Chaudhuri, Hocquenghem) Codes for an junior programming role at a telecoms company.
This book mostly covers the mathematics and theory behind the subject, but I'm struggling to implement some of the concepts; primarily getting the next n codewords.I have a GUI (implemented through NetBeans, so I won't post the code as the file is huge) that passes a code in order to get the next n numbers:
Generating these numbers is where I am having problems. If I could go through all of these within just the encoding method instead of looping through using the GUI my life would be ten times easier.
This has been driving me crazy for days now as it is easy enough to generate 0000000000 from the input, but I am lost as to where to go from there with my code. What do I then do to generate the next working number?
Any help with generating the above code would be appreciated.
(big edit...) Playing with the code a bit more this seems to work:
import java.util.ArrayList;
import java.util.List;
public class Main
{
public static void main(final String[] argv)
{
final int startValue;
final int iterations;
final List<String> list;
startValue = Integer.parseInt(argv[0]);
iterations = Integer.parseInt(argv[1]);
list = encodeAll(startValue, iterations);
System.out.println(list);
}
private static List<String> encodeAll(final int startValue, final int iterations)
{
final List<String> allEncodings;
allEncodings = new ArrayList<String>();
for(int i = 0; i < iterations; i++)
{
try
{
final int value;
final String str;
final String encoding;
value = i + startValue;
str = String.format("%06d", value);
encoding = encoding(str);
allEncodings.add(encoding);
}
catch(final BadNumberException ex)
{
// do nothing
}
}
return allEncodings;
}
public static String encoding(String str)
throws BadNumberException
{
final int[] digit;
final StringBuilder s;
digit = new int[10];
for(int i = 0; i < 6; i++)
{
digit[i] = Integer.parseInt(String.valueOf(str.charAt(i)));
}
digit[6] = ((4*digit[0])+(10*digit[1])+(9*digit[2])+(2*digit[3])+(digit[4])+(7*digit[5])) % 11;
digit[7] = ((7*digit[0])+(8*digit[1])+(7*digit[2])+(digit[3])+(9*digit[4])+(6*digit[5])) % 11;
digit[8] = ((9*digit[0])+(digit[1])+(7*digit[2])+(8*digit[3])+(7*digit[4])+(7*digit[5])) % 11;
digit[9] = ((digit[0])+(2*digit[1])+(9*digit[2])+(10*digit[3])+(4*digit[4])+(digit[5])) % 11;
// Insert Parity Checking method (Vandermonde Matrix)
s = new StringBuilder();
for(int i = 0; i < 9; i++)
{
s.append(Integer.toString(digit[i]));
}
if(digit[6] == 10 || digit[7] == 10 || digit[8] == 10 || digit[9] == 10)
{
throw new BadNumberException(str);
}
return (s.toString());
}
}
class BadNumberException
extends Exception
{
public BadNumberException(final String str)
{
super(str + " cannot be encoded");
}
}
I prefer throwing the exception rather than returning a special string. In this case I ignore the exception which normally I would say is bad practice, but for this case I think it is what you want.
Hard to tell, if I got your problem, but after reading your question several times, maybe that's what you're looking for:
public List<String> encodeAll() {
List<String> allEncodings = new ArrayList<String>();
for (int i = 0; i < 1000000 ; i++) {
String encoding = encoding(Integer.toString(i));
allEncodings.add(encoding);
}
return allEncodings;
}
There's one flaw in the solution, the toOctalString results are not 0-padded. If that's what you want, I suggest using String.format("<something>", i) in the encoding call.
Update
To use it in your current call, replace a call to encoding(String str) with call to this method. You'll receive an ordered List with all encodings.
I aasumed, you were only interested in octal values - my mistake, now I think you just forgot the encoding for value 000009 in you example and thus removed the irretating octal stuff.

Categories

Resources