I am working on this magical sub-string problem.
Magical binary strings are non-empty binary strings if the following two conditions are true:
The number of 0's is equal to the number of 1's.
For every prefix of the binary string, the number of 1's should not be less than the number of 0's.
I got stuck on how to proceed further in my Java program.
Here is my program:
static String findLargest(String str) {
String[] splits = str.split("");
Set<String> set = new LinkedHashSet<String>();
for (int i = 0; i < splits.length; i++) {
if (splits[i].equals("0")) {
continue;
}
int zeros = 0;
int ones = 0;
StringBuilder sb = new StringBuilder("");
for (int j = i; j < splits.length; j++) {
if (splits[j].equals("0")) {
zeros++;
} else {
ones++;
}
sb.append(splits[j]);
if (zeros == ones && ones >= zeros) {
set.add(sb.toString());
}
}
}
set.remove(str);
List<String> list = new ArrayList<String>(set);
System.out.println(list);
return null;
}
Using this program I am able to get the magical sub-strings for the given input String 11011000 as [10, 101100, 1100] in my list variable.
Now from here I am struggling how to remove the invalid entry of 101100 from my list and then use the elements 10, 1100 to swap from my input 11011000 to get the final result as 11100100
Also please guide me if there is any other alternate approach.
If your question is about only eliminating the unwanted "101100" from the result, here is the answer
import java.util.ArrayList;
import java.util.HashMap;
import java.lang.*;
import java.util.Set;
import java.util.*;
public class HelloWorld{
public static void main(String []args){
findLargest("11011000");
}
public static String findLargest(String str) {
String[] splits = str.split("");
Set<String> set = new LinkedHashSet<String>();
for (int i = 0; i < splits.length; i++) {
if (splits[i].equals("0")) {
continue;
}
int zeros = 0;
int ones = 0;
StringBuilder sb = new StringBuilder("");
for (int j = i; j < splits.length; j++) {
if (splits[j].equals("0")) {
zeros++;
} else {
ones++;
}
sb.append(splits[j]);
if (zeros == ones && ones >= zeros) {
set.add(sb.toString());
j = i +1; // RESET THE INDEX ELEMENT TO SKIP THE SUBSTRING FROM CONSIDERATION
break; // BREAK FROM THE LOOP
}
}
}
set.remove(str);
List<String> list = new ArrayList<String>(set);
System.out.println(list);
return null;
}
}
I can provide some points.
First, get all the magical substrings and store them as a pair of start and end index(l, r) in a list;
Second, sort the list based on index l;
Those who can be potentially swapped substring can get from the same index l. look at the example given "11011000"
the list will have (0,7),(1,2),(1,6),(3,6),(4,5)
obviously only potential swap is among (1,2)(1,6)
deal these substrings have same index l will help find potential swapping substrings, sort them to find the maximum order.
class Pair{
int start;
int end;
}
public List<Pair> findmagicalPairs(String binString){
List<Pair> magicPairs = new ArrayList<Pair>();
for(int start=0;start<binString.length()-1;start++){
int ones=0;
int zeros=0;
for(int i=start; i<binString.length();i++){
if(binString.charAt(i) == '1'){
ones++;
} else if(binString.charAt(i)=='0'){
zeros++;
}
if(ones == zeros){ //check if magical
Pair temp=new Pair();
temp.start=start;
temp.end =i;
magicPairs.add(temp);
}
}
}
return magicPairs;
}
public String largestMagical(String binString) {
// Write your code here
List<Pair> allPairs = findmagicalPairs(binString);
String largest=binString;
//check by swapping each pairs
for(int i=0;i<allPairs.size()-1;i++){
for(int j=i+1;j<allPairs.size()-1;j++){
if(allPairs.get(i).end+1 == allPairs.get(j).start){
//consecutive Pair so swap and see largest
int index = allPairs.get(j).start;
String swapped = binString.substring(0,allPairs.get(i).start)+binString.substring(allPairs.get(j).start,allPairs.get(j).end+1)+binString.substring(allPairs.get(i).start,allPairs.get(i).end+1)+binString.substring(allPairs.get(j).end+1);
largest = LargestString(largest, swapped);
} else {
//else ignore
}
}
}
return largest;
}
public String LargestString(String first, String second){
if(first.compareTo(second)>0){
return first;
} else {
return second;
}
}
JavaScript Code!
const largestMagical = (binString) => {
//console.log({ binString });
const len = binString.length;
const height = Array(len + 1).fill(0),
num = { 1: 1, 0: -1 },
marked = Array(len + 1).fill(false),
sameHeights = {};
let i,
j,
result = "";
for (i = 1; i <= len; ++i) {
height[i] = height[i - 1] + num[binString[i - 1]];
}
//console.log({ height });
for (i = 0; i <= len; ++i) {
if (marked[i]) continue;
marked[i] = true;
sameHeights[i] = [i];
for (j = i + 1; j <= len; ++j) {
if (height[j] < height[i]) break;
if (height[j] === height[i]) {
sameHeights[i].push(j);
marked[j] = true;
}
}
}
//console.log({ sameHeights });
for (let k in sameHeights) {
const leng = sameHeights[k].length;
let startId, midId, endId;
for (startId = 0; startId < leng - 2; ++startId) {
for (midId = startId + 1; midId < leng - 1; ++midId) {
for (endId = midId + 1; endId < leng; ++endId) {
const start = sameHeights[k][startId],
mid = sameHeights[k][midId],
end = sameHeights[k][endId];
//console.log({start, mid, end});
const swapped =
binString.substring(0, start) +
binString.substring(mid, end) +
binString.substring(start, mid) +
binString.substring(end, len);
//console.log({swapped});
if (swapped > result) result = swapped;
}
}
}
}
return result;
};
console.log(largestMagical("1010111000"));
console.log(largestMagical("11011000"));
I have an array of integers, and I need to find the one that's closest to zero (positive integers take priority over negative ones.)
Here is the code I have so far:
public class CloseToZero {
public static void main(String[] args) {
int[] data = {2,3,-2};
int curr = 0;
int near = data[0];
// find the element nearest to zero
for ( int i=0; i < data.length; i++ ){
curr = data[i] * data[i];
if ( curr <= (near * near) ) {
near = data[i];
}
}
System.out.println( near );
}
}
Currently I'm getting a result of -2 but I should be getting 2. What am I doing wrong?
This will do it in O(n) time:
int[] arr = {1,4,5,6,7,-1};
int closestIndex = 0;
int diff = Integer.MAX_VALUE;
for (int i = 0; i < arr.length; ++i) {
int abs = Math.abs(arr[i]);
if (abs < diff) {
closestIndex = i;
diff = abs;
} else if (abs == diff && arr[i] > 0 && arr[closestIndex] < 0) {
//same distance to zero but positive
closestIndex =i;
}
}
System.out.println(arr[closestIndex ]);
If you are using java8:
import static java.lang.Math.abs;
import static java.lang.Math.max;
public class CloseToZero {
public static void main(String[] args) {
int[] str = {2,3,-2};
Arrays.stream(str).filter(i -> i != 0)
.reduce((a, b) -> abs(a) < abs(b) ? a : (abs(a) == abs(b) ? max(a, b) : b))
.ifPresent(System.out::println);
}
}
Sort the array (add one line of code) so the last number you pick up will be positive if the same absolute value is selected for a positive and negative numbers with the same distance.
Source code:
import java.util.Arrays;
public class CloseToZero {
public static void main(String[] args) {
int[] data = {2,3,-2};
int curr = 0;
int near = data[0];
Arrays.sort(data); // add this
System.out.println(Arrays.toString(data));
// find the element nearest to zero
for ( int i=0; i < data.length; i++ ){
System.out.println("dist from " + data[i] + " = " + Math.abs(0 -data[i]));
curr = data[i] * data[i];
if ( curr <= (near * near) ) {
near = data[i];
}
}
System.out.println( near );
}
}
Just add zero to this list.
Then sort the list
Arrays.sort(data);
then grab the number before or after the zero and pick the minimum one greater than zero
Assumption is that the array data has at least 1 value.
int closestToZero = 0;
for ( int i = 1; i < data.length; i++ )
{
if ( Math.abs(data[i]) < Math.abs(data[closestToZero]) ) closestToZero = i;
}
The value in closestToZero is the index of the value closest to zero, not the value itself.
static int Solve(int N, int[] A){
int min = A[0];
for (int i=1; i<N ; i++){
min = min > Math.abs(0- A[i]) ? Math.abs(0- A[i]) : Math.abs(min);
}
return min;
}
As you multiply data[i] with data[i], a value negative and a value positive will have the same impact.
For example, in your example: 2 and -2 will be 4. So, your code is not able to sort as you need.
So, here, it takes -2 as the near value since it has the same "weight" as 2.
I have same answer with different method,Using Collections and abs , we can solved.
static int Solve(int N, int[] A){
List<Integer> mInt=new ArrayList<>();
for ( int i=0; i < A.length; i++ ){
mInt.add(Math.abs(0 -A[i]));
}
return Collections.min(mInt);
}
That all,As simple as that
This is a very easy to read O(n) solution for this problem.
int bigestNegative = Integer.MIN_VALUE;
int smalestpositive = Integer.MAX_VALUE;
int result = 0;
for (int i = 0; i < n; i++) {
//if the zero should be considered as result as well
if ( temperatures[i] == 0 ) {
result = 0;
break;
}
if ( temperatures[i] > 0 && temperatures[i] < smalestpositive ) {
smalestpositive = temperatures[i];
}
if ( temperatures[i] < 0 && temperatures[i] > bigestNegative ) {
bigestNegative = temperatures[i];
}
}
if( (Math.abs(bigestNegative)) < (Math.abs(smalestpositive)) && bigestNegative != Integer.MIN_VALUE)
result = bigestNegative;
else
result = smalestpositive;
System.out.println( result );
First convert the int array into stream. Then sort it with default sorting order. Then filter greater than zero & peek the first element & print it.
Do it in declarative style which describes 'what to do', not 'how to do'. This style is more readable.
int[] data = {2,3,-2};
IntStream.of(data)
.filter(i -> i>0)
.sorted()
.limit(1)
.forEach(System.out::println);
using Set Collection and abs methode to avoid complex algo
public static void main(String[] args) {
int [] temperature={0};
***// will erase double values and order them from small to big***
Set<Integer> s= new HashSet<Integer>();
if (temperature.length!=0) {
for(int i=0; i<temperature.length; i++) {
***// push the abs value to the set***
s.add(Math.abs(temperature[i]));
}
// remove a zero if exists in the set
while(s.contains(0)) {
s.remove(0);
}
***// get first (smallest) element of the set : by default it is sorted***
if (s.size()!=0) {
Iterator iter = s.iterator();
System.out.println(iter.next());
}
else System.out.println(0);
}
else System.out.println(0);
}
static int nearToZero(int[] A){
Arrays.sort(A);
int ans = 0;
List<Integer> list = Arrays.stream(A).boxed().collect(Collectors.toList());
List<Integer> toRemove = new ArrayList<>();
List<Integer> newList = new ArrayList<>();
for(int num: list){
if(newList.contains(num)) toRemove.add(num);
else newList.add(num);
}
list.removeAll(toRemove);
for(int num : list){
if(num == 0 ) return 0;
if(ans == 0 )ans = num;
if(num < 0 && ans < num) ans = num;
if(num < ans) ans = num;
if(num > 0 && Math.abs(ans) >= num) ans = num;
}
return ans;
}
here is a method that gives you the nearest to zero.
use case 1 : {1,3,-2} ==> return 1 : use the Math.abs() for comparison and get the least.
use case 2 : {2,3,-2} ==> return 2 : use the Math.abs() for comparison and get the Math.abs(least)
use case 3 : {-2,3,-2} ==> return -2: use the Math.abs() for comparison and get the least.
public static double getClosestToZero(double[] liste) {
// if the list is empty return 0
if (liste.length != 0) {
double near = liste[0];
for (int i = 0; i < liste.length; i++) {
// here we are using Math.abs to manage the negative and
// positive number
if (Math.abs(liste[i]) <= Math.abs(near)) {
// manage the case when we have two equal neagative numbers
if (liste[i] == -near) {
near = Math.abs(liste[i]);
} else {
near = liste[i];
}
}
}
return near;
} else {
return 0;
}
}
You can do like this:
String res = "";
Arrays.sort(arr);
int num = arr[0];
int ClosestValue = 0;
for (int i = 0; i < arr.length; i++)
{
//for negatives
if (arr[i] < ClosestValue && arr[i] > num)
num = arr[i];
//for positives
if (arr[i] > ClosestValue && num < ClosestValue)
num = arr[i];
}
res = num;
System.out.println(res);
First of all you need to store all your numbers into an array. After that sort the array --> that's the trick who will make you don't use Math.abs(). Now is time to make a loop that iterates through the array. Knowing that array is sorted is important that you start to make first an IF statement for negatives numbers then for the positives (in this way if you will have two values closest to zero, let suppose -1 and 1 --> will print the positive one).
Hope this will help you.
The easiest way to deal with this is split the array into positive and negative sort and push the first two items from both the arrays into another array. Have fun!
function closeToZeroTwo(arr){
let arrNeg = arr.filter(x => x < 0).sort();
let arrPos = arr.filter(x => x > 0).sort();
let retArr = [];
retArr.push(arrNeg[0], arrPos[0]);
console.log(retArr)
}
Easiest way to just sort that array in ascending order suppose input is like :
int[] array = {10,-5,5,2,7,-4,28,65,95,85,12,45};
then after sorting it will gives output like:
{-5,-4,2,5,7,10,12,28,45,65,85,95,}
and for positive integer number, the Closest Positive number is: 2
Logic :
public class Closest {
public static int getClosestToZero(int[] a) {
int temp=0;
//following for is used for sorting an array in ascending nubmer
for (int i = 0; i < a.length-1; i++) {
for (int j = 0; j < a.length-i-1; j++) {
if (a[j]>a[j+1]) {
temp = a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
//to check sorted array with negative & positive values
System.out.print("{");
for(int number:a)
System.out.print(number + ",");
System.out.print("}\n");
//logic for check closest positive and Integer
for (int i = 0; i < a.length; i++) {
if (a[i]<0 && a[i+1]>0) {
temp = a[i+1];
}
}
return temp;
}
public static void main(String[] args) {
int[] array = {10,-5,5,2,7,-4,28,65,95,85,12,45};
int closets =getClosestToZero(array);
System.out.println("The Closest Positive number is : "+closets);
}
}
static void closestToZero(){
int[] arr = {45,-4,-12,-2,7,4};
int max = Integer.MAX_VALUE;
int closest = 0;
for (int i = 0; i < arr.length; i++){
int value = arr[i];
int abs = Math.abs(value);
if (abs < max){
max = abs;
closest = value;
}else if (abs == max){
if (value > closest){
closest = value;
}
}
}
Return a positive integer if two absolute values are the same.
package solution;
import java.util.Scanner;
public class Solution {
public static void trier(int tab[]) {
int tmp = 0;
for(int i = 0; i < (tab.length - 1); i++) {
for(int j = (i+1); j< tab.length; j++) {
if(tab[i] > tab[j]) {
tmp = tab[i];
tab[i] = tab[j];
tab[j] = tmp;
}
}
}
int prochePositif = TableauPositif(tab);
int procheNegatif = TableauNegatif(tab);
System.out.println(distanceDeZero(procheNegatif,prochePositif));
}
public static int TableauNegatif(int tab[]) {
int taille = TailleNegatif(tab);
int tabNegatif[] = new int[taille];
for(int i = 0; i< tabNegatif.length; i++) {
tabNegatif[i] = tab[i];
}
int max = tabNegatif[0];
for(int i = 0; i <tabNegatif.length; i++) {
if(max < tabNegatif[i])
max = tabNegatif[i];
}
return max;
}
public static int TableauPositif(int tab[]) {
int taille = TailleNegatif(tab);
if(tab[taille] ==0)
taille+=1;
int taillepositif = TaillePositif(tab);
int tabPositif[] = new int[taillepositif];
for(int i = 0; i < tabPositif.length; i++) {
tabPositif[i] = tab[i + taille];
}
int min = tabPositif[0];
for(int i = 0; i< tabPositif.length; i++) {
if(min > tabPositif[i])
min = tabPositif[i];
}
return min;
}
public static int TailleNegatif(int tab[]) {
int cpt = 0;
for(int i = 0; i < tab.length; i++) {
if(tab[i] < 0) {
cpt +=1;
}
}
return cpt;
}
public static int TaillePositif(int tab[]) {
int cpt = 0;
for(int i = 0; i < tab.length; i++) {
if(tab[i] > 0) {
cpt +=1;
}
}
return cpt;
}
public static int distanceDeZero(int v1, int v2) {
int absv1 = v1 * (-1);
if(absv1 < v2)
return v1;
else if(absv1 > v2)
return v2;
else
return v2;
}
public static void main(String[] args) {
int t[] = {6,5,8,8,-2,-5,0,-3,-5,9,7,4};
Solution.trier(t);
}
}
To maintain O(n) time complexity and getting the desired results we have to add another variable called 'num' and assign to it 'near' before changing it's value. And finally make necessary checks. The improvements in the code are are:
public class CloseToZero {
public static void main(String[] args) {
int[] data = {2,3,-2};
int curr = 0;
int near = data[0];
int num=near;
// find the element nearest to zero
for ( int i=0; i < data.length; i++ ){
curr = data[i] * data[i];
if ( curr <= (near * near) ) {
num=near;
near = data[i];
}
}
if(near<0 && near*(-1)==num)
near=num;
System.out.println( near );
}
}
We have to find the Closest number to zero.
The given array can have negative values also.
So the easiest approach would append the '0' in the given array and sort it and return the element next to '0'
append the 0
Sort the Array
Return the element next to 0.
`
N = int(input())
arr = list(map(int, input().split()))
arr.append(0)
arr.sort()
zeroIndex = arr.index(0)
print(arr[zeroIndex + 1])
--> If this solution leaves corner cases please let me know also.
`
if you don't wanna use the inbuilt library function use the below code (just an and condition with your existing code)-
public class CloseToZero {
public static void main(String[] args) {
int[] data = {2,3,-2,-1,1};
int curr = 0;
int near = data[0];
// find the element nearest to zero
for ( int i=0; i < data.length; i++ ){
curr = data[i] * data[i];
if ( curr <= (near * near) && !((curr - (near * near) == 0) && data[i] < 0)) {
near = data[i];
}
}
System.out.println( near );
}
}
!((curr - (near * near) == 0) && data[i] < 0) : skip asignment if if near and curr is just opposit in sign and the curr is negative
public static int find(int[] ints) {
if (ints==null) return 0;
int min= ints[0]; //a random value initialisation
for (int k=0;k<ints.length;k++) {
// if a positive value is matched it is prioritized
if (ints[k]==Math.abs(min) || Math.abs(ints[k])<Math.abs(min))
min=ints[k];
}
return min;
}
public int check() {
int target = 0;
int[] myArray = { 40, 20, 100, 30, -1, 70, -10, 500 };
int result = myArray[0];
for (int i = 0; i < myArray.length; i++) {
if (myArray[i] == target) {
result = myArray[i];
return result;
}
if (myArray[i] > 0 && result >= (myArray[i] - target)) {
result = myArray[i];
}
}
return result;
}
I have added a check for the positive number itself.
Please share your views folks!!
public class ClosesttoZero {
static int closZero(int[] ints) {
int result=ints[0];
for(int i=1;i<ints.length;i++) {
if(Math.abs(result)>=Math.abs(ints[i])) {
result=Math.abs(ints[i]);
}
}
return result;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] ints= {1,1,5,8,4,-9,0,6,7,1};
int result=ClosesttoZero.closZero(ints);
System.out.println(result);
}
}
It can be done simply by making all numbers positive using absolute value then sort the Array:
int[] arr = {9, 1, 4, 5, 6, 7, -1, -2};
for (int i = 0; i < arr.length; ++i)
{
arr[i] = Math.abs(arr[i]);
}
Arrays.sort(arr);
System.out.println("Closest value to 0 = " + arr[0]);
import java.math.*;
class Solution {
static double closestToZero(double[] ts) {
if (ts.length == 0)
return 0;
double closestToZero = ts[0];
double absClosest = Math.abs(closestToZero);
for (int i = 0; i < ts.length; i++) {
double absValue = Math.abs(ts[i]);
if (absValue < absClosest || absValue == absClosest && ts[i] > 0) {
closestToZero = ts[i];
absClosest = absValue;
}
}
return closestToZero;
}
}
//My solution priorizing positive numbers contraint
int closestToZero = Integer.MAX_VALUE;//or we
for(int i = 0 ; i < arrayInt.length; i++) {
if (Math.abs(arrayInt[i]) < closestToZero
|| Math.abs(closestToZero) == Math.abs(arrayInt[i]) && arrayInt[i] > 0 ) {
closestToZero = arrayInt[i];
}
}
Hi i need some help to improve my code. I am trying to use Radixsort to sort array of 10 numbers (for example) in increasing order.
When i run the program with array of size 10 and put 10 random int numbers in like
70
309
450
279
799
192
586
609
54
657
i get this out:
450
309
192
279
54
192
586
657
54
609
DonĀ“t see where my error is in the code.
class IntQueue
{
static class Hlekkur
{
int tala;
Hlekkur naest;
}
Hlekkur fyrsti;
Hlekkur sidasti;
int n;
public IntQueue()
{
fyrsti = sidasti = null;
}
// First number in queue.
public int first()
{
return fyrsti.tala;
}
public int get()
{
int res = fyrsti.tala;
n--;
if( fyrsti == sidasti )
fyrsti = sidasti = null;
else
fyrsti = fyrsti.naest;
return res;
}
public void put( int i )
{
Hlekkur nyr = new Hlekkur();
n++;
nyr.tala = i;
if( sidasti==null )
f yrsti = sidasti = nyr;
else
{
sidasti.naest = nyr;
sidasti = nyr;
}
}
public int count()
{
return n;
}
public static void radixSort(int [] q, int n, int d){
IntQueue [] queue = new IntQueue[n];
for (int k = 0; k < n; k++){
queue[k] = new IntQueue();
}
for (int i = d-1; i >=0; i--){
for (int j = 0; j < n; j++){
while(queue[j].count() != 0)
{
queue[j].get();
}
}
for (int index = 0; index < n; index++){
// trying to look at one of three digit to sort after.
int v=1;
int digit = (q[index]/v)%10;
v*=10;
queue[digit].put(q[index]);
}
for (int p = 0; p < n; p++){
while(queue[p].count() != 0) {
q[p] = (queue[p].get());
}
}
}
}
}
I am also thinking can I let the function take one queue as an
argument and on return that queue is in increasing order? If so how?
Please help. Sorry if my english is bad not so good in it.
Please let know if you need more details.
import java.util.Random;
public class RadTest extends IntQueue {
public static void main(String[] args)
{
int [] q = new int[10];
Random r = new Random();
int t = 0;
int size = 10;
while(t != size)
{
q[t] = (r.nextInt(1000));
t++;
}
for(int i = 0; i!= size; i++)
{
System.out.println(q[i]);
}
System.out.println("Radad: \n");
radixSort(q,size,3);
for(int i = 0; i!= size; i++)
{
System.out.println(q[i]);
}
}
}
Hope this is what you were talking about...
Thank you for your answer, I will look into it. Not looking for someone to solve the problem for me. Looking for help and Ideas how i can solve it.
in my task it says:
Implement a radix sort function for integers that sorts with queues.
The function should take one queue as an
argument and on return that queue should contain the same values in ascending
order You may assume that the values are between 0 and 999.
Can i put 100 int numbers on my queue and use radixsort function to sort it or do i need to put numbers in array and then array in radixsort function which use queues?
I understand it like i needed to put numbers in Int queue and put that queue into the function but that has not worked.
But Thank for your answers will look at them and try to solve my problem. But if you think you can help please leave comment.
This works for the test cases I tried. It's not entirely well documented, but I think that's okay. I'll leave it to you to read it, compare it to what you're currently doing, and find out why what you have might be different than mine in philosophy. There's also other things that are marked where I did them the "lazy" way, and you should do them a better way.
import java.util.*;
class Radix {
static int[] radixSort(int[] arr) {
// Bucket is only used in this method, so I declare it here
// I'm not 100% sure I recommend doing this in production code
// but it turns out, it's perfectly legal to do!
class Bucket {
private List<Integer> list = new LinkedList<Integer>();
int[] sorted;
public void add(int i) { list.add(i); sorted = null;}
public int[] getSortedArray() {
if(sorted == null) {
sorted = new int[list.size()];
int i = 0;
for(Integer val : list) {
sorted[i++] = val.intValue(); // probably could autobox, oh well
}
Arrays.sort(sorted); // use whatever method you want to sort here...
// Arrays.sort probably isn't allowed
}
return sorted;
}
}
int maxLen = 0;
for(int i : arr) {
if(i < 0) throw new IllegalArgumentException("I don't deal with negative numbers");
int len = numKeys(i);
if(len > maxLen) maxLen = len;
}
Bucket[] buckets = new Bucket[maxLen];
for(int i = 0; i < buckets.length; i++) buckets[i] = new Bucket();
for(int i : arr) buckets[numKeys(i)-1].add(i);
int[] result = new int[arr.length];
int[] posarr = new int[buckets.length]; // all int to 0
for(int i = 0; i < result.length; i++) {
// get the 'best' element, which will be the most appropriate from
// the set of earliest unused elements from each bucket
int best = -1;
int bestpos = -1;
for(int p = 0; p < posarr.length; p++) {
if(posarr[p] == buckets[p].getSortedArray().length) continue;
int oldbest = best;
best = bestOf(best, buckets[p].getSortedArray()[posarr[p]]);
if(best != oldbest) {
bestpos = p;
}
}
posarr[bestpos]++;
result[i] = best;
}
return result;
}
static int bestOf(int a, int b) {
if(a == -1) return b;
// you'll have to write this yourself :)
String as = a+"";
String bs = b+"";
if(as.compareTo(bs) < 0) return a;
return b;
}
static int numKeys(int i) {
if(i < 0) throw new IllegalArgumentException("I don't deal with negative numbers");
if(i == 0) return 1;
//return (i+"").length(); // lame method :}
int len = 0;
while(i > 0) {
len++;
i /= 10;
}
return len;
}
public static void main(String[] args) {
int[] test = {1, 6, 31, 65, 143, 316, 93, 736};
int[] res = radixSort(test);
for(int i : res) System.out.println(i);
}
}
One thing that looks strange:
for (int p = 0; p < n; p++){
while(queue[p].count() != 0) {
q[p] = (queue[p].get());
}
}
Is p supposed to be the index in q, which ranges from 0 to n-1, or in queue, which ranges from 0 to 9? It is unlikely to be both ...
Another:
for (int index = 0; index < n; index++){
// trying to look at one of three digit to sort after.
int v=1;
int digit = (q[index]/v)%10;
v*=10;
queue[digit].put(q[index]);
}
Why are you multiplying v by 10, only to overwrite it by v = 1 in the next iteration? Are you aware than v will always be one, and you will thus look at the same digit in every iteration?
Well I don't think I can help without almost posting the solution (just giving hints is more exhausting and I'm a bit tired, sorry), so I'll just contribute a nice little fuzz test so you can test your solution. How does that sound? :-)
Coming up with a good fuzztester is always a good idea if you're implementing some algorithm. While there's no 100% certainty if that runs with your implementation chances are it'll work (radix sort doesn't have any strange edge cases I'm aware of that only happen extremely rarely)
private static void fuzztest() throws Exception{
Random rnd = new Random();
int testcnt = 0;
final int NR_TESTS = 10000;
// Maximum size of array.
final int MAX_DATA_LENGTH = 1000;
// Maximum value allowed for each integer.
final int MAX_SIZE = Integer.MAX_VALUE;
while(testcnt < NR_TESTS){
int len = rnd.nextInt(MAX_DATA_LENGTH) + 1;
Integer[] array = new Integer[len];
Integer[] radix = new Integer[len];
for(int i = 0; i < len; i++){
array[i] = rnd.nextInt(MAX_SIZE);
radix[i] = new Integer(array[i]);
}
Arrays.sort(array);
sort(radix); // use your own sort function here.
for(int i = 0; i < len; i++){
if(array[i].compareTo(radix[i]) != 0){
throw new Exception("Not sorted!");
}
}
System.out.println(testcnt);
testcnt++;
}