There is probably a simple solution to this problem I've been having all night. At least I hope there is. When attempting to offer an object to my subQueues LinkedList, I receive a NullPointerException. My program prints out the correct "head" Objects and "digit" integers, but then the Exception is thrown and the program ends.
My program, in short, is supposed to take a mainQueue LinkedList of integers, look at them all one-by-one, and sort them. Its examining the last digit of each integer, and placing them into corresponding subQueues. As of now, I am only to the ones place. After I get past this dilemma, I'll be able to work out the tens, hundreds, etc.
Ex)
mainQueue = { 12 50 215 100 85 539 16 35 }
subQueue[0] = { 50 100 }
subQueue[1] = { }
subQueue[2] = { 12 }
subQueue[3] = { }
subQueue[4] = { }
subQueue[5] = { 215 85 35 }
subQueue[6] = { 16 }
subQueue[7] = { }
subQueue[8] = { }
subQueue[9] = { 539 }
So what am I doing wrong here? Like I said, once I get by this little problem, the rest of the program should be a breeze. Any help is appreciated, thanks!
public class Sorting
{
private LinkedList mainQueue;
private LinkedList[] subQueues;
private final int SIZE = 10;
private int maxDigits; //maximum number of digits
//The constructor instantiates the mainQueue using the LinkedList,
//subQueue array as an array of LinkedList using SIZE(10),
//and initializes maxDigits = 0;
public Sorting()
{
mainQueue = new LinkedList();
for (int i=0; i<SIZE; i++)
{
subQueues = new LinkedList[i];
}
// I have also tried:
// subQueues = new LinkedList[SIZE];
//I get the same runtime error.
maxDigits = 0;
}
public void sortNumbers()
{
while (mainQueue.isEmpty() == false)
{
Object head = mainQueue.peek();
mainQueue.remove();
String digitLine = "" + head;
int digit = Integer.parseInt(digitLine.substring(digitLine.length()-1, digitLine.length()));
System.out.println(head);
System.out.println(digit);
subQueues[digit].offer(head);
}
}
}
You're not correctly building your subQueues it looks like.
If you want an array of SIZE linked-lists, try this:
subQueues = new LinkedList[ SIZE ];
for ( int i = 0; i < SIZE; ++i ) {
subQueues[i] = new LinkedList();
}
Note that this is using raw types as your code is, though preferably you should use parameterized types.
Related
I'm working on this program that emulates restriction enzymes and DNA splicing. I'm using DnaSequenceNode[s] as linked list nodes.
I have a problem with one of the function in my code, cutSplice() is supposed to create a new DnaStrand that is a clone of the current DnaStrand, but with every instance of enzyme replaced by splicee.
For example, if the LinkedDnaStrand is instantiated with "TTGATCC", and
cutSplice("GAT", "TTAAGG") is called, then the linked list should become something like (previous pointers not shown):
first -> "TT" -> "TTAAGG" -> "CC" -> null
My function works. However, my method cutSplice() takes more than 80 seconds to splice 200 DNAs. I'm supposed to bring that 80 seconds to 2 seconds.
This is all my code for the class : LinkedDnaStrand.java
And here's the code for the method cutSplice()
public DnaStrand cutSplice(String enzyme, String splicee) {
DnaStrand newStrand = null;
String original_Dna = this.toString();
String new_Dna = original_Dna.replaceAll(enzyme, splicee);
String[] splicee_split = new_Dna.split(splicee); // splits the new DNA string DnaStrand
newStrand = null;
int i = 0;
if (original_Dna.startsWith(enzyme)) {
newStrand = new LinkedDnaStrand(splicee);
} else {
newStrand = new LinkedDnaStrand(splicee_split[0]);
newStrand.append(splicee);
}
for (i = 1; i < splicee_split.length - 1; i++) {
String node = splicee_split[i];
newStrand.append(node);
newStrand.append(splicee);
}
newStrand.append(splicee_split[splicee_split.length - 1]);
if (original_Dna.endsWith(enzyme)) {
newStrand.append(splicee);
}
return newStrand;
}
Does anybody see anything that could make a critical difference on the time this function takes to process 200 DNAs sample?
Well, it is comfortable to use the string methods, but you are losing time in converting to the string, back to sequence, and (as pointed out in the previous comments) with the regex based string functions.
It will certainly consume less time to operate on the linked list directly, although this will require you to implement the replacement algorithm yourself:
#Override
public LinkedDnaStrand cutSplice(String enzyme, String splicee)
{
LinkedDnaStrand strand = new LinkedDnaStrand();
DnaSequenceNode end = null;
DnaSequenceNode begin = top;
int pos = 0;
DnaSequenceNode tmpStart, tmpEnd;
for (DnaSequenceNode current = top; current != null; current = current.next)
{
if(current.value != enzyme.charAt(pos))
{
tmpStart = tmpEnd = new DnaSequenceNode(begin.value);
for (DnaSequenceNode n = begin.next; n != current.next; n = n.next)
{
DnaSequenceNode c = new DnaSequenceNode(n.value);
tmpEnd.next = c;
c.previous = tmpEnd;
tmpEnd = c;
}
}
else if(++pos == enzyme.length())
{
tmpStart = tmpEnd = new DnaSequenceNode(splicee.charAt(0));
for (int i = 1; i < splicee.length(); ++i)
{
DnaSequenceNode c = new DnaSequenceNode(splicee.charAt(i));
tmpEnd.next = c;
c.previous = tmpEnd;
tmpEnd = c;
}
}
else
{
continue;
}
if(end == null)
{
strand.top = end = tmpStart;
}
else
{
end.next = tmpStart;
tmpStart.previous = end;
}
end = tmpEnd;
begin = current.next;
pos = 0;
}
return strand;
}
I do not claim that there is not any opportunity to further optimize, but this should be a lot faster as the original version. I tested it successfully with the example you gave, if you yet find a bug, feel free to fix it yourself...
Note 1: I did explicitely create a new sequence from the string (instead of using the constructor) to get the end of the sequence without having to iterate over it again.
Note 2: I assumed existing a constructor DnaSequenceNode(char value) and DnaSequenceNode having a member public char value. You might have to adjust the code appropriately if any of these assumptions fails.
I'm trying to compress an array of objects that will have empty items interspersed with complete items. I want to put all the full elements at the start in the same order they started with, and the empty elements on the end.
The object in question uses a String field, "name", and an int field, "weight". An empty version has "no name" and 0 respectively. So an array of the type the method needs to deal with will contain something like:
Fred | 4
Bob | 3
no name | 0
Gina | 9
no name | 0
Yuki | 7
After feeding through the method, the array should go Fred, Bob, Gina, Yuki, no name, no name.
My thought for step one was to just figure out which were full and which weren't, so I came up with this:
public void consolidate() {
boolean[] fullSlots = new boolean[spaces.length];
// pass 1: find empties
for (int i = 0; i < spaces.length; i++) {
fullSlots[i] = spaces[i].getName().equals("no name");
}
}
spaces is the array of objects, getName() retrieves the name field from the object.
I'm not sure where to go from here. Suggestions?
EDIT: Okay, here's what Infested came up with:
public void consolidate()
{
int numberOfEmpties = 0, spacesLength = spaces.length;
Chicken[] spaces2 = new Chicken[spacesLength];
for(int i = 0; i < spaces.length; i++)
{
spaces2[i] = new Chicken(spaces[i].getName(),
spaces[i].getWeight());
}
// pass 1: find empties
for (int i = 0, j = 0; i < spacesLength; i++)
{
if (spaces2[i].getName().equals("no name") == false)
{
spaces[j] = new Chicken(spaces2[i].getName(),
spaces2[i].getWeight());
j++;
}
else
{
numberOfEmpties++;
}
}
for (int i = spacesLength - 1; numberOfEmpties > 0 ; numberOfEmpties--, i--)
{
spaces[i] = new Chicken("no name", 0);
}
}
Tested and working.
Java's Arrays.sort is stable, meaning that the relative order of equal elements is not going to change.
This sort is guaranteed to be stable: equal elements will not be reordered as a result of the sort.
You can use this property of the sorting algorithm to sort all your elements with a simple comparator:
Arrays.sort(
spaces
, new Comparator() {
public int compare(Object o1, Object o2) {
MyClass a = (MyClass)o1;
MyClass b = (MyClass)o2;
boolean aIsEmpty = "no name".equals(a.getName());
boolean bIsEmpty = "no name".equals(b.getName());
if (aIsEmpty && !bIsEmpty) {
return 1;
}
if (!aIsEmpty && bIsEmpty) {
return -1;
}
return 0;
}
}
);
This will sort all items with non-empty names ahead of the items with empty names, leaving the relative order of both groups of objects unchanged within their respective group.
If your space constraints allow you to create a new array of MyClass, you can go for a simpler algorithm: go through the original array once, and make a count of non-empty items. Then create a new array, and make two indexes: idxNonEmpty = 0, and idxEmpty = NonEmptyCount+1. Then go through the original array one more time, writing non-empty objects to idxNonEmpty++, and empty objects to idxEmpty++.
ill assume its a method of the class:
public void consolidate()
{
int lengthOfSpaces = spaces.length , i, numberOfEmpties = 0;
Type[] spacesNumberTwo = new Type[lengthOfSpaces ];
// pass 1: find empties
for (i = 0; i < lengthOfSpaces ; i++)
{
if(spaces[i].getName().equals("no name") == false)
spacesNumberTwo[i] = new Type(spaces[i].getName(), spaces[i].getInt());
else
numberOfEmpties++;
}
for (i = lengthOfSpaces - 1; numberOfEmpties > 0 ; numberOfEmpties--, i--)
{
spacesNumberTwo[i] = new Type("no name", 0);
}
spaces = spacesNumberTwo
}
I'm making an app where the user has to choose a 4 digit number, and this will be compared to a randomly chosen hidden 4 digit number, but when ever I run the code which should check my array for a comparison between the chosen numbers and the random numbers the 'Arrays.asList().contains())' doesn't seem to pickup on the fact that the array it is checking does have the value it is checking for, any advice?
The code that compares the two variables:-
guess.v1 = code.int1;
guess.v2 = code.int2;
guess.v3 = code.int3;
guess.v4 = code.int4;
int[] guess_list = { guess.v1, guess.v2, guess.v3, guess.v4 };
if (Arrays.asList(guess_list).contains(home.value1)) {
if (code.int1 == home.value1) {
X1.setText("V");
guess.c1 = GuessStatus.V;
} else {
X1.setText("S");
guess.c1 = GuessStatus.S;
}
} else {
X1.setText("X");
guess.c1 = GuessStatus.X;
}
The code that generates the random numbers:-
Code.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent openCode = new Intent(b, code.class);
// adventure_time checks whether there is a saved game already,
// if 1, saved game,
adventure_time = 0;
// random number generation LET THE NUMBER GAMES BEGIN///
Random a1 = new Random();
random1 = new ArrayList<Integer>();
check.fudge = 0;
for (int index = 0; index < 4; index++) {
random1.add(a1.nextInt(5) + 1);
Log.v("MM", "" + random1.get(index));
}
value1 = random1.get(0);
value2 = random1.get(1);
value3 = random1.get(2);
value4 = random1.get(3);
startActivity(openCode);
}
});
You're not calling the Arrays.asList call you think you are. You're actually creating a List<int[]>, not a List<Integer> are you're probably expecting. (There's no such type as List<int> in Java, as it doesn't support generics over primitive types.)
The simplest fix would be to change this:
int[] guess_list = { guess.v1, guess.v2, guess.v3, guess.v4 };
to this:
Integer[] guess_list = { guess.v1, guess.v2, guess.v3, guess.v4 };
You'll then end up creating a List<Integer> which will work appropriately.
Right now I have my array sorting (which is better than getting an error) except it is sorting in the reverse than what I want it to sort in.
public static void sortDatabase(int numRecords, String[] sDeptArr,
int[] iCourseNumArr, int[] iEnrollmentArr)
{
System.out.println("\nSort the database. \n");
String sTemp = null;
int iTemp = 0;
int eTemp = 0;
String a, b = null;
for(int i=0; i<numRecords; i++)
{
int iPosMin = i+1;
for(int j=iPosMin; j<numRecords; j++)
{
a = sDeptArr[i];
b = sDeptArr[iPosMin];
if(a.compareTo(b) > 0)
{
sTemp= sDeptArr[j];
sDeptArr[j] = sDeptArr[iPosMin];
sDeptArr[iPosMin] = sTemp;
iTemp = iCourseNumArr[j];
iCourseNumArr[j] = iCourseNumArr[iPosMin];
iCourseNumArr[iPosMin] = iTemp;
eTemp = iEnrollmentArr[j];
iEnrollmentArr[j] = iEnrollmentArr[iPosMin];
iEnrollmentArr[iPosMin] = eTemp;
}
else if(sDeptArr[j].equals(sDeptArr[iPosMin]) && !(iCourseNumArr[j] < iCourseNumArr[iPosMin]))
{
sTemp= sDeptArr[i];
sDeptArr[i] = sDeptArr[iPosMin];
sDeptArr[iPosMin] = sTemp;
iTemp = iCourseNumArr[i];
iCourseNumArr[i] = iCourseNumArr[iPosMin];
iCourseNumArr[iPosMin] = iTemp;
eTemp = iEnrollmentArr[i];
iEnrollmentArr[i] = iEnrollmentArr[iPosMin];
iEnrollmentArr[iPosMin] = eTemp;
}
else continue;
}
}
}
Again, no array lists or array.sorts. I need just to reverse how this is sorting but I have no idea how.
just do a.compareTo(b) < 0 instead of the > 0
EDIT: I've figured out the problem. But since this is homework (thanks for being honest), I won't post my solution, but here are a few tips:
You are doing selection sort. The algorithm isn't as complicated as you made it. You only have to swap if the two elements you are checking are in the wrong order. I see you have 3 branches there, no need.
Take a look at when you are assigning a and b. Through the inner loop, where j is changing, a and b never change, because i and iPosMin stay the same. I hope that helps.
It's always good to break your algorithm down to discreet parts that you know works by extracting methods. You repeat the same swap code twice, but with different arguments for indices. Take that out and just make a:
-
// swaps the object at position i with position j in all arrays
private static void swap(String[] sDeptArr, int[] iCourseNumArr, int[] iEnrollmentArr, int i, int j)
Then you'll see you're code get a lot cleaner.
First I'd say you need to build a data structure to encapsulate the information in your program. So let's call it Course.
public class Course {
public String department;
public Integer courseNumber;
public Integer enrollment;
}
Why not use the built in sort capabilities of Java?
List<Course> someArray = new ArrayList<Course>();
...
Collections.sort( someArray, new Comparator<Course>() {
public int compare( Course c1, Course c2 ) {
int r = c1.compareTo( c2 );
if( r == 0 ) { /* the strings are the same sort by something else */
/* using Integer instead of int allows us
* to compare the two numbers as objects since Integer implement Comparable
*/
r = c1.courseNumber.compareTo( c2.courseNumber );
}
return r;
}
});
Hope that gets you an A on your homework. Oh and ditch the static Jr. Maybe one day your prof can go over why statics are poor form.
Hmm... I wonder what would happen of you altered the line that reads if(a.compareTo(b) > 0)?
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.