Radix sort with array of custom linked lists - error trying to print - arrays

I have an assignment for class and we have to use a radix sort using an array of linked lists.
It should split a string into a key and value, and store them as an Entry.
public class Entry {
public String key;
public String value;
public Entry() {
}
public Entry(String key, String value) {
this.key = key;
this.value = value;
}
}
The Entry class is pretty basic, I dont think it has any problems.
The issue is that I can either get the while loop to iterate exactly once and then the program completely stops, or I can cause an infinite loop depending on whether or not I use array[10].removeHead() twice or not
import java.io.File; // Import the File class
import java.io.FileNotFoundException; // Import this class to handle errors
import java.util.Scanner; // Import the Scanner class to read text files
public class RadixSort {
public static void main(String[] args) {
try {
LinkedList[] array = new LinkedList[11];
for(int i = 0; i < 11; i++) {
array[i] = new LinkedList();
}
File myObj = new File("years.txt");
Scanner myReader = new Scanner(myObj);
int counter = Integer.parseInt(myReader.nextLine());
System.out.println(counter);
while (myReader.hasNextLine()) {
String string = myReader.nextLine();
if (string.equals("END")) break;
String[] parts = string.split(",");
String part1 = parts[0];
String part2 = parts[1];
Entry a = new Entry(part1, part2);
array[10].addTail(a);
//System.out.println(array[ 0].removeHead().key);
// this works, but gives null ptr exception^^^
System.out.println(array[10].peekHead().key + "," + array[10].peekHead().value);
array[10].removeHead();
}
for (int i = counter; i > 0; i--) {
while (!array[10].peekHead().key.contains(null)) {
String s = array[10].peekHead().key;
String g = array[10].peekHead().value;
int a = Integer.parseInt(s.substring(i-1));
System.out.println(a);
//System.out.println(s);
Entry bruh = new Entry(s, g);
array[a].addHead(bruh);
if (s.equals(null)) System.out.println("error");
//System.out.println(array[10].peekHead().key);
//System.out.println(array[a].peekHead().value);
array[10].removeHead();
System.out.println(array[a].peekHead().key);
}
for (int j = 0; j < 10; j++) {
while (!array[j].peekHead().key.equals(null)) {
array[10].addTail(array[j].removeHead());
}
}
}
while (!array[10].peekHead().key.equals(null)) {
System.out.println(array[10].peekHead().key + "," + array[10].peekHead().value);
array[10].removeHead();
}
myReader.close();
} catch (FileNotFoundException e) {
System.out.println("An error occurred.");
e.printStackTrace();
}
}
}
When I try to print it out it just prints the first Node a bunch of times and then throws a NullPointerException like below:
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.lang.CharSequence.toString()" because "s" is null
at java.base/java.lang.String.contains(String.java:2054)
at RadixSort.main(RadixSort.java:34)
My linked list class should work fine, I did it for our first assignment and tested it pretty thoroughly and it had no errors that I could see.
I tried to just add a couple more removeHead() functions to see if that would change anything and it just keeps throwing that dumb null pointer exception. If anyone could help with anything I would be incredibly grateful.

Related

Shuffle list to maximise distances between similar elements

In a list of URLs
http://a.com/foo
http://b.com/bar
http://a.com/monkey
http://c.com/prune
http://a.com/bear
http://b.com/walrus
http://b.com/baz
http://b.com/plugh
I want to maximise the distance between any pair of a.com's, any pair of b.com's etc. This needs to be cheap but does not have to be optimum. (I am using a list of URLs to download files from websites a.com, b.com, c.com, and do not wish to visit any particular site with a higher frequency than necessary. In the example here, we would hit the b.com site 3 times in succession, which should be avoided.)
I would ideally like a Java library but would settle for pseudocode.
Maximise sum of pairwise distances in array seems to be a similar problem but didn't have a simple answer - I simply want something that's "good enough"
Since no answers, I wrote my own. It's very crude but works. It reads a list of URLs, extracts the hosts, counts them and then fills a pigeon-hole array with indexes proportional to the inverse frequency of the hosts.
package org.xmlcml.cmine.util;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import com.google.common.collect.HashMultiset;
import com.google.common.collect.Multiset;
public class URLShuffler {
public static final Logger LOG = Logger.getLogger(URLShuffler.class);
static {
LOG.setLevel(Level.DEBUG);
}
// in case we needed extra pigeonholes but it doesn't seem to for medium problems
private static int TOL = 1;
private List<String> urls;
private Multiset<String> domains;
private Map<String, Integer> currentIndexByDomain;
private Map<String, Integer> countByDomain;
private List<String> outputUrls;
public URLShuffler() {
}
public void readURLs(List<String> urls) {
this.urls= urls;
domains = HashMultiset.create();
for (String url : urls) {
String domain = getDomain(url);
domains.add(domain);
}
LOG.debug(domains);
}
// this would be better using java.net.URL
private String getDomain(String url) {
int idx = url.indexOf("//");
if (idx != -1) {
url = url.substring(idx+2);
}
idx = url.indexOf("/");
String domain = url.substring(0, idx);
return domain;
}
public List<String> getShuffledUrls() {
currentIndexByDomain = new HashMap<String, Integer>();
countByDomain = new HashMap<String, Integer>();
outputUrls = new ArrayList<String>();
for (int i = 0; i < urls.size() * TOL; i++) {
outputUrls.add("");
}
// this is a convenience method wrapping Guava sort.
for (Multiset.Entry<String> entry : CMineUtil.getEntriesSortedByCount(domains)) {
LOG.debug(entry);
countByDomain.put(entry.getElement(), entry.getCount());
currentIndexByDomain.put(entry.getElement(), entry.getCount() - 1);
}
for (String url : urls) {
String domain = getDomain(url);
Integer currentIndex = currentIndexByDomain.get(domain);
Integer count = countByDomain.get(domain);
int slot = (urls.size() * currentIndex * TOL) / count;
currentIndexByDomain.put(domain, currentIndex - 1);
addUrl(url, slot);
}
return outputUrls;
}
private void addUrl(String url, int slot) {
boolean filled = fillLower(url, slot);
if (!filled) {
fillUpper(url, slot);
}
}
// if slot is not free run upwards till next free slot
private boolean fillUpper(String url, int slot) {
for (int i = slot; i < outputUrls.size(); i++) {
if (fill(url, i)) {
return true;
}
}
return false;
}
// if slot is not free run downwards till next free slot
private boolean fillLower(String url, int slot) {
for (int i = slot; i >= 0; i--) {
if (fill(url, i)) {
return true;
}
}
return false;
}
private boolean fill(String url, int slot) {
if (outputUrls.get(slot).equals("")) {
outputUrls.set(slot, url);
return true;
}
return false;
}
}
```

Make a custom ArrayList toString() that displays contents line by line?

I understand with toString() methods, their must be a return type, when an external method is called.
The comment block below describes what I'm trying to do.
Later on when I work with setters and getters, this knowledge will most definitely be invaluable.
import java.util.*;
public class Display_ArrayList {
static ArrayList<String> cars = new ArrayList<String>();
public static void main(String[] args) {
cars.add("Nissan Maxima");
cars.add("Toyota Prius");
cars.add("Renault Clio");
cars.add("Ford Focus");
cars.add("Volkwagen Passat");
System.out.println("");
System.out.println("[Standard toString()]:");
System.out.println(cars.toString());
System.out.println("");
System.out.println("[Custom toString()]:");
System.out.println(custom_cars_toString());
}
// Array list displays the car list all on the same line
public static String getCarList() {
return cars.toString();
}
// *************************************************************************
// I want Array list contents to be displayed on their own lines without
// commas or brackets, while at the same allowing this method to be
// retrieved by a toString() method
// *************************************************************************
// public static void getCarList() {
// for (String element : cars)
// System.out.println(element);
// }
public static String custom_cars_toString() {
return "The cars contained are: \n" + getCarList();
}
}
Can't you just make a class that extends ArrayList which overrides the toString method? Then you could make something like this:
public class DisplayArrayList<T> extends ArrayList {
#Override
public String toString() {
String res = "";
for (int i = 0; i < size(); i++) {
res += (i == 0 ? "" : "\n") + get(i).toString();
}
return res;
}
}
Then you can just put your cars in a DisplayArrayList instead of an ArrayList and then when you print that you will get them all on individual lines.
For example this:
DisplayArrayList<String> list = new DisplayArrayList<>();
list.add("test1");
list.add("test2");
list.add("test3");
list.add("test4");
list.add("test5");
System.out.println(list);
Would output this:
test1
test2
test3
test4
test5
Sorry if this doesn't do what you want to, couldn't completely figure out what you want from your post.

nullpointerexception for array of objects

I have the following test class
public class Driver
{
public static void main(String [] args)
{
BankAccount[] b1 = {new BankAccount(200), new BankAccount(300), new BankAccount(250), new BankAccount(300), new BankAccount(200)};
BankAccountGroup bag = new BankAccountGroup(b1);
}
And BankAccountGroup:
public class BankAccountGroup
{
private BankAccount bank[];
public BankAccountGroup(BankAccount[]b)
{
for(int i =0; i<5;i++)
{
bank[i] = b[i];
}
}
these are just snippets of the whole code. Im getting a nullpointerexception for these two lines:
- bank[i] = b[i];
- BankAccountGroup bag = new BankAccountGroup(b1);
Please help
When you declare bank[] in the BankAccountGroup class it looks like you forgot to give it a length. Because of this, when you call bank[i] in your for loop, anything after i=0 is probably going to give you an error.
something like
private BankAccount[] bank = new BankAccount[5];
Either initialize your array first(Bad).
Or assign it from the value you pass the constructor.
private BankAccount[] bank;
public BankAccountGroup(BankAccount []){
bank = b;
}
You are not initializing the bank array. You also shouldn't assume that the argument will have a length of 5 elements. I would rewrite the class to something like this:
public class BankAccountGroup
{
private BankAccount bank[];
public BankAccountGroup(BankAccount[]b)
{
if (b != null)
{
bank = new BankAccount[b.length];
for(int i=0; i<b.length;i++)
{
bank[i] = b[i];
}
}
}
}

Enum switch in Java

I have this Java class where I am writing the code for applying the overrides. I want to know if using ENUM is appropriate or if I need to use the switch case, how can I use it? Also, I have the for loop that I need to use as a common block of code for each override type. Apart from that, I do have few separate fields that I need to code for each override type.
public class EWFMService
{
private WorkbrainSystemAccessService wsa = new WorkbrainSystemAccessService();
private static final org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(EWFMService.class);
private final static String ovrCalcGrp = "ovrCalcGrp";
private DBConnection conn = null;
private int empId;
private Date ovrDate;
private String ovrTime;
private String ovrAction;
public List<EWFMServiceData> getProcessEWFMOverrides(String userName, String password, List<EWFMServiceInputData> inputData)
throws WSApplicationException{
logger.debug("EWFM Service");
wsa.logOn(userName, password);
List<EWFMServiceData> returnList = new ArrayList<EWFMServiceData> ();
logger.debug("userName = " + userName);
DBConnection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try{
conn = new DBConnection(ConnectionManager.getConnection());
for (int i = 0; i < inputData.size(); i++)
{
Here I want to retrieve the emp_id from the database, store the value in a variable and be able to use the variable in the rest of my program. How do I do it? To retrieve the emp_id, I am using the following query.
conn = new DBConnection(ConnectionManager.getConnection());
String sql = "SELECT EMP_ID FROM EMPLOYEE_HISTORY"
+ " WHERE EMP_VAL2 = **This is where I want to use the variable in which the values of emp_id will be stored. There can be more than 100 emp_ids**"
+ " AND SYSDATE BETWEEN EMPHIST_START_DATE AND EMPHIST_END_DATE";
EWFMServiceInputData inData = (EWFMServiceInputData) inputData.get(i);
OverrideType ot = OverrideType.getOverrideType(inData.getRecordType());
logger.debug("override type = " + ot.toString());
logger.debug("inputData ["+i+"] = " + inData.toString());
OverrideAccess oa = new OverrideAccess(conn);
OverrideData ovr = new OverrideData();
ovr.setOvrUdf4(inData.getReferenceId().toString());
if (ovrAction.equals("APPLY")) {
ovr.setOvrStatus(OverrideData.PENDING);
Here I want to determine the Action. If it is Apply, then I need to find out the recordType. So basically branch it out for each recordType using if else statements or enum as I believe switch doesn't support Java 1.5 which is what I am using. Then for each recordType, I branch out and write the appropriate code corresponding to that recordType. If Action is CANCEL, then I just write the following code.
} else if (ovrAction.equals("CANCEL")) {
String sql = "SELECT * FROM OVERRIDE"
+ " WHERE OVR_UDF4 = ?"
+ " AND OVRTYP_ID = ?";
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
while (rs.next()); {
ovr.assignByName(rs);
ovr.setUpdated(false);
ovr.setRetrieved(true);
ovr.setOvrStatus(OverrideData.CANCEL);
oa.save(ovr);
}
}
ovr.setEmpId(empId);
String strOvrDate = inData.getOvrStartDate();
ovr.setOvrStartDate(DateHelper.parseDate(strOvrDate, "MM/dd/yyyy"));
if (ovrStartTime != null) {
ovr.setOvrStartTime(ovrTime);
}
Object ovrEndDate;
if (ovrEndDate != null) {
ovr.setOvrEndDate(ovrDate);
}
Object ovrEndTime;
if (ovrEndTime!= null) {
ovr.setOvrEndTime(ovrTime);
}
ovr.setOvrComment(inData.getOvrComments());
ovr.setWbuName(inData.getWbuName());
ovr.setWbuNameActual(inData.getWbuNameActual());
ovr.setOvrNewValue("VAC");
ovr.setOvrCreateDate(new Date());
ovr.setOvrtypId(103);
oa.insert(ovr);
RuleEngine.runCalcGroup(conn,
empId,
ovrDate,
ovrDate);
//COMMON BLOCK ENDS HERE
EWFMServiceData outData = new EWFMServiceData();
outData.setReferenceId(inData.getReferenceId());
String [] status = {"SUCCESS", "ERROR", "LOCKED", "EXCEPTION"};
Random ran = new Random();
String gen = status[ran.nextInt(status.length)];
logger.debug("Status is" + status );
outData.setStatus(gen);
if (gen.equals("SUCCESS")){
outData.setErrorDetails("");
} else if (gen.equals("ERROR")) {
outData.setErrorDetails("Usage of time code VAC is not allowed; balance is insufficient." + " error");
} else if (gen.equals("LOCKED")) {
outData.setErrorDetails("Timesheet cannot be edited because it is locked for payroll close." + "locked");
} else if (gen.equals("EXCEPTION")) {
outData.setErrorDetails("{ML}QR_INCORRECT_CONDITION_PARAMETER{/ML}Error in condition AWA Is Self Override Condition: java.lang.NullPointerException{ARGS}AWA Is Self Override Conditionjava.lang.NullPointerException{/ARGS" + "exception");
}
returnList.add(outData);
}
}catch (Exception e){
logger.error("Error occured",e);
throw new WSApplicationException("Error retrieved",e);
}finally{
SQLUtil.cleanUp(conn, ps, rs);
}
wsa.logOff();
logger.debug("inputData+ ");
return returnList;
}
// I need to know if writing enum is okay or can I just write a switch case above in the for loop and branch each override type and declare their individual variables there? What's the best way? Can someone help me with the code?
public enum OverrideType {
WORKDETAIL,
WORKPREMIUM,
EMPLOYEESCHEDULE,
EMPLOYEE;
public static OverrideType getOverrideType(String recordType) {
if(recordType == null) {
throw new IllegalArgumentException("Record Type cannot be null");
}
if(recordType.equals("Work Detail")) {
return WORKDETAIL;
} else if (recordType.equals("Work Premium")) {
return WORKPREMIUM;
} else if (recordType.equals("Schedule")) {
return EMPLOYEESCHEDULE;
} else if (recordType.equals("Shift Pattern")) {
return EMPLOYEE;
} else {
throw new IllegalArgumentException("Record Type cannot be" + recordType);
}
}
}
}
THE OTHER FIELDS I NEED TO INCLUDE ARE AS FOLLOWS:
FOR WORKDETAIL, I NEED TO USE TIMECODE OF FORMAT THAT IS SENT BY THE CLIENT.
FOR WORK PREMIUM, I NEED TO USE TIMECODE OF FORMAT THAT IS SENT BY THE CLIENT AND ANOTHER FIELD IS MINUTES THAT GIVES THE NUMBER OF MINUTES WHICH IS ALSO SENT BY THE CLIENT.
Generally, using enums is appropriate, especially if you have a defined set of possible types.
You can also add behavior to the enums, which could make your enum a little bit more sophisticated:
public enum OverrideType {
WORKDETAIL("Work Detail"),
WORKPREMIUM("Work Premium"),
EMPLOYEESCHEDULE("Schedule"),
EMPLOYEE("Shift Pattern");
private String identifier;
private OverrideType(String identifier){
this.identifier = identifier;
}
public static OverrideType getOverrideType(String recordType) {
if(recordType == null) {
throw new IllegalArgumentException("Record Type cannot be null");
}
for (OverrideType ot : OverrideType.values()) {
if (recordType.equals(ot.identifier)) {
return ot;
}
}
return null;
}
}
The following example shows how to use an interface in enums or an abstract method definition:
public enum OverrideType implements OverrideTypeIF {
WORKDETAIL("Work Detail") {
public int getKey() {
return 0;
}
},
WORKPREMIUM("Work Premium") {
public int getKey() {
return 0;
}
},
EMPLOYEESCHEDULE("Schedule") {
public int getKey() {
return 0;
}
},
EMPLOYEE("Shift Pattern") {
public int getKey() {
return 0;
}
public void myInterfaceMethod() {
// do type specific behavior
}
};
private String identifier;
private OverrideType(String identifier){
this.identifier = identifier;
}
public abstract int getKey();
public void myInterfaceMethod() {
// do default behavior
}
public static OverrideType getOverrideType(String recordType) {
if(recordType == null) {
throw new IllegalArgumentException("Record Type cannot be null");
}
for (OverrideType ot : OverrideType.values()) {
if (recordType.equals(ot.identifier)) {
return ot;
}
}
return null;
}
}
public interface OverrideTypeIF {
void myInterfaceMethod();
}

AS3 mismatch while accessing object in an array

I have encountered quite a challenging one and I'd love to get some support.
Here is the scenario :
The main Game class instances the Level1 Class in charge for spawning enemies through nested For loops and push them to an array.
It then checks for collisions between the Bullet and Enemy and if it find a collision it calls a method in the Enemy class that removes removeChild and Splice itself from the array.
The thing is it works for the first few enemies, and then it will pick the wrong Enemy to destroy, and stop completely to function.
I tried using indexOf to be sure I am referring to the right object, but to no avail.
I think the Pslice and removeChild are pointing to different objects.
This mess happended when I moved the removeChild and splice from the Game Class to the Enmy class
Link to the work in progress : https://dl.dropboxusercontent.com/s/69hcmzygnkx7h1e/space_shooter.swf
I'd like some help on this one.
Thank you !!!
Main class : Game.AS
package
{
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.text.*;
import flash.geom.Point;
public class Game extends MovieClip
{
public var _instance : Game;
public var player:Player;
public static var level1:Level1;
public var bullet:Bullet;
private var bullets_arr:Array;
var fire_on : Boolean;
var fire_counter : int;
public function Game()
{
level1=new Level1(this.stage);
player = new Player ;
addChild(player);
player.y = 600;
bullets_arr = [];
addEventListener(Event.ENTER_FRAME,Main);
stage.addEventListener(MouseEvent.MOUSE_DOWN,mouseDownHandler);
stage.addEventListener(MouseEvent.MOUSE_UP,mouseUpHandler);
}
function mouseDownHandler($e:MouseEvent):void
{
fire_on = true;
}
function mouseUpHandler($e:MouseEvent):void
{
fire_on = false;
fire_counter = 0;
}
function fire():void
{
bullet = new Bullet ;
addChild(bullet);
bullet.x = player.x;
bullet.y = player.y - 32;
bullets_arr.push(bullet);
}
public function Main(e: Event):void
{
player.x = mouseX;
if (bullets_arr)
{
for (var m:int = 0; m < bullets_arr.length; m++)
{
bullets_arr[m].y -= 20;
if(Game.level1.enemies_arr)
{
for (var n:int = 0; n < Game.level1.enemies_arr.length; n++)
{
if (Game.level1.enemies_arr[n].hitTestObject(bullets_arr[m]))
{
if(bullets_arr[m].parent)
{
bullets_arr[m].parent.removeChild(bullets_arr[m]);
bullets_arr.splice(bullets_arr[m],1);
Game.level1.enemies_arr[n].Damage(10, Game.level1.enemies_arr[n]);
}
}
}
}
}
}
if(fire_on)
{
fire_counter++;
if(fire_counter == 01)
{
fire();
}
else if(fire_counter >2)
{
fire_counter =0;
}
}
}
}
}
Level1.as where the enemies are spawned and pushed to the array.
package
{
import flash.display.MovieClip;
import flash.display.Stage;
import flash.events.Event;
public class Level1 extends MovieClip
{
var i:int;
var j:int;
var frame :int;
public var enemy:Enemy;
public var enemies_arr:Array;
public function Level1(target:Stage)
{
frame = 0;
enemies_arr = [];
for (var i:int = 0; i < 5; i++)
{
for (var j:int = 0; j < 3; j++)
{
enemy = new Enemy;
enemy.x = j*100 + 260;
enemy.y = i*40 - 150;
target.addChild(enemy);
enemies_arr.push(enemy);
trace(enemy.parent);
}
}
}
}
}
The Enemy class Enemy.AS
package
{
import flash.display.MovieClip;
public class Enemy extends MovieClip
{
var Health : int;
function Enemy()
{
Health =2;
}
public function Damage(Damage:int, enemyHit:Enemy)
{
Health -= Damage;
if (Health <1)
{
Die(enemyHit);
}
}
private function Die(enemyHit:Enemy)
{
if(enemyHit.parent)
{
this.parent.removeChild(this);
Game.level1.enemies_arr.splice(Game.level1.enemies_arr.indexOf(enemyHit,1));
}
}
}
}
You should traverse both Game.level1.enemies_arr and bullets_arr backwards. The point is, splice() shortens the array, shifts the elements that are in greater positions than the spliced one(s) to lesser indexes, and the loop counter is not automatically adjusted. The error is pretty common, but is often overlooked. Also, with bullets_arr you can get out of the array causing a 1009 error if your last bullet out of bullets_arr will hit an enemy.
A small nitpick: You are checking for the array's existence within a loop, and for another array's existence once within the enter frame listener. In fact you should either initialize them with at least new Array() or [] before you add an event listener to the Main object, or wherever this is assigned to, or check like if (!bullets_arr) bullets_arr=new Array(); and leave it at that, so one check of the array's existence will be needed.
public function Main(e: Event):void
{
player.x = mouseX;
if (!bullets_arr) bullets_arr=new Array();
if (!Game.level1.enemies_arr) throw new Error('Hey programmer, initialize your arrays!');
// ^ bad practice to throw exceptions in listeners, but if you get one, you've coded something wrongly.
for (var m:int=bullets_arr.length-1;m>=0;m--) {
var bm:Bullet=bullets_arr[m]; // TODO fix type
// the local variable is a cleaner and faster approach
bm.y-=20;
for (var n:int=Game.level1.enemies_arr.length-1;n>=0;n--) {
if (!bm) break; // bullet was destroyed, why checking more enemies vs that?
if (Game.level1.enemies_arr[n].hitTestObject(bm)) {
bm.parent.removeChild(bm);
bullets_arr.splice(m,1); // splice is done by index, not by object
bm=null; // oops, missed this. The bullet hit something and is now lost
// so we null the local var, so we can break out the loop.
Game.level1.enemies_arr[n].Damage(10, Game.level1.enemies_arr[n]);
}
}
}
// rest of your code follows here
}
I finally found the problem, it was very stupid of me :
I just mistyped the Die function in the Enemy class :
I have written :splice(Game.level1.enemies_arr.indexOf(enemyHit,1)) instead of splice(Game.level1.enemies_arr.indexOf(enemyHit),1)
Anyway I learnt a lot of think by trying to fix this error.
Thanks

Resources