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.
Related
I am a somewhat intermediate-level Java programmer but I have had trouble with one of my recent programs. Basically the application is a Hangman game that allows the user to input letters in order to guess a word. Everything works okay except for the counter for how many lives the player has, in this case it is 5. The counter for some reason subtracts by 4 instead of 1, as well as this it takes away from the number of lives even if the letter is guessed correctly.
Any help would be widely appreciated, thank you in advance. The two classes are provided below. Also,
Instantiable Class
public class Hangman {
private char letterGuess;
private int numberLives;
private String outputWord;
private final String hiddenWord;
private final StringBuffer swapBuffer = new StringBuffer();
public Hangman() {
letterGuess = ' ';
numberLives = 5;
hiddenWord = "java";
outputWord = "";
for (int i = 0; i < hiddenWord.length(); i++) {
swapBuffer.append("*");
}
}
public void setLetterGuess(char letterGuess) {
this.letterGuess = letterGuess;
}
public void compute() {
for (int i = 0; i < hiddenWord.length(); i++) {
if (letterGuess == hiddenWord.charAt(i)) {
swapBuffer.setCharAt(i, letterGuess);
}
else {
numberLives--;
}
}
outputWord = swapBuffer.toString();
}
public int getNumberLives() {
return numberLives;
}
public String getHiddenWord() {
return hiddenWord;
}
public String getOutputWord() {
return outputWord;
}
}
Main Class
import javax.swing.*;
public class HangmanApp {
public static void main(String[] args) {
char letterGuess;
int numberLives;
String hiddenWord, outputWord, restartGame;
do {
Hangman myHangman = new Hangman();
JOptionPane.showMessageDialog(null, "Welcome to Java Hangman!");
JOptionPane.showMessageDialog(null, "In this game, a word will be printed to you in asterisks - each letter will be revealed upon a correct guess!");
JOptionPane.showMessageDialog(null, "You have 5 lives for the game, the game will end if you make too many incorrect guesses!");
for (int i = 0; i < 10; i++) {
hiddenWord = myHangman.getHiddenWord();
numberLives = myHangman.getNumberLives();
JOptionPane.showMessageDialog(null, "You currently have " +numberLives+ " lives!");
letterGuess = JOptionPane.showInputDialog(null, "Now, please enter a letter : ").charAt(0);
myHangman.setLetterGuess(letterGuess);
myHangman.compute();
outputWord = myHangman.getOutputWord();
JOptionPane.showMessageDialog(null, "The word so far is : " +outputWord);
}
numberLives = myHangman.getNumberLives();
JOptionPane.showMessageDialog(null, "You have finished the game with : " +numberLives+ " lives!");
restartGame = JOptionPane.showInputDialog(null, "Would you like to play again?");
}
while (restartGame.equalsIgnoreCase("Yes"));
}
}
Use a found boolean to check if the letter was found. If it wasn't, subtract a life.
var found = false;
for (int i = 0; i < hiddenWord.length(); i++) {
if (letterGuess == hiddenWord.charAt(i)) {
swapBuffer.setCharAt(i, letterGuess);
found = true;
}
}
if (!found) numberLives--;
If the guessed letter is wrong, in the compute function 1 life will be taken for each letter of the hidden word. You should try and use a switch(boolean) that will show you if the letter was found or not after parsing the whole word.
public void compute() {
// for (int i = 0; i < hiddenWord.length(); i++) {
// if (letterGuess == hiddenWord.charAt(i)) {
// swapBuffer.setCharAt(i, letterGuess);
// }
//
// else {
// numberLives--;
// }
// }
int letterNo = hiddenWord.length();
boolean found = false;
while (letterNo>0){
letterNo--;
if (letterGuess == hiddenWord.charAt(letterNo)){
swapBuffer.setCharAt(letterNo, letterGuess);
found = true;
}
}
if (!found){
numberLives--;
}
outputWord = swapBuffer.toString();
}
Here's the question -
https://www.codechef.com/DEC17/problems/CPLAY
And here's my solution -
import java.util.Scanner;
class Penalty_Shoot_Out
{
public static void main(String args[])
{
Scanner sc = new Scanner(System.in);
//System.out.println("T: ");
int T = sc.nextInt();
sc.nextLine();
while(T-->0)
{
String s = sc.nextLine();
int l = s.length();
s = " " + s;
int A_score = 0, B_score = 0, A_shots = 0, B_shots = 0, flag = 0, A_shots_left = 5, B_shots_left = 5, shots_left = 0;
Outer:for(int i=1; i<=20; i++)
{
char c = s.charAt(i);
if(i%2==1)
{
flag = 0;
A_shots++;
A_shots_left--;
if(c=='1')
A_score++;
}
else
{
flag = 1;
B_shots++;
B_shots_left--;
if(c=='1')
B_score++;
}
if(i<=10)
{
if(A_score<B_score)
{
if(B_score-A_score>A_shots_left)
{
System.out.println("TEAM-B " + i);
break Outer;
}
}
else
{
if(A_score-B_score>B_shots_left)
{
System.out.println("TEAM-A " + i);
break Outer;
}
}
}
else if(i>10 && i<=20)
{
if(i%2==0)
{
if(A_score>B_score)
System.out.println("TEAM-A " + i);
else if(B_score>A_score)
System.out.println("TEAM-B " + i);
else
System.out.println("TIE");
break Outer;
}
}
}
}
}
}
These are the exceptions -
Exception
in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:862)
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextInt(Scanner.java:2117)
at java.util.Scanner.nextInt(Scanner.java:2076)
at Penalty_Shoot_Out.main(Main.java:8)
I'm getting the correct answer on my computer, but when I submit it online, I get the NZEC Runtime Error.
I tried Googling for solutions and most people said the error might have to do with the main function returning a wrong number or not returning a number. Some said it may be due to the use of a particular function or due to an exception that i am not handling during I/O. However, I haven't been able to figure it out.
I'd really appreciate it if someone could fix my code.
You should put your solution in a try catch.
public static void main(String args[])
{
try {
Scanner sc = new Scanner(System.in);
//System.out.println("T: ");
int T = sc.nextInt();
sc.nextLine();
while(T-->0)
{
String s = sc.nextLine();
int l = s.length();
s = " " + s;
int A_score = 0, B_score = 0, A_shots = 0, B_shots = 0, flag = 0,
A_shots_left = 5, B_shots_left = 5, shots_left = 0;
Outer:for(int i=1; i<=20; i++)
{
char c = s.charAt(i);
if(i%2==1)
{
flag = 0;
A_shots++;
A_shots_left--;
if(c=='1')
A_score++;
}
else
{
flag = 1;
B_shots++;
B_shots_left--;
if(c=='1')
B_score++;
}
if(i<=10)
{
if(A_score<B_score)
{
if(B_score-A_score>A_shots_left)
{
System.out.println("TEAM-B " + i);
break Outer;
}
}
else
{
if(A_score-B_score>B_shots_left)
{
System.out.println("TEAM-A " + i);
break Outer;
}
}
}
else if(i>10 && i<=20)
{
if(i%2==0)
{
if(A_score>B_score)
System.out.println("TEAM-A " + i);
else if(B_score>A_score)
System.out.println("TEAM-B " + i);
else
System.out.println("TIE");
break Outer;
}
}
}
}
} catch(Exception e) {
return;
}
}
}
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.
I have a problem to increase frequency that the word occurs in each file,
I tested into 3 equal files and obtained different results in each.
Example: Each file the word "program" occurs 13 times
but the output I have is:
*the word in the search field as this "programa" and not program because of stemming function
[program]
----------------
Doc: site1.html Freq: 21
Doc: site2.html Freq: 11
Doc: site3.html Freq: 1
none of the outputs are correct.
The output had to be:
[program]
----------------
Doc: site1.html Freq: 13
Doc: site2.html Freq: 13
Doc: site3.html Freq: 13
Document class:
public class Documento {
private String docid;
private int frequencia;
public Documento(String docid, int frequencia) {
this.docid = docid;
this.frequencia = frequencia;
}
public String getDocid() {
return docid;
}
public int getFrequencia() {
return frequencia;
}
public void setFrequencia(int frequencia) {
this.frequencia = frequencia;
}
#Override
public boolean equals(Object o) {
if ((o instanceof Documento) && docid == ((Documento) o).docid && frequencia == ((Documento) o).frequencia) {
return true;
}
return false;
}
Function to insert and find document:
public class Dicionario {
public Map<String, List<Documento>> indice = new HashMap<>();
public void InsereDicionario(String palavra, String docid) {
if (!indice.containsKey(palavra)) {
indice.put(palavra, new ArrayList<Documento>());
indice.get(palavra).add(new Documento(docid, 1));
} else {
boolean inserido = false;
List<Documento> lista = indice.get(palavra);
for (int i = 0; i < lista.size(); i++) {
Documento d = lista.get(i);
if (d.getDocid().equals(docid)) {
// indice.get(palavra).add(new Documento(docid, 1));
inserido = true;
} else {
d.setFrequencia(d.getFrequencia() + 1);
}
System.out.println("");
}
if (!inserido) {
indice.get(palavra).add(new Documento(docid, 1));
}
}
}
public String Busca(String palavra) {
String saida = "";
System.out.println("Buscando [" + palavra + "]");
List<Documento> list = new ArrayList();
for (String p : indice.keySet()) {
if (p.equals(palavra)) {
list.addAll(indice.get(p));
for (Documento d : indice.get(p)) {
System.out.println("Doc: " + d.getDocid() + " Freq: " + d.getFrequencia());
saida += "Doc: " + d.getDocid() + " Freq: " + d.getFrequencia() + "".trim() + "\n";
}
}
}
return saida;
}
Function to call Buscar(Search function) in all words.
for (String palavra : query.split(" ")) {
resultado += ("\n[" + palavra + "]\n----------------\n");
resultado += dic.Busca(palavra.trim());
}
Look at this:
if (d.getDocid().equals(docid)) {
// indice.get(palavra).add(new Documento(docid, 1));
inserido = true;
} else {
d.setFrequencia(d.getFrequencia() + 1);
}
If dociid is found in the list -> then do nothning.
Otherwise (a current doc retrieved from the list is not equal to docid) -> then increment the counter.
Swap these operations, or use a negation in the condition.
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).