Sorting program not sorting correctly - java

My program is meant to take in file in the current format with the top number being the max length of the words, the second number being the number of words that are there, and the rest being the numbers to be sorted.
4
10
437 1807 3218 1791 9058 9322 766 9977 16 7143
And then sort it so from lowest to highest. But every time i try to get it working i generally get the highest number in the first spot and the rest is just a jumbled mess. The final three for loops where meant to resemble this pseudo code:
the first power of ten = 10;
for each i up to the maximum number of digits+1
1. for each value v in the array, starting at position 0:
a. isolate the “ith” digit from v (call this digit d) – use the current power
of ten to do this
b. add v to bin[d]
2. for each bin (that is, each bin[j], starting with j=0)
a. while bin[j] is not empty
i. remove the first value from bin[j] and copy it back into the next
position in the array
3. Increase the power of ten to the next power of ten
Any help would be appreciated.
import java.io.*;
import java.util.*;
public class BinSort {
public static void main(String[] args) throws FileNotFoundException {
Scanner sc = new Scanner(new File(args[0]));
int length = sc.nextInt();
int size = sc.nextInt();
int[] temp = new int[size];
sc.nextLine();
for(int i = 0;i < temp.length;i++){
temp[i] = sc.nextInt();
}
sort(temp,size,length);
}
public static void sort(int[] input, int length,int size){
ArrayList<Integer>[]bin=(ArrayList<Integer>[]) new ArrayList[10];
for(int i = 0;i<length;i++){
bin[i] = new ArrayList<Integer>();
}
int power = 10;
for(int i = 0;i<size+1;i++){
for(int v = 0;v<input.length;v++){
int d = input[v] % power;
if(power>10)
d = d/ (power/10);
bin[d].add(input[v]);
}
for(int j = 0;j<10;j++){
while(!bin[j].isEmpty()){
int temp = bin[j].get(0);
bin[j].remove(0);
input[j] = temp;
}
}
power = power*10;
}
System.out.println("Final result");
System.out.println(Arrays.toString(input));
}
}

input[j] = temp;
should read
input[pos] = temp;

Related

Having trouble in printing the largest array number from the 20 randomly generated numbers

Ok so I been working on this assignment all day for the past 3 days but I haven't had any luck. I wasn't going to ask for help but I finally gave up. But there is also one more thing I need to implement to the code. This is what I gotta implement "Find the length of the longest continuous series of positive numbers in the array data. If the contents were: 4 5 0 2 . . . -1 88 78 66 -6. The length would be 3. For this problem, 0 is considered non-negative but not positive". Plus I have an issue where I can't print the largest int in the array of 20.
import java.util.Random;
import java.util.ArrayList;
public class arrayops {
public static int findLargest(ArrayList<Integer> nums) {
int greatestnum = nums.get(0);
for (Integer item : nums) {
if (item > greatestnum) {
greatestnum = item;
}
}
return greatestnum;
}
public static int randomData(ArrayList<Integer> nums) {
int[] array = new int [20];
Random random = new Random();
for (int i = 0; i < array.length; i++) {
array[i] = -100 + random.nextInt(201);
}
return -100 + random.nextInt(201);
}
public static void main(String[] args) {
ArrayList<Integer> nums = new ArrayList<Integer>();
nums.add(1);
nums.add(4);
nums.add(13);
nums.add(43);
nums.add(-25);
nums.add(17);
nums.add(22);
nums.add(-37);
nums.add(29);
System.out.println("The Greatest Number from the hardcoded numbers " + findLargest(nums));
System.out.println("The Greatest number from the random numbers " + randomData(nums));
}
}
The findLargest method:
public static int findLargest(ArrayList<Integer> nums) {
int greatestnum = 0;
int greatestLen = 0;
for (Integer item : nums) {
if (item > 0) {
greatestLen++ ;
if(greatestLen > greatestnum)
greatestnum = greatestLen;
}
else
greatestLen = 0;
}
return greatestnum;
}
Logic used:
Keep the length of the longest chain encountered, and the length of current chain, in two separate variables (greatestnum and greatestLen respectively)
Increment greatestLen every time a positive number is encountered. If the number if less than or equal to zero, reset this count.
If the length of current chain is greater than the previous longest chain, sent the longest chain size to current chain size.
The problem is you created a list with random numbers but never put that list into the findLargest method. You also never created a method to find the consecutive positive numbers. If you didn't know how to go about coding it, I recommend drawing out an algorithm on paper.
Largest value in ArrayList...
public static int findL(ArrayList<Integer> nums)
{
int top = nums.get(0);
for(int i = 0; i<nums.size(); i++)
{
if(nums.get(i)>top)
{
top = nums.get(i);
}
}
return top;
}
Largest number of consecutive positives...
public static int positiveString(ArrayList<Integer> nums)
{
int longest = 0;
int count = 0;
for(int i = 0; i<nums.size(); i++)
{
if(nums.get(i) > 0)
{
count++;
}
else
{
if(longest<count)
{
longest = count;
}
count = 0;
}
}
return longest;
}
If you want to arrange the numbers into order you can simply use java.util.TreeSet. Then use the method last() to get the largest number.
public static int findLargest(ArrayList<Integer> nums) {
return new TreeSet<Integer>(nums).last();
}

How to use create 2 Array with User input with Std.readAllInts()

This is how it should work, i Put in put for the 1 st array like: 2 3 1 2 3 4 5 6 then 2 and 3 are row and colum and the rest are the values. Problem is the 1st array work, but when i reach EOF ( ctrl+z) then there is out of bound exception. Which mean i cant input value for the 2nd Array like the 1st one. I know there is anotherway where that i can declare array size first then value. But how could i fix this f i still want to usr StdIn.readAllInts() ?
public class MatrixMult {
public static void main(String[] args){
System.out.println("First Matrix Config");
int[] einGabeMatrix1= StdIn.readAllInts();
int zeileM1 = einGabeMatrix1[0];
int spalteM1 = einGabeMatrix1[1];
int[][] ersteMatrix= new int [zeileM1][spalteM1];
int k=2;
int sum;
for(int i=0;i<zeileM1-1;i++){
for(int j=0;j<spalteM1-1;j++){
ersteMatrix[i][j]=einGabeMatrix1[k];
k++;
}
}
System.out.println("Second Matrix Config");
int[] einGabeMatrix2 = StdIn.readAllInts();
int zeileM2 = einGabeMatrix2[0];
int spalteM2 = einGabeMatrix2[1];
int h=2;
int[][] zweiteMatrix= new int [zeileM2][spalteM2];
for(int m=0;m<zeileM2-1;m++){
for(int n=0;n<spalteM2-1;n++){
zweiteMatrix[m][n]=einGabeMatrix2[h];
h++;
}
}
int[][] ergebnisMatrix= new int [zeileM1][spalteM2];
for (int t = 0; t < zeileM1; t++) {
for (int c = 0; c < spalteM2; c++) {
sum = 0;
for (int d = 0; d < spalteM1; d++) {
sum = sum + ersteMatrix[t][d] * zweiteMatrix[d][c];
}
ergebnisMatrix[t][c] = sum;
}
}
for(int i=0;i<zeileM1;i++){
for(int j=0;j<spalteM1;j++){
System.out.println(ergebnisMatrix[i][j]);
}
}
}
}
// This is StdIn.readAllInts(), standard method by java.
public static int[] readAllInts() {
String[] fields = readAllStrings();
int[] vals = new int[fields.length];
for (int i = 0; i < fields.length; i++)
vals[i] = Integer.parseInt(fields[i]);
return vals;
}
It looks like the issue is coming from the fact that StdIn.readAllInts() reads until the EOF. There will be no values left to read by the time your code gets to the second call.
I would suggest instead using the StdIn.readInt() call to read each integer one at a time and then you can use it within your loop to read the exact number of values your need.
Here is an example of how you could get the first 2 integers to find your matrix size:
int zeileM1 = StdIn.readInt();
int spalteM1 = StdIn.readInt();
You will also need to apply this method in your for loops to read the data into the matrix.

Arthur and co prime program Coprime Conundrum not getting the desired output

I am writing one java program. Arthur defines a function f(k) to be the number of (p,q) pairs such that:
1< p <= q <= k
p and q are coprimes
p.q=k
I am supposed to write one program for a given integer n and help Arthur find and print the result of (Σ k=1 to n) f(k)
Constraints:
1<=n<=pow(10,9)
For e.g
(Input)Let's say n = 12
For the value of f(k) for 1<=k<=12
For k=6 there is one valid pair (2,3), so f(6) = 1
For k=10 there is one valid pair (2,5), so f(10) = 1
For k=12 there is one valid pair (3,4), so f(12) = 1
For all other 1<=k<=12 the function return 0
So, other final sum is the result of 1+1+1 = 3 (Final output)
Here is my code:
import java.util.Scanner;
class ArthurFunction{
public static boolean areCoPrime(int a, int b){
int max = 0;
boolean flag = true;
if(a>=b)
max = a;
else
max = b;
for(int i=2;i<=max;i++)
if((a%i==0)&&(b%i==0))
flag = false;
return flag;
}
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
int sum = 0;
for(int k = 1;k<=n;k++){
for(int p=2;p<=k;p++){
for(int q=2;q<=k;q++){
if(areCoPrime(p,q)&&(p*q==k)&&(p<=q))
sum+=sum;
}
}
}
System.out.println(sum);
}
}
When I run this code the output should be 3 but I am getting 0 and also unable to find the solution.
You can improve your program by
Making a faster areCoPrime() method
Decrease the number of nested loops in main()
For (1), we know 2 numbers are coprime when their greatest common divisor (GCD) is 1. Their is an efficient method to find GCD called Euclidean algorithm.
For (2), you can remove the 3rd loop, p in the 2nd loop only need to go to sqrt(k)
Refer to my revised code below (Tested: n = pow(10,6) runs less than 2 secs on my PC)
import java.util.Scanner;
class ArthurFunction{
public static boolean areCoPrime(int a, int b){
if (GCD(a,b)==1) return true;
return false;
}
public static int GCD(int a, int b) {
if (b==0) return a;
return GCD(b,a%b);
}
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
int sum = 0;
for(int k=1;k<=n;k++){
for(int p=2;p*p<k;p++){
if(k%p==0) {
int q = k/p;
if (areCoPrime(p,q)) sum++;
}
}
}
System.out.println(sum);
}
}

Find peaks in array (with neighborhood)

Suppose I have a 1D array, and I want to find peaks. The difference from classic peak finding is that I need to check not only its neighbors, but I need to check n left neighbors and n right neighbors. For example my array is following:
[1,2,3,4,5,6,7,8,9,8,7,6,5,4,3,2,1]
And n = 4. I need to check every subarray with length 4 + 1 + 4 and see if the middle element is the maximum.
In the case:
[5,6,7,8,9,8,7,6,5], 9 is the peak.
But this does not sound very efficient. So what can be a better solution? When I find a peak, I can ignore the next n elements I think.
Try to avoid unimportant comparison. Example
public class NewClass12 {
static int [] arr = {1,2,3,4,5,3,2,1,0,9,7,6,5,4,3,2,1};
public static void main(String [] args){
int n = 4; //bounds
boolean peakFound = false;
int peak = 0;
//iterate of data
for(int k = n; k<=arr.length-n+1;k++){
//check data within bounds
for (int i = 1;i <=n;i++){
if(arr[k]<arr[k-i] || arr[k]<arr[k+i]){
peakFound = false;
break;
}
else{
peakFound = true;
peak = arr[k];
}
}
if(peakFound)
System.out.println(peak);
}
}
}

How can I prevent the overlapping random numbers

How would i prevent duplicating numbers from random numbers.
I need to generate 5 numbers between 1 and 9 that are each different.
I would often get same numbers like 23334, how can i prevent that?
Any help would be great!
int num2 = (int) Math.round((Math.random()*9) +1);
int num1 = (int) Math.round((Math.random()*9) +1);
int num5 = (int) Math.round((Math.random()*9) +1);
int num3 = (int) Math.round((Math.random()*9) +1);
int num4 = (int) Math.round((Math.random()*9) +1);
One option is to use shuffle algorithm (e.g. Fisher-Yates shuffle ) to generate random sequence from 1 to 9, then take first 5 numbers of the sequence
Further explanation on StackOverflow: https://stackoverflow.com/a/196065/950427
Set<Integer> set=new HashSet<>();
while (set.size()<5) {
set.add( Math.round((Math.random()*9) +1));
}
After the set is filled you have 5 unique random numbers.
UPDATE: just to illustrate Jared Burrows' comment
Create a List includes the numbers that you want (1 to 9).
Generate random number from 0 to (size of the list minus 1).
Remove one element by index from the above generated random number. And add the removed element to a array which to be returned as a results
public static void main(String[] args) {
int []answers= returnRandomNonRepeatingNumbers(5,0,9);
for(int answer: answers) {
System.out.println(answer);
}
}
public static int[] returnRandomNonRepeatingNumbers(int sizeYouWant, int poolStart, int poolEnd) {
List<Integer> pool=new ArrayList<Integer>();
for(int i=poolStart;i<=poolEnd;i++) {
pool.add(i);
}
int []answers=new int[sizeYouWant];
for(int i=0;i<sizeYouWant;i++) {
//random index to be pick and remove from pool
int randomIndex = (int) Math.round((Math.random()*(pool.size()-1)));
answers[i]=pool.remove(randomIndex);
}
return answers;
}
If the number of possible random values is small, you want to use shuffle.
List<Integer> values = IntStream.range(0, 10).boxed().collect(toList());
Collections.shuffle(values);
values = values.subList(0, 5);
If the number of possible random values is large, you want to test adding them to a Set (or the original list if small enough)
Set<Integer> valueSet = new HashSet<>();
Random rand = new Random();
while(valuesSet.size() < 5) valuesSet.add(rand.nextInt(9) + 1);
List<Integer> values = new ArrayList<>(valueSet);
Collections.shuffle(values, rand);
Note: you need to shuffle the set as it doesn't preserve order. e.g. the numbers 1,2,3 will always come out in that order with HashSet, not 3,2,1.
Floyd's subset selection algorithm is designed to do exactly what you want, and is extremely efficient even for large sets. Selecting m items from a set of n is O(m) average running time, independent of n. Here's a Java implementation.
/*
* Floyd's algorithm to chose a random subset of m integers
* from a set of n, zero-based.
*/
public static HashSet<Integer> generateMfromN(int m, int n) {
HashSet<Integer> s = new HashSet<Integer>();
for (int j = n-m; j < n; ++j) {
if(! s.add((int)((j+1) * Math.random()))) {
s.add(j);
}
}
return s;
}
One possible approach to this problem can be divide & conquer. Step of following describes the approach:
Say m is the minimum & n is the maximum, within what i wanna get x number of randoms
Choose a random p between m & n. Save it to an array of answer. decrease x by 1 as we get one answer to our problem.
Now take a q a random number between m & p-1, another r a random number between p+1 & n. Fill up the answer array with q & r decrease x 1 for q and another 1 for the r.
Now carry on this process recursively, until the lower bound (m) & higher bound (n) becomes equal or x becomes 0.
Benefit: benefit of this approach is that, in worst case, it's runtime will be O(x), where x is the number of random number required. The best case scenarion is also o(x), as i have to find at least n number of random. These two comprise average case to θ(x) complexity.
import java.util.Random;
class GenerateDistinctRandom{
static int alreadyPut = 0;
static Random rand = new Random();
public static int[] generateDistinctRandom(int howMany, int rangeMin, int rangeMax)
{
int randomNumbers[] = new int[howMany];
GenerateDistinctRandom.recursiveRandomGenerator(rangeMin, rangeMax, randomNumbers, howMany);
return randomNumbers;
}
private static void recursiveRandomGenerator(int rangeMin, int rangeMax, int[] storage ,int storageSize)
{
if(rangeMax - rangeMin <= 0 || GenerateDistinctRandom.alreadyPut == storageSize)
{
return ;
}
int randomNumber = GenerateDistinctRandom.rand.nextInt(rangeMax-rangeMin) + rangeMin;
storage[GenerateDistinctRandom.alreadyPut] = randomNumber;
GenerateDistinctRandom.alreadyPut++;
//calling the left side of the recursion
recursiveRandomGenerator(rangeMin, randomNumber - 1, storage, storageSize);
recursiveRandomGenerator(randomNumber + 1, rangeMax, storage, storageSize);
}
public static void main(String []args){
int howMany = 5;
int distinctNumber[] = GenerateDistinctRandom.generateDistinctRandom(howMany 0, 9);
for(int i = 0;i < howMany;i++)
{
System.out.println(distinctNumber[i]);
}
}
}
I suppose you would need to store the ones that have been generated into an array and compare the new random number to the list to ensure it is unique.
public static void main (String[] args) throws java.lang.Exception
{
// your code goes here
int[] numbers = new int[5];
int tempNumber = 0;
for(int numberCounter = 0; numberCounter < numbers.length;)
{
tempNumber = (int) Math.round((Math.random()*9) +1);
if(!contains(numbers, tempNumber)){
numbers[numberCounter++] = tempNumber;
}
}
}
public static boolean contains(final int[] numbersArray, final int tempNumber) {
for (final int numberFromArray : numbersArray) {
if (numberFromArray == tempNumber) {
return true;
}
}
return false;
}
I notice you did not use an array in your example, so in case you do not know how to use them yet, you could also make 5 variables.
int randomNumber = 0;
int firstNumber = Math.round((Math.random()*9) +1);
int secondNumber = 0;
while(secondNumber == 0){
randomNumber = Math.round((Math.random()*9) +1)l
if(randomNumber != firstNumber){
secondNumber = randomNumber;
}
}
And you could continue making while statements like that. But if you are supposed to know about arrays, you should definitely be using one to store the numbers.
How about this?
package com.se;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class TestRandom {
List<Integer> comp = new ArrayList<>();
int listSize = 20;
public void doTask() {
Random ran = new Random();
int i = 0;
while(i < listSize){
int randomNumber = ran.nextInt(80) + 1;
if(!comp.contains(randomNumber)){
comp.add(randomNumber);
i++;
}
}
for(Integer num : comp){
System.out.println(num);
}
}
public static void main(String[] args) {
TestRandom testRandom = new TestRandom();
testRandom.doTask();
}
}

Categories