Autocomplete byReverseWeightOrder comparator issue - java

I have been working on this problem for several hours now and I just cannot figure out what I am doing wrong here. Could anyone help point me in the right direction?
I was asked to write an Autocomplete program and I've completed everything except for this one method I cannot get working. Each term has: 1. String query and 2. long weight.
Here is the method:
public static Comparator<Term> byReverseWeightOrder() {
return new Comparator<Term>() { // LINE CAUSING PROBLEM
public int compare(Term t1, Term t2) {
if (t1.weight > t2.weight) { // LINE CAUSING PROBLEM
return -1;
} else if (t1.weight == t2.weight) {
return 0;
} else {
return 1;
}
}
};
}
My problem is that no matter how I mess with the method I always result in a NullPointerException(). Which, it points to this method (byReverseWeightOrder) as well as these two statements.
Arrays.sort(matches, Term.byReverseWeightOrder());
Term[] results = autocomplete.allMatches(prefix);
Here is the rest of the code if it can be found helpful:
Term
import java.util.Comparator;
public class Term implements Comparable<Term> {
public String query;
public long weight;
public Term(String query, long weight) {
if (query == null) {
throw new java.lang.NullPointerException("Query cannot be null");
}
if (weight < 0) {
throw new java.lang.IllegalArgumentException("Weight cannot be negative");
}
this.query = query;
this.weight = weight;
}
public static Comparator<Term> byReverseWeightOrder() {
return new Comparator<Term>() {
public int compare(Term t1, Term t2) {
if (t1.weight > t2.weight) {
return -1;
} else if (t1.weight == t2.weight) {
return 0;
} else {
return 1;
}
}
};
}
public static Comparator<Term> byPrefixOrder(int r) {
if (r < 0) {
throw new java.lang.IllegalArgumentException("Cannot order with negative number of characters");
}
final int ref = r;
return
new Comparator<Term>() {
public int compare(Term t1, Term t2) {
String q1 = t1.query;
String q2 = t2.query;
int min;
if (q1.length() < q2.length()) {
min = q1.length();
}
else {
min = q2.length();
}
if (min >= ref) {
return q1.substring(0, ref).compareTo(q2.substring(0, ref));
}
else if (q1.substring(0, min).compareTo(q2.substring(0, min)) == 0) {
if (q1.length() == min) {
return -1;
}
else {
return 1;
}
}
else {
return q1.substring(0, min).compareTo(q2.substring(0, min));
}
}
};
}
public int compareTo(Term that) {
String q1 = this.query;
String q2 = that.query;
return q1.compareTo(q2);
}
public long getWeight() {
return this.weight;
}
public String toString() {
return this.weight + "\t" + this.query;
}
}
BinarySearchDeluxe
import java.lang.*;
import java.util.*;
import java.util.Comparator;
public class BinarySearchDeluxe {
public static <Key> int firstIndexOf(Key[] a, Key key, Comparator<Key> comparator) {
if (a == null || key == null || comparator == null) {
throw new java.lang.NullPointerException();
}
if (a.length == 0) {
return -1;
}
int left = 0;
int right = a.length - 1;
while (left + 1 < right) {
int middle = left + (right - left)/2;
if (comparator.compare(key, a[middle]) <= 0) {
right = middle;
} else {
left = middle;
}
}
if (comparator.compare(key, a[left]) == 0) {
return left;
}
if (comparator.compare(key, a[right]) == 0) {
return right;
}
return -1;
}
public static <Key> int lastIndexOf(Key[] a, Key key, Comparator<Key> comparator) {
if (a == null || key == null || comparator == null) {
throw new java.lang.NullPointerException();
}
if (a == null || a.length == 0) {
return -1;
}
int left = 0;
int right = a.length - 1;
while (left + 1 < right) {
int middle = left + (right - left)/2;
if (comparator.compare(key, a[middle]) < 0) {
right = middle;
} else {
left = middle;
}
}
if (comparator.compare(key, a[right]) == 0) {
return right;
}
if (comparator.compare(key, a[left]) == 0) {
return left;
}
return -1;
}
}
AutoComplete
import java.util.Arrays;
import java.util.Scanner;
import java.io.File;
import java.io.IOException;
import java.util.Comparator;
public class Autocomplete {
public Term[] terms;
public Autocomplete(Term[] terms) {
if (terms == null) {
throw new java.lang.NullPointerException();
}
this.terms = terms.clone();
Arrays.sort(this.terms);
}
public Term[] allMatches(String prefix) {
if (prefix == null) {
throw new java.lang.NullPointerException();
}
Term theTerm = new Term(prefix, 0);
int start = BinarySearchDeluxe.firstIndexOf(terms, theTerm, Term.byPrefixOrder(prefix.length()));
int end = BinarySearchDeluxe.lastIndexOf(terms, theTerm, Term.byPrefixOrder(prefix.length()));
int count = start;
System.out.println("Start: " + start + " End: " + end);
if (start == -1 || end == -1) {
// System.out.println("PREFIX: " + prefix);
throw new java.lang.NullPointerException();
} // Needed?
Term[] matches = new Term[end - start + 1];
//matches = Arrays.copyOfRange(terms, start, end);
for (int i = 0; i < end - start; i++) {
matches[i] = this.terms[count];
count++;
}
Arrays.sort(matches, Term.byReverseWeightOrder());
System.out.println("Finished allmatches");
return matches;
}
public int numberOfMatches(String prefix) {
if (prefix == null) {
throw new java.lang.NullPointerException();
}
Term theTerm = new Term(prefix, 0);
int start = BinarySearchDeluxe.firstIndexOf(terms, theTerm, Term.byPrefixOrder(prefix.length()));
int end = BinarySearchDeluxe.lastIndexOf(terms, theTerm, Term.byPrefixOrder(prefix.length()));
System.out.println("Finished numberMatches");
return end - start + 1; // +1 needed?
}
public static void main(String[] args) throws IOException {
// Read the terms from the file
Scanner in = new Scanner(new File("wiktionary.txt"));
int N = in.nextInt(); // Number of terms in file
Term[] terms = new Term[N];
for (int i = 0; i < N; i++) {
long weight = in.nextLong(); // read the next weight
String query = in.nextLine(); // read the next query
terms[i] = new Term(query.replaceFirst("\t",""), weight); // construct the term
}
Scanner ip = new Scanner(System.in);
// TO DO: Data Validation Here
int k;
do {
System.out.println("Enter how many matching terms do you want to see:");
k = ip.nextInt();
} while (k < 1 || k > N);
Autocomplete autocomplete = new Autocomplete(terms);
// TO DO: Keep asking the user to enter the prefix and show results till user quits
boolean cont = true;
do {
// Read in queries from standard input and print out the top k matching terms
System.out.println("Enter the term you are searching for. Enter * to exit");
String prefix = ip.next();
if (prefix.equals("*")) {
cont = false;
break;
}
Term[] results = autocomplete.allMatches(prefix);
System.out.println(results.length);
for(int i = 0; i < Math.min(k,results.length); i++)
System.out.println(results[i].toString());
} while(cont);
System.out.println("Done!");
}
}
I apologize for the sloppy code, I have been pulling my hair out for awhile now and keep forgetting to clean it up.
Two examples:
Example 1:
int k = 2;
String prefix = "auto";
Enter how many matching terms do you want to see:
2
Enter the term you are searching for. Enter * to exit
auto
619695 automobile
424997 automatic
Example 2:
int k = 5;
String prefix = "the";
Enter how many matching terms do you want to see:
5
Enter the term you are searching for. Enter * to exit
the
5627187200 the
334039800 they
282026500 their
250991700 them
196120000 there

Related

BubbleDown function(min heap) not working

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.

How to make an "queued" for? [duplicate]

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();
}
}

Binary search algorithm isn't returning variable

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.

binary search between two user defined points, returning all names inbetween those two entered

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;
}
}
}

Convert a string like 2,4,5,6,7,8,10,12,14,15,16 to 2,4-8,10,12,14-16

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 ','.

Categories

Resources