I have this code that asks for numbers and then introduces them into an array, then, I have to separate positives, negatives and nulls.
I'm having trouble with creating the array of each type.
For example, I start the code, I introduce 5 numbers(1,2,3,4,5), then goes to the method that assings the positives to the positiveArray, negatives to the negativeArray and nulls to the nulledArray.
But when I print, for example, positiveArray, only adds at the final index
I read that everytime I call ArrayUtils.add(), it should be placing the number at the end, but not like what I'm getting, that should be like this:
int[] numbers= new int[4];
numbers = ArrayUtils.add(numbers , 1);
numbers = ArrayUtils.add(numbers , 2);
numbers = ArrayUtils.add(numbers , 3);
numbers = ArrayUtils.add(numbers , 4);
numbers = {1,2,3,4}
Or am I wrong?
I'm using ApacheCommons
Thanks
import java.util.Arrays;
import javax.swing.JOptionPane;
import org.apache.commons.lang3.ArrayUtils;
public class das {
private int cantidadElementos = 0;
private int pos = 0, neg = 0, nulos = 0; //contadores de los números positivos y negativos
private int[] numeros = new int[10]; //array que contendrá los números leídos por teclado
private int[] numerosNegativos;
private int[] numerosPositivos;
private int[] numerosNulos;
public static void main(String[] args) {
das das = new das();
das.agregarElementos();
das.cantidadPositivos();
}
public void agregarElementos(){
int i = 0;
for (i = 0; i < 10; i++) {
try {
numeros[i] = (Integer.parseInt(JOptionPane.showInputDialog(null, "Introduce un valor", "Agregando elemento ["+cantidadElementos+"]", JOptionPane.QUESTION_MESSAGE)));
if(numeros[i] > 0)
{
pos++;
}
else if (numeros[i] < 0)
{
neg++;
}
else
{
nulos++;
}
cantidadElementos++;
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "Has agregado "+cantidadElementos+" elementos.", "Información que cura", JOptionPane.INFORMATION_MESSAGE);
return;
}
}
}
public void cantidadPositivos(){
int i = 0;
for(i = 0; i < cantidadElementos; i++)
{
if(numeros[i] >= 1)
{
numerosPositivos = new int[pos];
numerosPositivos = ArrayUtils.add(numerosPositivos, numeros[i]);
System.out.println(Arrays.toString(numerosPositivos));
}
else if (numeros[i] <=-1)
{
numerosNegativos = new int[neg];
numerosNegativos = ArrayUtils.add(numerosNegativos, numeros[i]);
}
else
{
numerosNulos = new int[nulos];
numerosNulos = ArrayUtils.add(numerosNulos, numeros[i]);
}
}
JOptionPane.showMessageDialog(null, "De los [ "+cantidadElementos +" ] elementos en el vector:\n\nPositivos: "+ pos +"\n\nNegativos: "+ neg +"\n\nNulos: " + nulos + "\n", "Información que cura", JOptionPane.INFORMATION_MESSAGE, null);
}
}
The problem is that you recreate a new array at each iteration, like this line (in cantidadPositivos()):
numerosPositivos = new int[pos];
You should define those arrays before entering the for cycle.
public void cantidadPositivos(){
int i = 0;
numerosPositivos = new int[pos];
numerosNegativos = new int[neg];
numerosNulos = new int[nulos];
for(i = 0; i < cantidadElementos; i++)
{
if(numeros[i] >= 1)
{
numerosPositivos = ArrayUtils.add(numerosPositivos, numeros[i]);
System.out.println(Arrays.toString(numerosPositivos));
}
else if (numeros[i] <=-1)
{
numerosNegativos = ArrayUtils.add(numerosNegativos, numeros[i]);
}
else
{
numerosNulos = ArrayUtils.add(numerosNulos, numeros[i]);
}
}
JOptionPane.showMessageDialog(null, "De los [ "+cantidadElementos +" ] elementos en el vector:\n\nPositivos: "+ pos +"\n\nNegativos: "+ neg +"\n\nNulos: " + nulos + "\n", "Información que cura", JOptionPane.INFORMATION_MESSAGE, null);
}
When you use new int[4] you get an array like [0, 0, 0, 0] since int is primitive so it cannot be null.
ArrayUtil.add does not replace those 0 values, since they are valid entries, so it just appends your new number to the array.
So i would suggest to start with an empty array.
Related
I'm a noob in java and just starting out.
I have this problem: there is a boolean[] stored in the HashMap
HashMap <String,boolean[]> calendar = new HashMap<String, boolean[]>();
So every element of intervalls should be true, but console says that all are false when running setFree(1, false, "01010001");.
import java.util.HashMap;
public class Calendar {
int numberOfIntervalls = 12;
HashMap <String,boolean[]> calendar = new HashMap<String, boolean[]>();
public Calendar() {
}
private void summonDay(String _day) {
/*
* Der String setzt sich nach dem Prinzip ddmmyyyy zusammen.
*/
boolean[] intervalls = new boolean[numberOfIntervalls];
System.out.print("Summoned " + _day + " ");
for (int i = 0; i < numberOfIntervalls; i++) {
intervalls[i] = true;
System.out.print(intervalls[i] + ", ");
}
System.out.println(".");
calendar.put(_day, intervalls);
}
public boolean isFree(int _time, String _day) {
int time = _time - 1;
if(!calendar.containsKey(_day)) {
System.out.println("free");
return true;
}
boolean[] _intervalls = calendar.get(_day);
_intervalls = calendar.get(_day);
for (int i = 0; i <calendar.get(_day).length; i++) {
System.out.print(calendar.get(_day)[i] + ", ");
}
for (int i = 0; i < _intervalls.length; i++) {
System.out.print(_intervalls[i] + ", ");
}
System.out.println(_intervalls[time]);
return _intervalls[time];
}
public void setFree(int _time, boolean _free, String _day) {
int time = _time - 1;
boolean[] intervalls = new boolean[numberOfIntervalls];
if(calendar.containsKey(_day)) {
System.out.println("Contains " + _day);
intervalls = calendar.get(_day);
intervalls[time] = _free;
System.out.println(intervalls[time]);
if(allElementsTheSameBool(intervalls) && _free)
calendar.remove(_day);
else
calendar.put(_day, intervalls);
}else {
if(!_free) {
summonDay(_day);
intervalls[time] = _free;
calendar.put(_day, intervalls);
}
}
System.out.println("-------");
for (int i = 0; i <calendar.get(_day).length; i++) {
System.out.print(calendar.get(_day)[i] + ", ");
}
}
public boolean allElementsTheSameBool(boolean[] intervalls) {
if (intervalls.length == 0) {
return true;
} else {
boolean first = intervalls[0];
for (int i = 0; i < intervalls.length; i++) {
if (intervalls[i] != first) {
return false;
}
}
return true;
}
}
public int getNumberOfIntervalls() {
return numberOfIntervalls;
}
public boolean isLeapYear(int _year) {
/*
* Schaltjahre müssen durch 4 teilbar sein.
Ist das Jahr auch durch 100 teilbar, ist es kein Schaltjahr, es sei denn...
...das Jahr ist ebenfalls durch 400 teilbar – dann ist es ein Schaltjahr.
*/
if(_year%4 == 0) {
if(_year%100 == 0) {
if(_year%400 == 0)
return true;
return false;
}
return true;
}
return false;
}
public void toTest(/* insert Parameters*/) {
}
}
(All the System.out.println(); are just for debugging.)
I really have no clue which line sets it all false...
An important thing to keep in mind is that something like this:
boolean[] intervals = new boolean[3];
Will create an array with: [false, false, false]. It seems that the problem may be about this.
I've tested your code and it is not 100% clear what is the starting point, but if you run the summonDay() before the setFree(). In order to "fill" the day with intervals, I think you get the expected result.
What I did was:
static int numberOfIntervalls = 12;
static Map<String,boolean[]> calendar = new HashMap<>();
public static void main(String[] args) {
summonDay("01010001");
setFree(3, false, "01010001");
}
private static void summonDay(String _day) {
boolean[] intervals = new boolean[numberOfIntervalls];
System.out.print("Summoned " + _day + " ");
for (int i = 0; i < numberOfIntervalls; i++) {
intervals[i] = true;
System.out.print(intervals[i] + ", ");
}
System.out.println(".");
calendar.put(_day, intervals);
}
public static void setFree(int _time, boolean _free, String _day) {
int time = _time - 1;
boolean[] intervals = new boolean[numberOfIntervalls];
if(calendar.containsKey(_day)) {
System.out.println("Contains " + _day);
intervals = calendar.get(_day);
intervals[time] = _free;
System.out.println(intervals[time]);
if(allElementsTheSameBool(intervals) && _free)
calendar.remove(_day);
else
calendar.put(_day, intervals);
}else {
if(!_free) {
summonDay(_day);
intervals[time] = false;
calendar.put(_day, intervals);
}
}
System.out.println("-------");
for (int i = 0; i <calendar.get(_day).length; i++) {
System.out.print(calendar.get(_day)[i] + ", ");
}
}
If you check the main() you have there both methods being called
And my output was:
Summoned 01010001 true, true, true, true, true, true, true, true, true, true, true, true, .
Contains 01010001
false
-------
true, true, false, true, true, true, true, true, true, true, true, true,
Process finished with exit code 0
So it started with 12 trues and after the setFree() was called it freed the third interval.
It seems that the problem is that you are missing this:
for (int i = 0; i < numberOfIntervalls; i++) {
intervals[i] = true;
System.out.print(intervals[i] + ", ");
}
When creating a day and that is the reason behind the all false intervals.
IMPORTANT: Probably a rookie question, but I'm clueless on how to solve it.
I have a UI class which I use to input a name and gender (geslacht) using a scanner (see code below)
private static void geefNaamEnGeslacht(int aantal) {
String naam, geslacht;
for (int i = 0; i < aantal; i++) {
System.out.print("Wat is de naam van speler " + (i + 1) + " (min 6 tekens, max 12 tekens)? ");
naam = sc.next();
naam += sc.nextLine();
System.out.print("Wat is het geslacht van speler " + (i + 1) + "(man=m vrouw=v)? ");
geslacht = sc.next();
System.out.println(naam.length());
try {
dc.maakSpelerAan(naam, geslacht.charAt(0));
} catch (NameLengthNotValidException e) {
System.out.println(e.getMessage());
i--;
}
}
}
In my domain class I check the length of that name in the setter, but it always throws the exception, no matter what I tried. When debugging, the length of any name I picked checks out to be between 6 and 12 characters strangely enough. (see code below)
public final void setNaam(String naam) {
int lengte = naam.length();
if (naam.length() < 6 || naam.length() > 12) {
throw new NameLengthNotValidException("Je naam moet tussen 6 en 12 tekens liggen!");
}
this.naam = naam;
}
Any ideas or tips are apreciated.
EDIT1 code of dc.maakSpelerAan
public void maakSpelerAan(String naam, char geslacht){
s.maakSpeler(naam, geslacht);
}
EDIT2 code of s.maakspeler
public void maakSpeler(String naam, char geslacht){
if (spelCompleet()) {
throw new ListFilledException("De lijst met spelers is vol !");
}
if (!controleerUniekeNaam(naam)) {
throw new NotUniqueNameException();
}
Kaart[] schatkaarten = new Kaart[STARTAANTAL];
Kaart[] kerkerkaarten = new Kaart[STARTAANTAL];
for (int i = 0; i > STARTAANTAL; i++) {
schatkaarten[i] = stapels.get(SCHATKAART).geefBovensteKaart();
kerkerkaarten[i] = stapels.get(KERKERKAART).geefBovensteKaart();
}
try{
Speler s = new Speler(naam, geslacht);
s.getKaarten(kerkerkaarten, schatkaarten);
spelers.add(s);
}catch (IllegalArgumentException | NameLengthNotValidException e){
throw e;
}
if (spelCompleet()) {
//UC2
spelers.get(EERSTESPELERINDEX).setBeurt(true);
}
}
EDIT3 REPOST WITH CORRECT IMAGE Image of variable "naam" right before it goes in the IF loop while debugging. MINLENGTHNAAM and MAXLENGTHNAAM are set to 6 and 12 respectively in an interface class.
EDIT4 Code in my interface class for MINLENGTH AND MAXLENGTH
public interface SpelInfo {
final int STARTAANTAL = 2;
final int MAXAANTALPUNTEN = 10;
final int INDEXNAAMDETAILS = 0;
final int INDEXGESLACHTDETAILS = 1;
final int INDEXPUNTENDETAILS = 2;
final int MINAANTALSPELERS = 3;
final int MAXAANTALSPELERS= 6;
final int EERSTESPELERINDEX = 0;
final int MAXLENGTHNAAM = 6;
final int MINLENGTHNAAM = 12;
final int AANTALSTAPELS = 2;
final char MAN = 'm';
final char VROUW = 'v';
final int SCHATKAART = 0;
final int KERKERKAART = 1;
}
In "Edit4" you need to change the green line into:
if(naam.length() > MAXLENGTHNAAM || naam.length() < MINLENGTHNAAM) {
Just a little logical issue :)
I'm trying to build simple multithreading application. But I'm confused about Java monitors. I have many threads that want to format with their data one array. So for example I have Supermarket Threads (data of the thread is in txt file) So first thread have these product (Milk, Cheese, Chocolate) and country code for each product 1,2, 3
SupermarketA
Milk 1
Cheese 2
Chocolate 3
SupermarketB
Yogurt 1
Orangle 2
Bannana 3
Tea 7
Kiwi 9
and I want to format array that has to fields (country_code and count)
So my array should look like that
Country_code count
1 2
2 2
3 2
7 1
9 1
Code
public class SortedArray{
private int num = 0; // num is country code
private int count = 0;
}
So here's my monitor class
public class SingleArray {
private SortedArray[] array;
private int arrayIndex;
private static final int MAX_SIZE = 5;
public SingleArray() {
array = new SortedArray[MAX_SIZE];
arrayIndex = 0;
initArray();
}
private void initArray() {
for (int i = 0; i < MAX_SIZE; i++) {
array[i] = new SortedArray();
}
}
public synchronized void inc(){
awaitUnderMax();
notifyAll();
}
private void awaitUnderMin(){
while (arrayIndex == 0) try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void dec(){
awaitUnderMin();
notifyAll();
}
public void add(ArrayList<Integer> count){
for (int i = 0; i < count.size(); i++) {
singleArray.inc();
int num = count.get(i);
if (singleArray.arrayIndex == 0) { // if array is empty add value to it
singleArray.array[0].num = num;
singleArray.array[0].count++;
singleArray.arrayIndex++;
} else {
if (!isThere(num)) { // if num is a new value to array
singleArray.inc();
int index1 = singleArray.arrayIndex;
if (num > singleArray.array[index1 - 1].num) {
singleArray.inc();
singleArray.array[index1].num = num;
singleArray.inc();
singleArray.array[index1].count++;
singleArray.inc();
singleArray.arrayIndex++;
System.out.println(Thread.currentThread().getName() + " first " + singleArray.array[index1].num);
} else if (num < singleArray.array[index1 - 1].num) { // jei num mazesne uz paskutinia masyvo reiksme
int index = index1 - 1 < 0 ? index1 : index1 - 1;
while (index > 0 && num < singleArray.array[index].num) {
index--;
}
if (index != singleArray.arrayIndex) {
System.out.println(Thread.currentThread().getName() + " sec " + singleArray.array[index].num);
singleArray.array = addPos(singleArray.array, index + 1, num);
}
}
}
}
}
}
public boolean isThere(int number){
for(int i=0; i<singleArray.arrayIndex; i++){
singleArray.inc();
if(number == singleArray.array[i].num){
singleArray.array[i].count++;
return true;
}
}
return false;
}
private void awaitUnderMax(){
while (arrayIndex >= MAX_SIZE) try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void removeValue(int number, int howManyItems){
for(int i=0; i<arrayIndex; i++){
dec();
if(number == array[i].num){
int numberToDelete = array[i].count - howManyItems >= 0 ? howManyItems : array[i].count;
if(array[i].count >= numberToDelete){
array[i].count -= numberToDelete;
}
if(array[i].count == 0){
deleteItem(i);
}
}
if(array[i].count == 0){
deleteItem(i);
}
}
}
Each thread call add(ArrayList<Integer> count) method
So basically what add method does:
Find place where to insert new value (dependng if new value is greater or lower than a previous)
call isThere(int num) method that check if new value is already in array (if so increment count singleArray.array[i].count++) otherwise add new value to array
If array is full arrayIndex == MAX_SIZE wait current thread for other threads to decrement arrayIndex (this is oly one part of code I also have other threads that based on county code decrement array)
So the biggest problem is that multiplethreads need to update single array at the same time (I know that adding synchronized keyword to add method should solve this problem but it only let one thread to run this method at once!) So sometimes all works fine, but sometimes I get really starnge results (for example that country code is 0 (That is imposible!!!) and sometimes new values is placed in wrong array posiitons). Also I think that semaphores should solve this problem, but is it possible to do that with monitors? Thank's for the answers.
EDIT v2
to #Elyasin
public Thread[] setUpShopsBuilderThreads(){
int size = data.getSize();
ArrayList<ArrayList<String>> a = new ArrayList<>();
ArrayList<ArrayList<Integer>> b = new ArrayList<>();
ArrayList<ArrayList<Double>> c = new ArrayList<>();
Thread[] threads = new Thread[size];
for (int i = 0; i < size; i++) {
int tmp = data.getIndex(i);
int range = i + 1 < size ? data.getIndex(i + 1) : data.getWaresSize();
ArrayList<String> name = new ArrayList<>();
ArrayList<Integer> count = new ArrayList<>();
ArrayList<Double> price = new ArrayList<>();
for (int j = tmp; j < range; j++) {
name.add(data.getName(j));
count.add(data.getCount(j));
price.add(data.getPrice(j));
}
a.add(name);
b.add(count);
c.add(price);
}
procesas_1 p1 = new procesas_1(a.get(0), b.get(0), c.get(0));
procesas_2 p2 = new procesas_2(a.get(1), b.get(1), c.get(1));
procesas_3 p3 = new procesas_3(a.get(2), b.get(2), c.get(2));
procesas_4 p4 = new procesas_4(a.get(3), b.get(3), c.get(3));
procesas_5 p5 = new procesas_5(a.get(4), b.get(4), c.get(4));
Thread worker1 = new Thread(p1);
Thread worker2 = new Thread(p2);
Thread worker3 = new Thread(p3);
Thread worker4 = new Thread(p4);
Thread worker5 = new Thread(p5);
threads[0] = worker1;
threads[1] = worker2;
threads[2] = worker3;
threads[3] = worker4;
threads[4] = worker5;
return threads;
}
public static void main(String[] args) {
Starter start = new Starter();
start.read();
start.printShopsData();
start.printUserData();
Thread[] builderThreads = start.setUpShopsBuilderThreads();
for(int i=0; i<builderThreads.length; i++){
builderThreads[i].start();
}
}
what about using the concurrent safe datasets java already provides?
if you want it sorted, this one looks it might work for you:
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentSkipListSet.html
just add it as in a normal Collection
This question already has answers here:
Error: Selection does not contain a main type
(24 answers)
Closed 8 years ago.
So I have an assignment to do, its in spainsh but i hope its okay.
the problem is i did everything according to the instructions they gave me and when i try to run it with eclipse, it says "selection does not contain a main type" i dont know what to do because in my instructions they didnt say to put "main (string ...etc."
this is my code:
BTW TelemetriaEstado and CoordenadaEcuatorial are both two classes that they gave me already done, so they shouldnt be the problem:package es.upm.dit.prog.p3;
public class GestorTelemetrias {
final int N_MAX_TELEMETRIAS = 5;
private TelemetriaEstado [] telemetriasAlmacenadas;
private int totalTMalmacenadas;
/**
* construcor de la clase GestorTelemetrias. Inicia el objeto.
*/
public GestorTelemetrias () {
totalTMalmacenadas = 0;
telemetriasAlmacenadas = new TelemetriaEstado [N_MAX_TELEMETRIAS];
}
/**
* Metodo que guarda 5 telemetrias de estado, sin que se repitan y ignorando las de valor null.
*/
public void setTelemetrias (TelemetriaEstado [] telemetrias) throws NullPointerException {
if (telemetrias == null)
throw new NullPointerException (); //aseguramos no guardar ninguna telemetria con valor null.
totalTMalmacenadas = 0; //ponemos el contador de telemetrias almacenadas a 0.
for (int i=0; i < telemetrias.length; i++) {
if (telemetrias[i] != null) {
telemetriasAlmacenadas [totalTMalmacenadas++] = telemetrias[i];
}
if (totalTMalmacenadas == N_MAX_TELEMETRIAS) break;
}
}
public TelemetriaEstado[] getTelemetrias () {
TelemetriaEstado [] telemetrias = new TelemetriaEstado [totalTMalmacenadas];
for (int i=0; i < totalTMalmacenadas; i++) {
telemetrias [i] = telemetriasAlmacenadas[i];
}
return telemetrias;
}
public void insertarTelemetria (TelemetriaEstado unaTelemetria) throws NullPointerException, Exception {
if (unaTelemetria == null)
throw new NullPointerException ();
for (int i=0; i< totalTMalmacenadas; i++) {
if (telemetriasAlmacenadas[i].equals(unaTelemetria))
throw new Exception("La telemetria que intenta insertar ya está almacenada");
if (!telemetriasAlmacenadas[i].equals(unaTelemetria))
telemetriasAlmacenadas[i] = unaTelemetria;
}
}
public int obtenerNumeroTelemetrias () {
return totalTMalmacenadas;
}
public void eliminarTelemetria (TelemetriaEstado unaTelemetria) throws NullPointerException, Exception {
if (unaTelemetria == null) throw new NullPointerException ();
for (int i=0; i< totalTMalmacenadas; i++) {
if (telemetriasAlmacenadas[i].equals(unaTelemetria) == true) unaTelemetria = null;
else
throw new Exception("La telemetria que intenta eliminiar no existe.");
}
}
public boolean estaTelemetria (TelemetriaEstado unaTelemetria) throws NullPointerException {
if (unaTelemetria == null) throw new NullPointerException ();
for (int i=0; i< totalTMalmacenadas; i++){
if (telemetriasAlmacenadas[i].equals(unaTelemetria) == true)
return true;
}
return false;
}
public double getMayorDiferenciaTemperatura () throws Exception {
if (totalTMalmacenadas< 2) throw new Exception ("Error. Necesitamos al menos 2 telemetrias almacenadas para calcular la mayor diferencia de temperatura.");
double diff = 0;
for (int i=1; i< totalTMalmacenadas; i++) {
double max = telemetriasAlmacenadas[0].getTemperatura();
double comparacion = telemetriasAlmacenadas[i].getTemperatura();
if (Math.max(comparacion, max) == telemetriasAlmacenadas[i].getTemperatura())
max = telemetriasAlmacenadas[i].getTemperatura();
double min = telemetriasAlmacenadas[0].getTemperatura();
double comparacion2 = telemetriasAlmacenadas[i].getTemperatura();
if (Math.min(comparacion2, min) == telemetriasAlmacenadas[i].getTemperatura())
min = telemetriasAlmacenadas[i].getTemperatura();
diff = Math.abs(max - min);
}
return diff;
}
}
Thankyou very much!
Do one of the other classes you mentioned have a main method? If so, try running one of them. If not, then you could try creating your own main method. A Java application cannot start without a main method.
I've got some problems with the topological sorting. It can find lops, but it counts some of the tasks (or "nodes" if you want to call it) several times. I think the problem is something with how I read or the Edge class, but I just can't see where it goes wrong. Any help would be really appreciated :)
enter code here
import java.util.*;
import java.io.*;
import java.lang.*;
class Task {
int id, time, staff;
int depA, depB;
String name;
int eStart, lStart;
Edge outEdge;
int cntPredecessors;
boolean visited;
Task(int id, String name, int time, int staff) {
this.id = id;
this.name = name;
this.time = time;
this.staff = staff;
visited = false;
}
public String getName() {
return name;
}
public String toString() {
return name;
}
}
class Edge {
Task id, name, time, staff;
Edge neste;
Task fra, til;
Edge(Task id) {
this.id = id;
}
}
class Input {
public static void main(String[] args) {
if (args.length == 0) {
System.out.println("enter a filename!");
System.exit(1);
} else if (args.length == 1) {
String fil = args[0]+".txt";
LesFraFil(fil);
// skrivUt();
topSort();
} else {
System.out.println("too many parameters, try again...");
}
}
static int antTask;
static Task[] ids;
static int tTid;
static void LesFraFil(String fil) {
int i = 0;
int j;
try {
String lest;
Scanner in = new Scanner(new FileReader(fil));
Edge til;
int counter = 0;
antTask = in.nextInt();
ids = new Task[antTask];
System.out.println(antTask);
while (in.hasNextLine()) {
lest = in.nextLine();
// hvis tom linje, så hopper den over
if(lest.trim().length() == 0) continue;
String split[] = lest.split("\\s+");
int id = Integer.parseInt(split[0]);
String act = split[1];
int tid = Integer.parseInt(split[2]);
int staff = Integer.parseInt(split[3]);
int depA = Integer.parseInt(split[4]);
tTid += tid;
ids[i] = new Task(id, act, tid, staff);
j = 4;
/*
* Lesingen av inputen skal avbrytes når den leser 0.
* j er den som holder på hvor langt vi er i split arrayet
* når den møter på 0
*/
while(split[j].compareTo("0") != 0) {
int tmp = Integer.parseInt(split[j])-1;
// System.out.println(tmp+1 + " Aktivitetens navn : " + act); //+ " tiden aktiviteten tar tid: " + tid + " avhengihet: " + split[j]);
j++;
if (ids[tmp] == null) {
ids[tmp] = new Task(id, act, tid, staff);
ids[tmp].visited = true;
}
ids[i].cntPredecessors++;
if(ids[tmp].outEdge == null) {
ids[tmp].outEdge = new Edge(ids[i]);
} else {
til = ids[tmp].outEdge;
while(til.neste != null) {
til = til.neste;
}
til.neste = new Edge(ids[i]);
}
}
counter++;
i++;
}
if (antTask == counter) {
System.out.println("Lesinga gikk som planlagt av fil: " + fil);
System.out.println("Total arbeidstid: " + tTid);// + antTask + " == " + counter );
} else {
System.out.println("Noe gikk galt avslutter!");
System.out.println(antTask + " || " + counter);
System.exit(2);
}
in.close();
} catch (Exception e) {
System.err.println("ERROR!" + e.getMessage());
}
}
static void skrivUt() {
for (Task sort : ids) {
System.out.print(sort.id + " " + sort.name);
Edge til = sort.outEdge;
while (til != null) {
System.out.print(" " + til.id.id);
til = til.neste;
}
System.out.println();
}
}
static void topSort() {
LinkedList<Task> list = new LinkedList<Task>();
ArrayList<Task> array = new ArrayList<Task>();
Task temp;
int count = 0;
int totalTime = 0;
// Legger taskene i lista
for (Task t : ids) {
if(t.cntPredecessors == 0) {
list.add(t);
totalTime += t.time;
// System.out.println(t);
t.visited = true;
}
}
for (Task t : ids) {
if(t.cntPredecessors == 1) {
list.add(t);
totalTime += t.time;
// System.out.println(t);
t.visited = true;
}
}
// går i evig løkke til lista er tom.
while (!list.isEmpty()) {
temp = list.pop(); // fjerner elementet fra lista
array.add(temp); // legger inn i arraylisten
count++;
// System.out.println(temp);
for(Edge til = temp.outEdge; til!=null;til=til.neste) {
til.id.cntPredecessors--;
if(til.id.cntPredecessors==0) {
list.add(til.id);
}
}
}
if(count < antTask) {
System.out.println("A loop has been found. Terminating...");
System.exit(0);
}
System.out.println("Topological sort: " + Arrays.toString(array.toArray()));// den sorterte "arraylisten"
System.out.println("Total time spend: " + totalTime);
}
} // End class Input
Here is an example of an input file
8
1 Build-walls 4 2 5 0
2 Build-roofs 6 4 1 0
3 Put-on-wallpapers 1 2 1 2 0
4 Put-on-tiles 1 3 2 0
5 Build-foundation 4 2 0
6 Make-floor 2 2 5 0
7 Put-carpet-floor 4 2 6 2 0
8 Move-in 4 4 3 7 0
The problem is with this loop (inside topSort()):
for (Task t : ids) {
if(t.cntPredecessors == 1) {
list.add(t);
totalTime += t.time;
// System.out.println(t);
t.visited = true;
}
}
You just need to remove it.
Reason: this loop adds to list nodes that have 1 incoming edge. Later (in the while loop), it is possible that for these nodes the cntPredecessors field will be decreased to 0 which will make them being pushed back onto list, thus counted twice.
In the future, please try to narrow down your code to something that contains less "noise", that is: the smallset (or nearly smallest) code that illustrates the problem. This will ease the understanding on potential answerers (not to mention that it may help you see the problem yourself).