Removing from Red & Black Tree issue - java

i think that the problem is root being null. WOuld someone one teach me how to do it the proper way ? Because i don't know why it is null ... I think the remove function is well implemented, but due to root being null it doesn't continue executing. Help please.
Any recommendation are welcome too :D
public static void main(String[] args) {
Tree t = new Tree("");
String msg;
String[] inputs;
Scanner sc = new Scanner(System.in);
ArrayList <String> palavras = new ArrayList <String>();
int i = 0;
while (true) {
msg = sc.nextLine();
if (msg.equals("")) {
break;
}
inputs = msg.split(" ");
i = 0;
while (i < inputs.length) {
palavras.add(inputs[i]);
i++;
}
}
i = 0;
while (i < palavras.size()) {
if (palavras.get(i).equals("REMOVE")) {
t.remove(palavras.get(i+1));
palavras.remove(i+1);
i+=1;
} else {
t.insert(palavras.get(i).toLowerCase());
i++;
}
}
t.postorder();
t.preorder();
t.inorder();
}
**********************************************************
public void remove( String word)
{
Node father=root;
Node actual=root;
boolean leftnode=true;
if(root!=null){
while(!word.equals(actual.str))
{
father=actual;
if(word.compareTo(actual.str)<0)
{
leftnode=true;
actual=actual.left;
}
else{
leftnode=false;
actual=actual.right;
}
if(actual==null){
return ;
}
}
actual.occ = 0;
}
}

I was implementing Splay tree which works on the same concept as red black tree and at a point I was stuck like this. I will suggest you to draw the flow diagram of your code and then code it again. I hope your problem will be solved as mine.
you can refer this and this articles.

Related

Merge strings of ints

I am stuck ... can anyone tell me how can i do this:
Here is the required input and output:
input: [4, 2, +, 8, +, 2, 5, multiply sign, 2]
output: [42,+,8,+,25,multiply sign,2]
This was my last try and it output nothing :
public static List<String> unifyNumbers(List<String> data) {
List<String> temp = new ArrayList<String>();
for (int i = 0; i < data.size(); i++) {
String num = "";
try {
num += Integer.parseInt(data.get(i));
for (int i2 = i; i < data.size(); i++) {
try {
num += Integer.parseInt(data.get(i2));
} catch (NumberFormatException e) {
e.printStackTrace();
i = i2 - 1;
temp.add(num);
num = "";
}
}
} catch (NumberFormatException e) {
e.printStackTrace();
temp.add(data.get(i));
}
}
return temp;
}
The i2 variable doesn't iterate, which is why you are not getting any output. That loop isn't necessary anyway. Putting the test to see if a string is a number in its own function simplifies things a little.
Here is a revised solution, and a link to a place you can test it.
http://tpcg.io/l2xbRASM
public static Boolean isNumeric(String value) {
try {
Integer.parseInt(value);
return true;
} catch(NumberFormatException e) {
return false;
}
}
public static List<String> unifyNumbers(List<String> data) {
List<String> temp = new ArrayList<String>();
String num = "";
for (int i = 0; i < data.size(); i++) {
// HelloWorld is the name of the class I am testing this in.
if(HelloWorld.isNumeric(data.get(i))) {
num += Integer.parseInt(data.get(i));
} else {
temp.add(num);
// this line adds the arithmetic operator to the resulting output
temp.add(data.get(i));
num = "";
}
}
// add number that remains to the array
if(num != "")
temp.add(num);
return temp;
}
I hope this adds to the answers other people have given.
import java.util.*;
import java.lang.*;
import java.io.*;
class Sample
{
public static void main (String[] args) throws java.lang.Exception
{
List<String> sampleData = new ArrayList<String>();
sampleData.add("1");
sampleData.add("2");
sampleData.add("*");
sampleData.add("8");
sampleData.add("+");
sampleData.add("2");
sampleData.add("5");
List<String> resultList = unifyNumbers(sampleData);
System.out.println(resultList);
}
public static List<String> unifyNumbers(List<String> data) {
String concatedNum = "";
List<String> resultList = new ArrayList<String>();
for(String arrVal: data) {
if(isInteger(arrVal)) {
concatedNum += arrVal;
} else {
resultList.add(concatedNum);
resultList.add(arrVal);
concatedNum = "";
}
}
if(!concatedNum.isEmpty()) {
resultList.add(concatedNum);
}
return resultList;
}
public static boolean isInteger( String input ) {
try {
Integer.parseInt( input );
return true;
}
catch( Exception e ) {
return false;
}
}
}
It seems like Gowtham Nagarajan already gave you a better way to do it. I'd advise you to use a modified version of his code, one that checks whether your String is an Integer without a try/catch block (see this question for a discussion on why your current approach isn't really good practice).
I'll still show you what I did, just to help you understand what went wrong with your first approch and how to fix something like that.
I changed your code to make it work like you want it to. All my check prints that I used to find problems are still in there, to give you an idea how to find problems in the execution. Checks like these make it easier to follow the "flow" of your program and to find out what went wrong. You can take a piece of paper and write down every step your program goes through, the checks will show you if everything works like you want it to or if there's unwanted behavior.
public static List<String> unifyNumbers(List<String> data) {
List<String> temp = new ArrayList<String>();
for (int i = 0; i < data.size(); i++) {
String num = "";
try {
num = "" + Integer.parseInt(data.get(i));
System.out.println("Check 1");
for (int i2 = i + 1; i2 < data.size(); i2++) {
try {
num += Integer.parseInt(data.get(i2));
System.out.println("Check 2");
} catch (NumberFormatException e) {
System.out.println("Error inside loop");
e.printStackTrace();
i = i2 - 1;
System.out.println("To add:" + num);
temp.add(num);
num = "";
break;
}
}
} catch (NumberFormatException e) {
System.out.println("Error outside loop");
e.printStackTrace();
temp.add(data.get(i));
}
if (!num.equals("")) {
System.out.println(num);
temp.add(num);
}
}
return temp;
}
When using the print statements, I found out that your original code never left the first inside loop. The print statement at the end System.out.println(num); printed something like 44444444. Hints like this one can help you make the code work.
There were a lot of small mistakes that were reasonably easy to find this way. I suggest you try that next time. Good Luck!

Java- function seems to mess up the console, nothing will be printed out after calling the function

I was asked to program a method that receives a scanner, and returns a sorted array of words which contain only letters, with no repetitions (and no bigger in length than 3000). Then, I was asked to program a method that checks whether a certain given string is contained in a given vocabulary. I used a simple binary search method.
This is what I've done:
public static String[] scanVocabulary(Scanner scanner){
String[] array= new String[3000];
int i=0;
String word;
while (scanner.hasNext() && i<3000) {
word=scanner.next();
if (word.matches("[a-zA-Z]+")){
array[i]=word.toLowerCase();
i++;
}
}int size=0;
while (size<3000 && array[size]!=null ) {
size++;
}
String[] words=Arrays.copyOf(array, size);
if (words.length==0 || words.length==1) {
return words;
}
else {
Arrays.sort(words);
int end= removeDuplicatesSortedArr(words);
return Arrays.copyOf(words, end);
}
}
private static int removeDuplicatesSortedArr(String[] array) { //must be a sorted array. returns size of the new array
int n= array.length;
int j=0;
for (int i=0; i<n-1; i++) {
if (!array[i].equals(array[i+1])) {
array[j++]=array[i];
}
}
array[j++]=array[n-1];
return j;
}
public static boolean isInVocabulary(String[] vocabulary, String word){
//binary search
int n=vocabulary.length;
int left= 0;
int right=n-1;
while (left<=right) {
int mid=(left+right)/2;
if (vocabulary[mid].equals(word)){
return true;
}
else if (vocabulary[mid].compareTo(word)>0) {
right=mid-1;
}else {
right=mid+1;
}
}
return false;
}
while trying the following code:
public static void main(String[] args) {
String vocabularyText = "I look at the floor and I see it needs sweeping while my guitar gently weeps";
Scanner vocabularyScanner = new Scanner(vocabularyText);
String[] vocabulary = scanVocabulary(vocabularyScanner);
System.out.println(Arrays.toString(vocabulary));
boolean t=isInVocabulary(vocabulary, "while");
System.out.println(t);
System.out.println("123");
}
I get nothing but-
[and, at, floor, gently, guitar, i, it, look, my, needs, see, sweeping, the, weeps, while]
nothing else is printed out nor returned. Both functions seem to be working fine separately, so I don't get what I'm doing wrong.
I would be very happy to hear your thoughts, thanks in advance :)
This has nothing to do with the console. Your isInVocabulary method is entering an infinite loop in this block:
if (!isInVocabulary(vocabulary, "while")) {
System.out.println("Error");
}
If you were to debug through isInVocabulary, you would see that after a few iterations of the while loop,
left = 0;
right = 2;
mid = 1;
if (vocabulary[mid].equals(word)){
// it doesn't
} else if (vocabulary[mid].compareTo("while") > 0) {
// it doesn't
} else {
right = mid + 1;
// this is the same as saying right = 1 + 1, i.e. 2
}
So you'll loop forever.

Resource leak 'blank' never closed

It seems that when I create my scanner I get this error. I have tried to solve this by searching the error name, but have so far been unsuccessful in getting the message to stop appearing.
Code:
import java.util.Scanner;
public class PrintQueue {
//Instance variables
private Queue<Job> pq;
//Constructor
public PrintQueue() {
pq = new Queue<Job>();
}
//Adds a job object to the end of the queue
public void lpr(String owner, int jobId) {
Job j = new Job(owner, jobId);
pq.enqueue(j);
}
//Enumerates the queue
public void lpq() {
Job curr = pq.first();
for (int i = 0; i < pq.size(); i++) {
System.out.println(curr);
curr = pq.next();
}
}
//Removes the first entry in the queue if the input integer matches the integer contained within the job object
public void lprm(int jobId) {
if (pq.first().getJobId() == (jobId))
pq.dequeue();
else
System.out.println("Unable to find jobId.");
}
//Removes all objects that contain the input String
public void lprmAll(String owner) {
Job curr = pq.first();
for (int i = 0; i < pq.size(); i++) {
if (curr.getOwner().equals(owner))
pq.dequeue();
curr = pq.next();
}
}
//Demo
public static void main(String[] args) {
Scanner k = new Scanner(System.in);
PrintQueue myPQ = new PrintQueue();
String name;
int id;
for (int i = 1; i <= 5; i++) {
System.out.print("Enter owner and id: ");
name = k.next();
id = k.nextInt();
myPQ.lpr(name, id);
}
System.out.println("Print Queue");
myPQ.lpq();
myPQ.lprm(101);
myPQ.lprmAll("ronaldinho");
System.out.println("Print Queue");
System.out.println("\n\n");
myPQ.lpq();
}
}
Part where I get the error:
Scanner k = new Scanner(System.in);
That's because you're never closing the Scanner. Change your code to:
Scanner k = null;
try {
k = new Scanner(System.in);
//do stuff with k here...
} finally {
if( k != null )
k.close();
}
It seems that it is rather warning than error. However it is good practice to solve it.
Actually you just have to call k.close(); in the end of your method.
The best practice is to call close in finally block: this guarantees that the resource is closed whenever exception is thrown or not;
Scanner k = null;
try {
k = new Scanner(System.in);
........
} finally {
if (k != null) {
k.close();
}
}
Fortunately java 7 provides makes this syntax less verbose:
try (
Scanner k = new Scanner(System.in);
) {
.... // use k
}
When object of any class that implements Closable is created in special section of try block that marked with regular brackets () you do not have to write finally block: it is added by compiler.

ClassCast Exception

I've written a method that has some casting errors:
public class Factor {
public static int[] findFactors(ArrayList<Integer> nums){
ArrayList<Integer> factors= new ArrayList();
for(Integer i=new Integer(0);i<nums.size();i++) {
System.out.println(nums.get(i));
for(int j=0;j<nums.get(i);j++) {
if (nums.get(i) %j==0) {
factors.add(j);
}
}
}
int ct=0;
String factorString= factors.toString();
char[] charArray= factorString.toCharArray();
int[] factorArray= new int[(charArray.length+1)/2];
for(int a=0;a<charArray.length;a++) {
if(charArray[a]==',') {
continue;
} else {
String s= Character.toString(charArray[a]);
factorArray[ct]=Integer.parseInt(s);
ct++;
}
}
return factorArray;
}
}
any help would be appreciated
The problem you have that you only escape the , but when you use toString() on a List it is enclose in square brackets []. When you fix that you will discover that size of result array is not valid also you have to subtract 2 (the brackets).
Good Luck with rest. And please read some basic manual about Java.

For loop input in BlueJ (infinite loop)

I'm working on a project for school and am stumped at where I am at the moment. When I run my project, the VM seems to be stuck in a loop and will not load (A console should pop up allowing me to input characters for the CombinationLock class setDigit() method). I believe it has something to do with my for loop in my Interface.java class. If anyone could take a look and lead me in the right direction, that'd be much appreciated. Thanks a bunch!
Interface.java
import java.util.*;
public class Interface
{
public static void main() {
Scanner in = new Scanner(System.in);
CombinationLock combo = new CombinationLock();
for(int i = 0; i < 3; i++) {
String ltr = in.nextLine();
combo.setDigit(ltr.charAt(0), i);
System.out.println("Digit " + i + " has been set to " + ltr);
}
}
}
CombinationLock.java
public class CombinationLock
{
String[] combo = new String[3];
public CombinationLock() { }
public boolean setDigit(char letter, int index) {
if (Character.isDigit(letter)) {
return false;
}
combo[index] = String.valueOf(letter);
return true;
}
public boolean unlock(String combo) {
if (combo.length() > 3) {
return false; //Longer then it can be, not valid
}
char[] comboArray = combo.toCharArray();
for (char c : comboArray) {
if (Character.isDigit(c)) {
return false; //Contains numbers, not valid
}
}
boolean valid = true;
for (int i = 0; i < 3; i++) {
if (combo.charAt(i) != comboArray[i] && valid == true) {
valid = false;
break;
}
}
return valid;
}
}
You have initialized combo array in CombinationLock class with length 0 as String[] combo = {};. This is cause ArrayIndexOutOfBoundsException when you are calling combo.setDigit(ltr.charAt(0), i);. Please correct the initialization. I beleive you want to capture 3 inputs, in that case, please initialize combo in CombinationLock with length 3 as below:
String[] combo = new String[3];
Your problem is (the signature of the main method is wrong)
public static void main() {
it should be
public static void main(String[] args) {
I've found where my error was, using the BlueJ IDE one must output something to the console before it shows up and allows you to input data, therefore it never popped up as I never used System.out.println or System.out.print. After doing so, the console popped up and allowed me to input my data. Thanks you for all your suggestions and help!

Categories