Binary heap output not as expected - java

I have a homework that the teacher test if it's corrects by checking it's output using this website moodle.caseine.org, so to test my code the program execute these lines and compare the output with the expected one, this is the test :
Tas t = new Tas();
Random r = new Random(123);
for(int i =0; i<10000;i++)t.inser(r.nextInt());
for(int i =0;i<10000;i++)System.out.println(t.supprMax());
System.out.println(t);
And my Heap (Tas) class:
package td1;
import java.util.ArrayList;
import java.util.List;
public class Tas {
private List<Integer> t;
public Tas() {
t = new ArrayList<>();
}
public Tas(ArrayList<Integer> tab) {
t = new ArrayList<Integer>(tab);
}
public static int getFilsGauche(int i) {
return 2 * i + 1;
}
public static int getFilsDroit(int i) {
return 2 * i + 2;
}
public static int getParent(int i) {
return (i - 1) / 2;
}
public boolean estVide() {
return t.isEmpty();
}
#Override
public String toString() {
String str = "";
int size = t.size();
if (size > 0) {
str += "[" + t.get(0);
str += toString(0);
str += "]";
}
return str;
}
public boolean testTas() {
int size = t.size();
int check = 0;
if (size > 0) {
for (int i = 0; i < t.size(); i++) {
if (getFilsGauche(i) < size) {
if (t.get(i) < t.get(getFilsGauche(i))) {
check++;
}
}
if (getFilsDroit(i) < size) {
if (t.get(i) < t.get(getFilsDroit(i))) {
check++;
}
}
}
}
return check == 0;
}
public String toString(int i) {
String str = "";
int size = t.size();
if (getFilsGauche(i) < size) {
str += "[";
str += t.get(getFilsGauche(i));
str += toString(getFilsGauche(i));
str += "]";
}
if (getFilsDroit(i) < size) {
str += "[";
str += t.get(getFilsDroit(i));
str += toString(getFilsDroit(i));
str += "]";
}
return str;
}
//insert value and sort
public void inser(int value) {
t.add(value);
int index = t.size() - 1;
if (index > 0) {
inserCheck(index); // O(log n)
}
}
public void inserCheck(int i) {
int temp = 0;
int parent = getParent(i);
if (parent >= 0 && t.get(i) > t.get(parent)) {
temp = t.get(parent);
t.set(parent, t.get(i));
t.set(i, temp);
inserCheck(parent);
}
}
//switch position of last element is list with first (deletes first and return it)
public int supprMax() {
int size = t.size();
int max = 0;
if (size > 0) {
max = t.get(0);
t.set(0, t.get(size - 1));
t.remove(size - 1);
supprMax(0);
}
else {
throw new IllegalStateException();
}
return max;
}
public void supprMax(int i) {
int size = t.size();
int temp = 0;
int index = i;
if (getFilsGauche(i) < size && t.get(getFilsGauche(i)) > t.get(index)) {
index = getFilsGauche(i);
}
if (getFilsDroit(i) < size && t.get(getFilsDroit(i)) > t.get(index)) {
index = getFilsDroit(i);
}
if (index != i) {
temp = t.get(index);
t.set(index, t.get(i));
t.set(i, temp);
supprMax(index);
}
}
public static void tri(int[] tab) {
Tas tas = new Tas();
for (int i = 0; i < tab.length; i++) {
tas.inser(tab[i]);
}
for (int i = 0; i < tab.length; i++) {
tab[i] = tas.supprMax();
}
}
}
The last 3 lines of the test are :
-2145024521
-2147061786
-2145666206
But the last 3 of my code are :
-2145024521
-2145666206
-2147061786
The problem are probably with the inser and supprMax methods.
I hate to get a bad grade just because of 3 lines placement, because it is a program that verify the code, it dosn't care the the solution was close, it's still says it's wrong.

Related

Creating a Word List array that can be modified by adding and removing words

In this problem, I am attempting to begin with an array and add or remove words. My problem so far is adding words. I want to have an array String[] {"",""} and fill this up, and if a word is repeated, do nothing. So, add("computer"), add("again"), and add("computer") would result in {"computer", "again"} and give me count 3. I keep getting {"computer", "computer", "again"} remove("computer") would result in {"again", "again"} and give me count 1. Could on look at this code and help?
public class WordList {
public String[] words;
int count;
public WordList() {
count = 0;
words = new String[] {"",""};
}
public int addWord(String w) {
WordList r = new WordList();
int x = r.findWord(w);
int y = words.length;
if (x>-1) {
return count;
}
else if (x==-1) {
if (count < words.length) {
words[count] = w;
}
else if (count == words.length) {
String[] nwords = new String[words.length * 2];
for (int i = 0; i < words.length; i++) {
nwords[i] = words[i];
}
words = nwords;
words[y] = w;
}
count++;
}
return count;
}
public void removeWord(String s) {
WordList r = new WordList();
int x = r.findWord(s);
if (x == -1) {
return;
}
if (x>-1) {
for (int j=0;j<words.length;j++) {
words[j] = words[j+1];
count--;
}
}
return;
}
public int findWord(String w) {
for (int i =0;i<words.length; i++) {
if (w.equals(words[i])) {
return i;
}
}
return -1;
}
public boolean equals(WordList other) {
if (words.length != other.count) {
return false;
} else {
for (int i = 0; i < words.length; i++) {
if (words[i] != other.words[i]) {
return false;
}
}
}
return true;
}
public String toString() {
String s = "There are " + count + " word" + ((words.length == 1)?"":"s") + " in the word list:\n";
for (String w : words) {
s = s + w + "\n";
}
return s;
}
public static void main(String[] args) {
WordList wl = new WordList();
System.out.println(wl.addWord("computer"));
System.out.println(wl.addWord("abacus"));
System.out.println(wl.addWord("computer"));
wl.removeWord("computer");
}
}
First of all. Please consider Arraylist or Map.
Nevertheless i tried to keep changes to the minimal
public class WordList {
public String[] words;
int count;
public WordList() {
count = 0;
words = new String[] {"",""};
}
public int addWord(String w) {
//WordList r = new WordList();
int x = findWord(w);
int y = words.length;
if (x>-1) {
return count++;
}
else if (x==-1) {
if (count < words.length) {
words[count] = w;
}
else if (count == words.length) {
String[] nwords = new String[words.length * 2];
for (int i = 0; i < words.length; i++) {
nwords[i] = words[i];
}
words = nwords;
words[y] = w;
}
count++;
}
return count;
}
public void removeWord(String s) {
//WordList r = new WordList();
int x = findWord(s);
if (x == -1) {
return;
}
if (x>-1) {
for (int j=0;j<words.length;j++) {
if(words.length < j+1 && !words[j+1].isBlank()){
words[j] = words[j+1];
}
}
count--;
}
return;
}
public int findWord(String w) {
for (int i =0;i<words.length; i++) {
if (w.equals(words[i])) {
return i;
}
}
return -1;
}
public boolean equals(WordList other) {
if (words.length != other.count) {
return false;
} else {
for (int i = 0; i < words.length; i++) {
if (words[i] != other.words[i]) {
return false;
}
}
}
return true;
}
public String toString() {
String s = "There are " + count + " word" + ((words.length == 1)?"":"s") + " in the word list:\n";
for (String w : words) {
s = s + w + "\n";
}
return s;
}
public static void main(String[] args) {
WordList wl = new WordList();
System.out.println(wl.addWord("computer"));
System.out.println(wl);
System.out.println(wl.addWord("abacus"));
System.out.println(wl);
System.out.println(wl.addWord("computer"));
System.out.println(wl);
wl.removeWord("computer");
System.out.println(wl);
}
}
The severe ones are:
1. You are working on new instances of wordlist (r) when adding and removing which is absolutely wrong.
2. When removing word you have to check the length of word before going for j+1
You should use a Set, not an array.
That will reduce your code to:
class WordList {
private Set<String> words;
public WordList() {
words = new HashSet<>();
}
public int addWord(String w) {
words.add(w);
return words.size();
}
public void removeWord(String s) {
words.remove(s);
}
public boolean findWord(String w) {
return words.contains(w);
}
public boolean equals(WordList other) {
return this.words.equals(other.words);
}
#Override
public String toString() {
String s = "There are " + words.size() + " word" + ((words.size() == 1)?"":"s") + " in the word list:\n";
for (String w : words) {
s = s + w + "\n";
}
return s;
}
public static void main(String[] args) {
WordList wl = new WordList();
System.out.println(wl.addWord("computer"));
System.out.println(wl.addWord("abacus"));
System.out.println(wl.addWord("computer"));
wl.removeWord("computer");
}
}
Output
1
2
2

Minheapify method

Problem desc:
i seem to have a problem with my MIN-heap structure. I get the nullpointer in the min-heapify method in the first if-statement. The test class doesnt matter in this case
Can anyone spot the error? Here is the code for the minHeap (Line 31 is the first IF statement in the minHeapify method):
public class PQHeap implements PQ {
private PriorityQueue pq;
private Element[] heapArray;
private int heapSize;
public PQHeap(int maxElms) {
pq = new PriorityQueue(maxElms);
heapArray = new Element[maxElms];
heapSize = 0;
}
public void minHeapify(int index) {
int left = getLeft(index);
int right = getRight(index);
int smallest = index;
if (left < heapSize && heapArray[left].getKey() < heapArray[index].getKey()) {
smallest = left;
}
if (right < heapSize && heapArray[right].getKey() < heapArray[smallest].getKey()) {
smallest = right;
}
if (smallest != index) {
exchangeKey(heapArray[index].getKey(), heapArray[smallest].getKey());
minHeapify(smallest);
}
}
public int getLeft(int index) {
return index * 2;
}
public int getRight(int index) {
return index * 2 + 1;
}
public int getParent(int index) {
return index / 2;
}
public void exchangeKey(int a, int b) {
int temp = a;
a = b;
b = temp;
}
#Override
public Element extractMin() {
Element min = heapArray[0];
heapArray[0] = heapArray[heapArray.length - 1];
minHeapify(0);
return min;
}
#Override
public void insert(Element e) {
heapSize++;
int i = heapSize;
heapArray[i] = e;
while (i > 1 && heapArray[getParent(i)].getKey() > heapArray[i].getKey()) {
exchangeKey(heapArray[i].getKey(), getParent(heapArray[i].getKey()));
i = getParent(i);
}
}
//SKAL FJERNES
public void print() {
for (int i = 1; i <= heapSize / 2; i++) {
System.out.print(" PARENT : " + heapArray[i].getKey()
+ " LEFT CHILD : " + heapArray[2 * i].getKey()
+ " RIGHT CHILD :" + heapArray[2 * i + 1].getKey());
System.out.println();
}
}
//SKAL FJERNES
public void minHeap() {
for (int pos = (heapSize / 2); pos >= 1; pos--) {
minHeapify(pos);
}
}
}

PALIN- The next Palindrome - a SPOJ problem

I have opened an account for Ridit, one of 7-years-old students learning Java at SPOJ. The first task i gave to him was PALIN -The Next Palindrome. Here is the link to this problem- PALIN- The next Palindrome- SPOJAfter i explained it to him, he was able to solve it mostly except removing the leading zeros, which i did. Following is his solution of the problem -
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
Scanner in = new Scanner(System.in);
int t = Integer.parseInt(in.nextLine());
String[] numbersInString = new String[t];
for (int i = 0; i <t; i++) {
String str = in.nextLine();
numbersInString[i] = removeLeadingZeros(str);
}
for (int i = 0 ; i<t; i++) {
int K = Integer.parseInt(numbersInString[i]);
int answer = findTheNextPalindrome(K);
System.out.println(answer);
}
}catch(Exception e) {
return;
}
}
static boolean isPalindrome(int x) {
String str = Integer.toString(x);
int length = str.length();
StringBuffer strBuff = new StringBuffer();
for(int i = length - 1;i>=0;i--) {
char ch = str.charAt(i);
strBuff.append(ch);
}
String str1 = strBuff.toString();
if(str.equals(str1)) {
return true;
}
return false;
}
static int findTheNextPalindrome(int K) {
for(int i = K+1;i<9999999; i++) {
if(isPalindrome(i) == true) {
return i;
}
}
return -1;
}
static String removeLeadingZeros(String str) {
String retString = str;
if(str.charAt(0) != '0') {
return retString;
}
return removeLeadingZeros(str.substring(1));
}
}
It is giving correct answer in Eclipse on his computer, but it is failing in SPOJ. If someone helps this little boy in his first submission, it will definitely make him very happy. I couldn't find any problem with this solution... Thank you in advance...
This might be helpful
import java.io.IOException;
import java.util.Scanner;
public class ThenNextPallindrom2 {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
int t = 0;
Scanner sc = new Scanner(System.in);
if(sc.hasNextInt()) {
t = sc.nextInt();
}
sc.nextLine();
int[] arr, arr2;
while(t > 0) {
t--;
String s = sc.nextLine();
arr = getStringToNumArray(s);
if(all9(arr)) {
arr2 = new int[arr.length + 1];
arr2[0] = 1;
for(int i=0;i<arr.length;i++) {
arr2[i+1] = 0;
}
arr2[arr2.length -1] = 1;
arr = arr2;
} else{
int mid = arr.length/ 2;
int left = mid-1;
int right = arr.length % 2 == 1 ? mid + 1 : mid;
boolean left_small = false;
while(left >= 0 && arr[left] == arr[right]) {
left--;
right++;
}
if(left < 0 || arr[left] < arr[right]) left_small = true;
if(!left_small) {
while(left >= 0) {
arr[right++] = arr[left--];
}
} else {
mid = arr.length/ 2;
left = mid-1;
int carry = 1;
if(arr.length % 2 == 0) {
right = mid;
} else {
arr[mid] += carry;
carry = arr[mid]/10;
arr[mid] %= 10;
right = mid + 1;
}
while(left >= 0) {
arr[left] += carry;
carry = arr[left] / 10;
arr[left] %= 10;
arr[right++] = arr[left--];
}
}
}
printArray(arr);
}
}
public static boolean all9(int[] arr) {
for(int i=0;i<arr.length;i++) {
if(arr[i] != 9)return false;
}
return true;
}
public static void printArray(int[] arr) {
for(int i=0;i<arr.length;i++) {
System.out.print(arr[i]);
}
System.out.println();
}
public static int[] getStringToNumArray(String s) {
int[] arr = new int[s.length()];
for(int i=0; i<s.length();i++) {
arr[i] = Integer.parseInt(String.valueOf(s.charAt(i)));
}
return arr;
}
}

To shrink a string "abbcccbfgh" by removing conescutive k characters till no removal can be done

To shrink a string "abbcccbfgh" by removing consecutive k characters till no removal can be done.
e.g. for k=3 output for the above string will be "afgh".
Please note that K and string both are dynamic i.e provided by the user.
I wrote the below program but I couldn't complete it. Please help.
public class Test {
public static void main(String[] args) {
String str = "abbcccbfgh";
int k = 3;
String result = removeConsecutive(str, k);
System.out.print("result is " + result);
}
private static String removeConsecutive(String str, int k) {
String str1 = str + "";
String res = "";
int len = str.length();
char c1 = 0, c2 = 0;
int count = 0;
for (int i = 0; i < len - 1; i++) {
c1 = str.charAt(i);
c2 = str.charAt(i + 1);
if (c1 == c2) {
count++;
} else {
res = res + String.valueOf(c1);
count = 0;
}
if (count == k-1) {
//remove String
}
}
return res;
}
I suggest to do it with regex:
int l = 0;
do {
l = str.length();
str = str.replaceAll("(.)\\1{" + n + "}", "");
} while (l != str.length());
n = k - 1
(.)\1{2} means any character followed by n same characters. \1 means the same character as in group #1
Is it okey to have recursion ?
public class Test {
public static void main(String[] args) {
String str = "abbcccbfgh";
int k = 3;
String result = removeConsecutive(str, k);
System.out.print("result is " + result);
}
private static String removeConsecutive(String str, int k) {
String ret = str;
int len = str.length();
int count = 0;
char c1 = 0 ;
char c2 = 0;
char last = 0 ;
for (int i = 0; i < ret.length()-1; i++) {
last = c1 ;
c1 = str.charAt(i);
c2 = str.charAt(i + 1);
if (c1 == c2 ) {
if( count > 0 ) {
if( last == c1 ) {
count ++ ;
}
else {
count = 0;
}
}
else {
count++;
}
} else {
count = 0;
}
if (count == k-1) {
int start = ((i+1) - k) + 1 ;
String one = str.substring(0, start) ;
String two = str.substring(start+k);
String new1 = one + two ;
//recursion
ret = removeConsecutive(new1, k) ;
count = 0;
}
}
return ret;
}
}
You can do it with a stack. For each character ch in the string, push it to the stack, if there's 3 consecutive same characters, pop them all. In the end, convert the stack to a string. You can improve the program a little by using a special stack that remembers the number of occurrences of each element.
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
public class Reduce implements Function<String, String> {
private final int k;
public Reduce(final int k) {
if (k <= 0) {
throw new IllegalArgumentException();
}
this.k = k;
}
#Override
public String apply(final String s) {
Stack<Character> stack = new Stack<>();
for (Character ch : s.toCharArray()) {
stack.push(ch);
if (stack.topCount() == k) {
stack.pop();
}
}
return stack.toString();
}
public static void main(String[] args) {
Reduce reduce = new Reduce(3);
System.out.println(reduce.apply("abbcccbfgh"));
}
private static class Stack<T> {
private class Node {
private T value;
private int count;
Node(T value) {
this.value = value;
this.count = 1;
}
}
private List<Node> nodes = new ArrayList<>();
public void push(T value) {
if (nodes.isEmpty() || !top().value.equals(value)) {
nodes.add(new Node(value));
} else {
top().count++;
}
}
public int topCount() {
return top().count;
}
public void pop() {
nodes.remove(nodes.size()-1);
}
private Node top() {
return nodes.get(nodes.size()-1);
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
nodes.forEach(n->{
for (int i = 0; i < n.count; i++) {
sb.append(n.value);
}
});
return sb.toString();
}
}
}

Time Complexity of the below Solution? Its already been asked, but i still didnt understand the exponential part! Kindly explain

The following code prints all strings of length k where the characters are in sorted order. It does this by generating all strings of length k and then checking if each is sorted. What is its runtime?
public static int numChars = 26;
public static void printSortedStrings(int remaining) {
printSortedStrings(remaining, "");
}
public static void printSortedStrings(int remaining, String prefix) {
if (remaining == 0) {
if (isInOrder(prefix)) {
System.out.println(prefix); // Printing the string
}
} else {
for (int i = 0; i < numChars; i++) {
char c = ithLetter(i);
printSortedStrings(remaining - 1, prefix + c);
}
}
}
public static boolean isInOrder(String s) {
for (int i = 1; i < s.length(); i++) {
int prev = ithLetter(s.charAt(i - 1));
int curr = ithLetter(s.charAt(i));
if (prev > curr) {
return false;
}
}
return true;
}
public static char ithLetter(int i) {
return (char) (((int) 'a') + i);
}
public static void main(String[] args) {
printSortedStrings(2);
}

Categories

Resources