I have generated a minheap to this file but I think something I have missed but I can't identify what are the things I have missed. I have missed something on --private void bubbleDown() { }-- section but I can't find what are the things missed by me.
private int default_size = 100; // how big the heap should be
private T[] array;
private int size;
public Heap() {
#SuppressWarnings("unchecked")
T[] tmp = (T[]) (new Comparable[default_size]);
array = tmp;
size = 0;
}
boolean isRoot(int index) { return (index == 0); }
int leftChild(int index) { return 2 * index + 1; }
int parent(int index) { return (index - 1) / 2; }
int rightChild(int index) { return 2 * index + 2; }
T myParent(int index) { return array[parent(index)]; }
T myLeftChild(int index) { return array[leftChild(index)]; }
T myRightChild(int index) { return array[rightChild(index)]; }
boolean hasLeftChild(int i) { return leftChild(i) < size-1; }
boolean hasRightChild(int i){ return rightChild(i) < size-1; }
private void swap(int a, int b) {
T tmp = array[a];
array[a] = array[b];
array[b] = tmp;
}
public boolean isEmpty() { return (size == 0); }
/* adding heap */
public void add(T value) {
if(size == default_size) throw new IllegalStateException("Full array");
array[size++] = value;
bubbleUp();
}
public void bubbleUp() {
if(size == 0) throw new IllegalStateException("Shape error");
int index = size - 1;
while(!isRoot(index)) {
if(myParent(index).compareTo(array[index]) <= 0) break;
/* else part */
swap(parent(index), index);
index = parent(index);
}
}
/* removing */
public T remove() {
if(isEmpty()) return null;
T res = array[0]; /* root */
array[0] = array[size-1];
size --;
bubbleDown();
return res;
}
// i think this section having wrong something
private void bubbleDown() {
int parent = 0;
int leftChild = 2*parent + 1;
int rightChild = 2*parent + 2;
int choice = compareAndPick(leftChild, rightChild);
while (choice != -1)
{
swap(choice, parent);
parent = choice;
choice = compareAndPick(2*choice+1, 2*choice+2);
}
}
private int compareAndPick(int leftChild, int rightChild)
{
if (leftChild >= default_size || array[leftChild] == null) return -1;
if (array[leftChild].compareTo(array[rightChild]) <= 0 || (array[rightChild] == null))
return leftChild;
return rightChild;
}
public void show() {
for(int i=0; i<size; i++)
System.out.print(array[i] + " ");
System.out.println("=======");
}
public static void main(String [] args) {
Heap<Integer> heap = new Heap<Integer>();
for(int i=0; i<10; i++) {
heap.add((Integer)(int)(Math.random() * 100));
heap.show();
}
System.out.println("You should see sorted numbers");
while(!heap.isEmpty()) {
System.out.print(heap.remove());
System.out.print(" ");
heap.show();
}
System.out.println();
}
}
this code used generics and min heap functions.. i need to identify what is the wrong thing did by me on bubbleDown() section
Explanation
The bubbleDown() method is not a different way to insert a node and move it to it's correct position in the Heap. When bubbleDown() is called it's job is to Heapify the Binary Tree from any state. So your attempt to write the method just by changing the condition from the bubbleUp() method isn't gonna help you.
Extra
Here is a video that can give you the idea of how bubbleDown is supposed to work.
I am trying to create a simple pagination routine for values held in an ArrayList. Basically what I want to do is render the first five elements in the ArrayList at first go. And then when users click on Next (increment by another 5) and Previous (decrease by 5).
My logic looks like this:
class foo
{
private static final int defaultStep = 5;
private int moveCounter;
private List<String> values;
public foo()
{
values = new ArrayList<String>();
values.add("Fiber Channel");
values.add("Copper Channel");
...
}
private void pageNext()
{
if (moveCounter > -1 && moveCounter < values.size())
{
int currentIndex = (moveCounter + 1);
renderValues(currentIndex, false);
}
}
private void pagePrevious()
{
if (moveCounter > -1 && moveCounter <= values.size())
{
renderValues(moveCounter-1, true);
}
}
private void renderValues(int startIndex, boolean isPreviousCall)
{
if (startIndex > -1)
{
StringBuilder html = new StringBuilder();
List<String> valuesToRender = new ArrayList<String>();
int checkSteps = 1;
while (startIndex < values.size())
{
valuesToRender.add(values.get(startIndex));
if (checkSteps == defaultStep) break;
startIndex++;
checkSteps++;
}
moveCounter = startIndex;
//TODO: Build html String
...
}
}
}
I have an issue with pagePrevious call, can you guys help me build the valuesToRender 5-steps up values array before adding the value to render to the valuesToRender array.
I tried doing something like this also:
for (int start = startIndex, end = values.size() - 1; start < end; start++, end--)
{
if (isPreviousCall) valuesToRender.add(values.get(end));
else valuesToRender.add(values.get(start));
if (checkSteps == defaultStep) break;
checkSteps++;
}
But this doesn't seems to work neither. Can you guys spot and help me fix this issue.
Thanks Guys.
Based on "pscuderi" solution here
I've built a wrapping class that can be helpful for someone looking for this:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class PaginatedList<T> {
private static final int DEFAULT_PAGE_SIZE = 10;
private List<T> list;
private List<List<T>> listOfPages;
private int pageSize = DEFAULT_PAGE_SIZE;
private int currentPage = 0;
public PaginatedList(List<T> list) {
this.list = list;
initPages();
}
public PaginatedList(List<T> list, int pageSize) {
this.list = list;
this.pageSize = pageSize;
initPages();
}
public List<T> getPage(int pageNumber) {
if (listOfPages == null ||
pageNumber > listOfPages.size() ||
pageNumber < 1) {
return Collections.emptyList();
}
currentPage = pageNumber;
List<T> page = listOfPages.get(--pageNumber);
return page;
}
public int numberOfPages() {
if (listOfPages == null) {
return 0;
}
return listOfPages.size();
}
public List<T> nextPage() {
List<T> page = getPage(++currentPage);
return page;
}
public List<T> previousPage() {
List<T> page = getPage(--currentPage);
return page;
}
public void initPages() {
if (list == null || listOfPages != null) {
return;
}
if (pageSize <= 0 || pageSize > list.size()) {
pageSize = list.size();
}
int numOfPages = (int) Math.ceil((double) list.size() / (double) pageSize);
listOfPages = new ArrayList<List<T>>(numOfPages);
for (int pageNum = 0; pageNum < numOfPages;) {
int from = pageNum * pageSize;
int to = Math.min(++pageNum * pageSize, list.size());
listOfPages.add(list.subList(from, to));
}
}
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
for (int i = 1; i <= 62; i++) {
list.add(i);
}
PaginatedList<Integer> paginatedList = new PaginatedList<Integer>(list);
while (true) {
List<Integer> page = paginatedList.nextPage();
if (page == null || page.isEmpty()) {
break;
}
for (Integer value : page) {
System.out.println(value);
}
System.out.println("------------");
}
}
}
Change
if (moveCounter > -1 && moveCounter <= archive.size())
{
renderValues(moveCounter-1, true);
}
to
if (moveCounter > 0 && moveCounter <= archive.size())
{
renderValues(moveCounter-1, true);
}
I would do it like this:
I'm not sure what renderValues does, and whether we have to substract 1 or maybe defaultStep from the upper bound of the moveCounter.
private void pageMove (int step)
{
moveCounter = moveCounter + step;
if (moveCounter < 0) moveCounter = 0;
if (moveCounter > values.size ()) moveCounter = values.size ();
renderValues (currentIndex, false);
}
private void pageNext ()
{
pageMove (defaultStep);
}
private void pagePrevious ()
{
pageMove (-defaultStep);
}
The first 3 lines could be packed into two big ternary experssions like so:
mc = ((mc + s) < 0) ? 0 : ((mc + s) > vs) ? vs : (mc + s);
but the 3 lines solution is better to follow.
Here is a simple java function for pagination. Note that the page starts from 0 (first page)
public List<Object> pagedResponse(List<Object> allItems, int page, int limit){
int totalItems = allItems.size();
int fromIndex = page*limit;
int toIndex = fromIndex+limit;
if(fromIndex <= totalItems) {
if(toIndex > totalItems){
toIndex = totalItems;
}
return allItems.subList(fromIndex, toIndex);
}else {
return Collections.emptyList();
}
}
I'm very new to binary search and I attempted a code that would read values from a document and then the user can input a number to search for from the document, and through binary search, the number would be found. I'm having trouble now because the "low" variable that I initialize in the binary search section of my code is not being returned to my main code and there's an error that says "low can not be resolved to a variable".
Here is the code for my binary search:
static public int search (int[]numbers,int target, int count)
{
int high = numbers.length;
int low = -1;
int middle = (high+low)/2;
while(high-low>1)
{
count++;
middle = (high+low)/2;
if(numbers[middle]>target)
{
high = middle;
}
else if(numbers[middle]<target)
{
low = middle;
}
else
{
break;
}
System.out.println(numbers[middle]);
System.out.println(middle);
}
if(low == -1 || numbers[low]!=target)
{
low=-1;
return low;
}
else
{
return low;
}
}
And here is the code from my main code. The part with the if statements is where the error is showing up:
public static void main(String[] args) throws IOException {
DataInputStream input = new DataInputStream(System.in);
int [] numbers = new int [50000];
int target;
int count=0;
try
{
BufferedReader br = new BufferedReader(new FileReader("randNums.txt"));
for(int i=0;i<50000;i++)
{
numbers[i]=Integer.parseInt(br.readLine());
}
br.close();
Arrays.sort(numbers);
System.out.print("Choose a number between 1-100000000 to search for: ");
target = Integer.parseInt(input.readLine());
search(numbers, target,count);
if(low==-1)
{
System.out.println("The number was not on the list.");
}
else
{
System.out.println("The number is at position " + low);
System.out.println("It took " + count + " comparisons to find the number.");
}
}
You have to initialize low in main:
int low=search(numbers, target,count);
I have Already resolved this algorithm.
Try my code :
public static int guessNumber(int number) {
int first = 0;
int last = 1_000_000;
if (verify(first) == 0) {
count++;
return first;
}
if (verify(last) == 0) {
count++;
return last;
}
while (last > first && count <= 50) {
count += 1;
// get the middle of the range
int middle = (first + last) / 2;
if (verify(middle) == 0) {
return middle;
}
if (verify(middle) == 1) {
first = middle + 1;
if (verify(first) == 0) {
return first;
}
}else {
last = middle - 1;
if (verify(last) == 0)
return last;
}
}
return 0;
}
//Function verify(integer) => integer
public static int verify(int guess){
if (numberTobeGuessed > guess ) {
return 1;
}else if (numberTobeGuessed < guess) {
return -1;
}
return 0;
}
I recently found a solution for lazy peoples like me use below code
int position = Arrays.binarySearch(numbers , target);
here no need to sort, and array variable number integer variable target.
In java, I have to do a binary search, asking the user to select two names that exist in my list and then print all the people between those two, starting at the first name they enter and ending at the second name they enter. I start by calling the method searchTwoPeople. It's returning nothing.... Here's my code:
public int binarySearch(String searchItem)
{
int first = 0;
int last = nMembers - 1;
int mid = 0;
boolean found = false;
while (first <= last && !found)
{
mid = (first + last) / 2;
if (bookMembers[mid].lastName.compareTo(searchItem) == 0)
found = true;
else if (bookMembers[mid].lastName.compareTo(searchItem) > 0)
last = mid - 1;
else
first = mid + 1;
}
if (!found)
mid = -1; //it is an unsuccessful search
return mid;
}//end binarySearch
public int findFirstPosition(int position)
{
int newPosition = position;
if (position == 0)
{
return position;
}
while (true)
{
if (bookMembers[newPosition-1].lastName.compareTo(bookMembers
[position].lastName) != 0)
{
return newPosition;
}
else
{
--newPosition;
if (newPosition == 0)
{
return newPosition; // no more people in list
}
}
// end sequential search
}
}
public void searchTwoPeople()
{
String lastName = new String();
String lastName2 = new String();
int position, nextPosition;
int tryCount = 0;
boolean more = true;
do
{
lastName = inputFirstLastName();//this is the
method where I have user input a name where to start search and it's passed in here
lastName2 = inputSecondLastName(); //user puts
name where to end search
position = binarySearch(lastName);
if (position == -1)
{
System.out.println ("\n You have no
contacts with the name " + lastName);
++ tryCount;
}
}
while (position == -1 && tryCount < 3);// only let them try
3 times....
if (tryCount == 3)
{
System.out.println("Only allowed 3 attempts -
select a new menu option");
return;
}
nextPosition = findFirstPosition(position);
while (more)
{
System.out.println(bookMembers
[nextPosition].toString());
}
++ nextPosition; // check next person
if (nextPosition == nMembers) // last person in
the list
{
more = false;
}
else
{
if (bookMembers
[nextPosition].lastName.compareTo(lastName2) == 0)
{
more = false;
}
}
}
I want to convert a string input like 2,3,6,7,8,10,12,14,15,16 to 2-3,6-8,10,12,14-16 using java
I tried using the below code
Vector ar=new Vector();
int lastadded=0;
String ht="";
String [] strarray=str.split(",");
strarray=sortArray(strarray);
Vector intarray=new Vector();
for(int i=0;i<strarray.length;i++)
{
int temp=1;
for(int j=1;j<=intarray.size();j++)
{
if(Integer.parseInt(strarray[i])==Integer.parseInt(intarray.get(j-1).toString()))
{
temp=0;
}
}
if(temp==1)
{
intarray.add(Integer.parseInt(strarray[i]));
ar.add(Integer.parseInt(strarray[i]));
}
}
ht="";
String strdemo="";
for(int i=0;i<intarray.size();i++)
{
if(ht=="")
{
ht=ar.get(i)+"";
lastadded=i;
}
else
{
strdemo=(String)ht;
if(strdemo.length()==ar.get(0).toString().length())
{
if(Integer.parseInt(strdemo.substring(0))==Integer.parseInt(ar.get(i).toString())-1)
{
strdemo=strdemo+"-"+ar.get(i);
lastadded=Integer.parseInt(ar.get(i).toString());
ht=strdemo;
}
else
{
strdemo=strdemo+","+ar.get(i);
lastadded=Integer.parseInt(ar.get(i).toString());
ht=strdemo;
}
}
else if(strdemo.length()==3)
{
strdemo=(String)ht;
if(Integer.parseInt(strdemo.substring(strdemo.length()-1,strdemo.length()))==Integer.parseInt(ar.get(i).toString())-1)
{
strdemo=strdemo.substring(0,strdemo.length()-2)+"-"+Integer.parseInt(ar.get(i).toString());
lastadded=Integer.parseInt(ar.get(i).toString());
ht=strdemo;
}
else
{
strdemo=strdemo+","+Integer.parseInt(ar.get(i).toString());
lastadded=Integer.parseInt(ar.get(i).toString());
ht=strdemo;
}
}//Else IF
else{
strdemo=(String)ht;
int de=1;
int ddd=lastadded;
if(ddd==Integer.parseInt(ar.get(i).toString())-1)
{
int lastaddedlen=(lastadded+"").length();
String symbol=strdemo.substring(strdemo.length()-lastaddedlen-1,strdemo.length()-lastaddedlen);
if(symbol.equalsIgnoreCase("-"))
strdemo=strdemo.substring(0,strdemo.length()-lastaddedlen-1)+"-"+Integer.parseInt(ar.get(i).toString());
else
strdemo=strdemo+"-"+Integer.parseInt(ar.get(i).toString());
lastadded=Integer.parseInt(ar.get(i).toString());
ht=strdemo;
}
else
{
strdemo=strdemo+","+Integer.parseInt(ar.get(i).toString());
lastadded=Integer.parseInt(ar.get(i).toString());
ht=strdemo;
}
}
}
}
Here sortArray function sorts the array descending and returns
protected static String[] sortArray(String ss[])
{
String temp;
for(int i=0;i<ss.length;i++)
{
for(int j=0;j<ss.length;j++)
{
if(Integer.parseInt(ss[i])<Integer.parseInt(ss[j]))
{
temp=ss[i];
ss[i]=ss[j];
ss[j]=temp;
}
}
}
return ss;
}
I am not getting consistant results for some inputs for example for the below case
2,3,6,7,8,10,12,14,15,16 it gives 2-3,6-8,10,12,14-16 (which is correct)
while for 2,4,5,6,7,8,10,12,14,15,16 it gives 2-8,10,12,14-16 (which actually should have been 2,4-8,10,12,14-16)
Where does the code go inconsistent is what I need to find out..
This is pretty ugly and verbose in Java, but here is a version. Note, it uses StringUtils from Spring at the very end for the trivial but also ugly process of converting a String collection to a comma delimited string.
The key is to use a separate class to model the numeric ranges. Let this class know how to turn itself into a String. Then you won't have so much logic around appending to a StringBuilder.
Also, try to think in terms of collections. This always makes things clearer. The pseudo-code is something like: String becomes List<Integer> becomes List<Range> and finally becomes String.
public class Ranges {
// A class that models a range of integers
public static class Range {
private int low;
private int high;
public Range(int low, int high) {
this.low = low;
this.high = high;
}
public int getHigh() {
return high;
}
public void setHigh(int high) {
this.high = high;
}
#Override
public String toString() {
return (low == high) ? String.valueOf(low) : String.format("%d-%d", low, high);
}
}
public static void main(String[] args) {
String input = "2,3,6,7,8,10,12,14,15,16";
// Turn input string into a sorted list of integers
List<Integer> inputNumbers = new ArrayList<Integer>();
for (String num : input.split(",")) {
inputNumbers.add(Integer.parseInt(num));
}
Collections.sort(inputNumbers);
// Flatten list of integers into a (shorter) list of Ranges
Range thisRange = null; // the current range being built
List<Range> ranges = new ArrayList<Range>();
for (Integer number : inputNumbers) {
if (thisRange != null && number <= thisRange.getHigh() + 1) {
// if we are already building a range (not null) && this new number is
// the old high end of the range + 1, change the high number.
thisRange.setHigh(number);
} else {
// create a new range and add it to the list being built
thisRange = new Range(number, number);
ranges.add(thisRange);
}
}
// Join List<String> into a single String
String result = StringUtils.collectionToCommaDelimitedString(ranges);
System.out.println("result = " + result);
}
}
Here is my implementation. Hope this help.
You have to pass these values
e.g int[] a = {2,3,4,5,6,7,8,10,12, 14,15,16,18,19,21,22,26};
to the following method.
public List<String> listIntRange(int[] values)
{
List<String> intRangeList = new ArrayList<String>();
int first = 0;
int current = 0;
int prev = 0;
int count = 0;
if (values == null || values.length < 1)
return intRangeList;
first = prev = values[0];
int index = 1;
boolean range = false;
for(index = 1; index < values.length; index++)
{
current = values[index];
if(current - prev == 1)
{
range = true;
prev = current;
continue;
}
if(range == true)
{
intRangeList.add(first + "-" + prev);
}
else
{
intRangeList.add("" + first);
}
first = current;
prev = current;
range = false;
}
if(range == true)
{
intRangeList.add(first + "-" + current);
}
else
{
intRangeList.add("" + current);
}
return intRangeList;
}
Output is as follows, when print out the values from intRangeList:
2-8,10,12,14-16,18-19,21-22,26,
Please ignore last comma ','.