I need to do find values 10 different times or until the value of difference is found twice. Im not really sure how to break the loop if found.
Here goes the code:
public class Algorithm {
private static int small; //global field so it is usable in zeros method
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
int number = 0;
// object array to use collections class
Integer [] digit = new Integer [4];
// loop for handling 10 different numbers
for (int index=0; index<10; index++){
number = random();
String smaller =""; String bigger=""; // strings used to display zeros/ easier processing
for (int i = 3; i >= 0; i--) {
digit[i] = number % 10;
number /= 10;
}
// prints initial random number
System.out.println(digit[0] + " " +digit[1] + " " +
digit[2]+ " "+ digit[3] + " Random Number");
// sorts the digits increasingly
Arrays.sort(digit);
// adds the numbers to the smaller string
for (int i=0; i <digit.length; i++){
smaller += digit[i];
}
// convert string to int
int small = Integer.parseInt(smaller);
String zerosNr = null;
zerosNr = zeros();
System.out.printf(" smaller " +zerosNr, small );
// Reverse sort order and adds results to bigger for displaying
Arrays.sort(digit, Collections.reverseOrder());
for (int i=0; i < digit.length; i++){
bigger += digit[i];
}
int big = Integer.parseInt(bigger);
System.out.println("bigger " + big);
int difference = 0;
int [] copy;
copy = new int[11];
difference = big - small;
copy[index] = big - small;
// here i tried to do it
System.out.println( index + " Difference "+ difference);
if (difference == copy[index+1])
break;
}
}
//method that creates random numbers
public static int random(){
final int n = 9999;
Random rad = new Random();
int number = rad.nextInt(n);
return number;
}
//method that adds zeros where necesarry to smaller
public static String zeros(){
String zerosNr = null;
if (small < 1000)
return " %04d\n ";
else if (small < 100)
return " %03d\n ";
else
return " %02d\n ";
}
}
A problem with your approach is that you're trying to break based on "future" values, i.e. when you compare difference == copy[index+1] you have not yet populated copy[index+1]. You just haven't gotten that far yet.
Instead, you should be comparing difference to past values of copy. And you'll have to compare each difference to all preceding values of copy. So something like:
boolean iShouldBreak = false;
for (int j = 0; j < index; j++) {
if (difference == copy[j]) {
iShouldBreak = true;
}
}
if (iShouldBreak)
{
break;
]
You'll want to use a label:
For example:
OUTERFOR: for(Object1 object1: objects){
for(Object2 object2: object1.getMoreObjects()){
if( object2.isWhatever()) {
break OUTERFOR;
}
}// inner for loop ends here
}// outer for loop ends here
Related
I am having a lot of trouble finding an efficient solution to Problem #9 in the UCF HSPT programming competition. The whole pdf can we viewed here, and the problem is called "Chomp Chomp!".
Essentially the problem involves taking 2 "chomps" out of an array, where each chomp is a continuous chain of elements from the array and the 2 chomps have to have at least element between them that's not "chomped." Once the two "chomps" are determined, the sum of all the elements in both "chomps" has to be a multiple of the number given in the input. My solution essentially is a brute-force that goes through every possible "chomp" and I tried to improve the speed of it by storing previously calculated sums of chomps.
My code:
import java.util.Arrays;
import java.util.HashMap;
import java.util.Scanner;
public class chomp {
static long[] arr;
public static long sum(int start, int end) {
long ret = 0;
for(int i = start; i < end; i++) {
ret+=arr[i];
}
return ret;
}
public static int sumArray(int[] arr) {
int sum = 0;
for(int i = 0; i < arr.length; i++) {
sum+=arr[i];
}
return sum;
}
public static long numChomps(long[] arr, long divide) {
HashMap<String, Long> map = new HashMap<>();
int k = 1;
long numchomps = 0;
while(true) {
if (k > arr.length-2) break;
for (int i = 0; i < arr.length -2; i++) {
if ((i+k)>arr.length-2) break;
String one = i + "";
String two = (i+k) + "";
String key1 = one + " " + two;
long first = 0;
if(map.containsKey(key1)) {
//System.out.println("Key 1 found!");
first = map.get(key1).longValue();
} else {
first = sum(i, i+k);
map.put(key1, new Long(first));
}
int kk = 1;
while(true){
if (kk > arr.length-2) break;
for (int j = i+k+1; j < arr.length; j++) {
if((j+kk) > arr.length) break;
String o = j + "";
String t = (j+kk) + "";
String key2 = o + " " + t;
long last = 0;
if(map.containsKey(key2)) {
//System.out.println("Key 2 found!");
last = map.get(key2).longValue();
} else {
last = sum(j, j+kk);
map.put(key2, new Long(last));
}
if (((first+last) % divide) == 0) {
numchomps++;
}
}
kk++;
}
}
k++;
}
return numchomps;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
int n = Integer.parseInt(in.nextLine());
for(int i = 1; i <= n; i++) {
int length = in.nextInt();
long divide = in.nextLong();
in.nextLine();
arr = new long[length];
for(int j = 0; j < length; j++) {
arr[j] = (in.nextLong());
}
//System.out.println(arr);
in.nextLine();
long blah = numChomps(arr, divide);
System.out.println("Plate #"+i + ": " + blah);
}
}
}
My code gets the right answer, but seems to take too long, especially for large inputs when the size of the array is 1000 or greater. I tried to improve the speed of my algorithm my storing previous sums calculated in a HashMap, but that didn't improve the speed of my program considerably. What can I do to improve the speed so it runs under 10 seconds?
The first source of inefficiency is constant recalculation of sums. You should make an auxiliary array of partial sums long [n] partial;, then instead of calling sum(i, i + k) you may simply do partial[i + k] - partial[i].
Now the problem reduces to finding indices i<j<k<m such that
(partial[j] - partial[i] + partial[m] - partial[k]) % divide == 0
or, rearranging terms,
(partial[j] + partial[m]) % divide == (partial[i] + partial[k]) % divide
To find them you may consider an array of triples (s, i, j) where s = (partial[j] - partial[i]) % divide, stable sort it by s, and inspect equal ranges for non-overlapping "chomps".
This approach improves performance from O(n4) to O(n2 log n). Now you shall be able to improve it to O(n log n).
I'm not sure if this is the best way to ask my question.
Basically, I have a 2D array that is being built from a text file.
It takes the first two int's for the dimensions. Then fills the array with the remaining data. That part is working fine.
In my array, I need to add each value with each adjacent value. To determine which value, when added with all of its adjacent values, is the highest. I need to do the reverse also, to find the lowest.
What kind of loop or function could I use to accomplish this? I'l create a small example below.
2 4 3 7 8
1 5 7 9 2
2 9 2 5 7
So the 2 would become a 7, the 4 would become a 14, and so on. After the math is done I need to detect which coordinate in the array is the largest number.
For simplicity, lets use the example you provided. The array is 5 by 3. Lets call the array data Try this
int totals[5][3];
for(int x = 0;x<5;x++){
for(int y = 0;y<5;y++){
int total = data[x][y]
if(x>0){
total+= data[x-1][y];
}
if(x<4){
total+= data[x+1][y];
}
if(y>0){
total+= data[x][y-1];
}
if(y<2){
total+= data[x][y+1];
}
totals[x][y] = total;
}
}
Then loop through the arrays and compare the values.
My approach would be the following:
public int largeNeighbor(int[][] numbers) {
int max = 0;
for (int i = 0; i < numbers.length ; i++) {
for (int j = 0; j < numbers[0].length; j++) {
int temp = numbers[i][j];
if (i > 0) {
temp += numbers[i-1][j];
}
if (i < numbers.length - 1) {
temp += numbers[i+1][j];
}
if (j > 0) {
temp += numbers[i][j-1];
}
if (j < numbers[0].length - 1) {
temp += numbers[i][j+1];
}
if (temp > max) {
max = temp;
}
}
}
return max;
}
When given a 2D integer array, the method will compare every value with added neighbors to the current max value.
You explained your situation well but in future questions you should include what you already have in small blocks of code. :)
I did this for fun. Hope someone enjoys.
import java.lang.ArrayIndexOutOfBoundsException;
import java.util.Random;
public class HelloWorld{
int smallest = 10000;
int largest = -1;
int xCoords_small = -1;
int yCoords_small = -1;
int xCoords_large = -1;
int yCoords_large = -1;
//Make it as big as you want!!!!!
int iSize = 5;
int jSize = 3;
int[][] totals = new int[iSize][jSize];
int[][] yourNumbers = new int[iSize][jSize];
Random r = new Random();
//Initializes the array. With random numbers. Yours would read in the
//the file here and initialize the array.
public HelloWorld(){
for(int i = 0; i < iSize; i++){
for(int j = 0; j < jSize; j++){
yourNumbers[i][j] = r.nextInt(10);
}
}
}
//Calculates the total and whether or not it's the largest number and
//tracks position in array and the total number.
//It has crumby error catching but this way you can make your array
//as big as you want without needing to change anything but the two
//two size variables.
public void calculate(){
for(int i = 0; i < iSize; i++){
for(int j = 0; j < jSize; j++){
int total = 0;
try{
total += yourNumbers[i][j];
}catch(ArrayIndexOutOfBoundsException ex ){
//do nothing
}
try{
total += yourNumbers[i-1][j];
}catch(ArrayIndexOutOfBoundsException ex){
//do nothing
}
try{
total += yourNumbers[i][j-1];
}catch(ArrayIndexOutOfBoundsException ex){
//do nothing
}
try{
total += yourNumbers[i+1][j];
}catch(ArrayIndexOutOfBoundsException ex){
//do nothing
}
try{
total += yourNumbers[i][j+1];
}catch(ArrayIndexOutOfBoundsException ex){
//do nothing
}
totals[i][j] = total;
if(total > largest){
largest = total;
xCoords_large = i;
yCoords_large = j;
}
if(total < smallest){
smallest = total;
xCoords_small = i;
yCoords_small = j;
}
System.out.println(total);
}
}
System.out.println(largest + " = Largest Total and it's beginning number in your 2D array. " + xCoords_large+ "," + yCoords_large+ " Its value = " + yourNumbers[xCoords_large][yCoords_large]);
System.out.println(smallest + " = Smallest Total and it's beginning number in your 2D array. " + xCoords_small + "," + yCoords_small + " Its value = " + yourNumbers[xCoords_small][yCoords_small]);
}
public static void main(String []args){
HelloWorld hw = new HelloWorld();
hw.calculate();
}
}
I've recently been teaching myself Java and I made a piece of code to produce Pascal's triangle. However, I can't get it to print out properly in a triangle. I can't figure out how to take into account numbers with multiple digits. Here's what I have so far:
public class Pas{
public static void main(String[] args){
pas(20);
}
public static void pas(int rows){
for(int i = 0; i < rows; i++){
String spaces = "";
int counter = (rows + 30)/2 - i;
for(int f = counter; f > 0; f --){
spaces += " ";
}
System.out.print(spaces);
for(int j = 0; j <= i; j++){
System.out.print( ncr(i, j) + " ");
}
System.out.println();
}
}
public static long ncr(int n, int r){
return fact(n) / (fact(r) * fact(n - r));
}
public static long fact(int n){
long ans = 1;
for(int i = 2; i <= n; i++){
ans *= i;
}
return ans;
}
Please keep in mind I'm a complete beginner and have never had any actual instruction. Everything I know is from the internet and messing around in Eclipse.
So the problem you're having is with spacing.
You are using always one space after a number, which is a problem because one number can be of length 1 - i.e: 1,2,3,4,5,6,7,8,9 - and another can be of length 5 - i.e. 31824. Because of that your triangle is wider on the right side.
To change that you have to reserve equal space for all your numbers - so if your biggest number is 184756 then for every number you print you have to reserve place for 6 digits and 1 empty space after them.
Also your initial spacing is not related to the number of rows, which in general can generate problems (if you would like to make triangle bigger than 30 - your current constant).
So there are two places where I would suggest changes:
First is this (1):
int counter = (rows + 30)/2 - i;
Here 30 is a constant that works for your 20 dimention triangle, but it's not elegant and won't work for bigger triangles. So I would suggest something like this (2):
int counter = (maxNumberLength*(numberOfRows - i))/2;
maxNumberLength is the maximum length the numbers in your triangle can get. How to calculate it? I'have estimated like that (3):
Math.pow(2d, numberOfRows.doubleValue());
This power will always be bigger than the biggest value in the triangle, but not by much. You can do it differently - it's first that came to my mind.
So back to (2)... the numberOfRows is the number of rows in the triangle. You substract i before multiplying to get the initial space maximumNumberLength/2 smaller in every row (so that it has a left slope).
The second thing that I would suggest changing is this:
System.out.print( ncr(i, j) + " ");
That's the most important part as you always add 1 space. If maximum number length is 6, then you should add 6 spaces after 1, 5 spaces after 20 and so on. Thats why I suggest creating a method that would return you the number of spaces you need (4):
private String spaces(final Long number, final int maxNumberLength)
{
StringBuilder spaces = new StringBuilder("");
for (int i = 0; i<maxNumberLength - number.toString().length(); i++)
{
spaces.append(" ");
}
return spaces.toString();
}
In (4) you take number as first param (that's the number that is to be followed by spaces) and maxNumberLength from (3). This way all of your numbers would take the same amount of spaces in the output. I build the spaces with StringBuilder which is more effective for String concatenation.
So that's it - two changes and it should work.
I attach my full code so if you need you can test it:
public class TraingleTest
{
private final BufferedReader input;
private Integer numberOfRows;
public static void main(String args[])
{
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
new TraingleTest(input).run();
}
private TraingleTest(final BufferedReader input)
{
this.input = input;
}
private void run()
{
boolean validNumber = false;
System.out.print("Please enter number of rows for Pascals Triangle: ");
do
{
String usersInput = readUserInput();
validNumber = validateInput(usersInput);
} while (!validNumber);
makeTriangle();
}
private String readUserInput()
{
try
{
return input.readLine();
}
catch (final IOException e)
{
System.out.print("Error while reading input. Please try one more time: ");
return "";
}
}
private boolean validateInput(final String input)
{
try
{
Integer inputValue = Integer.parseInt(input);
if (inputValue > 2 && inputValue < 22)
{
numberOfRows = inputValue;
return true;
}
System.out.print("Value must be an integer between 3 and 21. Please insert valid number: ");
return false;
}
catch (final Exception e)
{
System.out.print("Error while parsing input. Please insert valid number: ");
}
return false;
}
private void makeTriangle()
{
int maxNumberLength = Double.valueOf(Math.pow(2d, numberOfRows.doubleValue())).toString().length();
for(int i = 0; i < numberOfRows; i++){
String spaces = "";
int counter = (maxNumberLength*(numberOfRows - i))/2;
for(int f = counter; f > 0; f --)
{
spaces += " ";
}
System.out.print(spaces);
for(int j = 0; j <= i; j++)
{
long number = ncr(i, j);
System.out.print(number + spaces(number, maxNumberLength));
}
System.out.println();
}
}
private String spaces(final Long number, final int maxNumberLength)
{
StringBuilder spaces = new StringBuilder("");
for (int i = 0; i<maxNumberLength - number.toString().length(); i++)
{
spaces.append(" ");
}
return spaces.toString();
}
public long ncr(int n, int r)
{
return fact(n) / (fact(r) * fact(n - r));
}
public long fact(int n)
{
long ans = 1;
for(int i = 2; i <= n; i++)
{
ans *= i;
}
return ans;
}
}
// I have not inputted the rows you can just give an input statement and input no of rows
public class PascalTriangle {
public static void main(String[] args) {
int rows = 10;
for(int i = 0; i < rows; i++) {
int number = 1;
System.out.format("%"+(rows-i)*2+"s","");
for(int j = 0; j <= i; j++) {
System.out.format("%4d",number);
number = number * (i - j) / (j + 1);
}
System.out.println();
}
}
}
this code will help you
int rows = 10;
for(int i =0;i<rows;i++) {
int number = 1;
System.out.format("%"+(rows-i)*2+"s","");
for(int j=0;j<=i;j++) {
System.out.format("%4d",number);
number = number * (i - j) / (j + 1);
}
System.out.println();
}
The simplest thing to is to decree that every number you output will use a set number of characters, and to add extra blanks if necessary when outputting each number. For example, you can decide that each number will take 4 characters (if all the numbers are 9999 or less--actually, with Pascal's triangle with 20 rows, you'll need at least 5 characters). Then you'll need to adjust the number of spaces you print out in each row of the triangle.
To convert a number to a 4-character string where the number is pushed over to the right of the 4-character "box", and you add blanks on the left if necessary, use String.format:
String output = String.format("%4d", number);
If you want the number to be at the left of the "box",
String output = String.format("%-4d", number);
If you want the number to be centered in the "box", this is harder. Here's a method that will pad a string on both sides with blanks, making the padding as close to equal on both sides as possible:
public static String center(int desiredLength, String input) {
if (input.length() >= desiredLength) {
return input;
}
int leftPadding = (desiredLength - input.length()) / 2;
int rightPadding = desiredLength - input.length() - leftPadding;
StringBuilder result = new StringBuilder();
for (int i = 0; i < leftPadding; i++) {
result.append(' ');
}
result.append(input);
for (int i = 0; i < rightPadding; i++) {
result.append(' ');
}
return result.toString();
}
and then you could say
System.out.print(center(4, Integer.toString(number)));
or, if number is a long,
System.out.print(center(4, Long.toString(number)));
(P.S. Instead of StringBuilder, you could declare result to be a String and use things like result += " " like you did in your original question. That would work just as well, except maybe a few nanoseconds slower.)
package myjavapractice;
import java.util.Arrays;
import java.util.Scanner;
public class pascaltriangle
{
public static void main(String args[]) {
int i;
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
int[][] pascal=new int[n][];
for(i=0;i<n;i++)
{
pascal[i]=new int[i+1];
}
pascal[0][0]=pascal[1][0]=pascal[1][1]=1;
for(int j=2;j<n;j++) {
pascal[j]=getNextRow(pascal[j]);
}
//print
for(int k=0;k<n;k++)
{
System.out.println(Arrays.toString(pascal[k]));
}
}
static int[] getNextRow(int[] p)
{
int[] current = new int[p.length];//row
System.out.println("length "+p.length);
current[0]=current[current.length-1]=1;//colmn
for(int m=1;m<current.length-1;m++)
{
current[m]=p[m]+p[m-1];
System.out.println("pof m is"+p[m]);
}``
return current;
}
}
I'm doing a project in which I must generate an array list the size of a user input(in this case i chose 4), with random numbers between -1000 and 1000. Then I have to have it do a selection sort and display both the unsorted numbers in output1 and the sorted numbers in output2 Heres what I have thus far
ArrayList <Integer> unSortedNumbers = new ArrayList <Integer>();
Integer [] numberSort;
...
private void SortActionPerformed(java.awt.event.ActionEvent evt) {
String input, sortedNumberOutput = "";
int int1, int2 = 0, min = -1000, max = 1000, j, minimum, temp = 0;
input = Input.getText();
int1 = Integer.parseInt(input);
Random number = new Random();
while (int2 < int1) {
for (int i = 0; i < int1; i++) {
int randomInt = number.nextInt(max - min + 1) + min;
unSortedNumbers.add(randomInt);
int1--;
}
}
numberSort = new Integer[unSortedNumbers.size()];
unSortedNumbers.toArray(numberSort);
for (int i = 0; i < numberSort.length; i++) {
sortedNumberOutput += numberSort[i] + (i != numberSort.length ? "," : "");
}
if (Selection.isSelected() && Ascending.isSelected()) {
for (int i = 0; i < numberSort.length - 1; i++) {
minimum = numberSort[i];
for (j = i + 1; j <= numberSort.length - 1; j++) {
if (minimum > numberSort[j]) {
numberSort[temp] = numberSort[i];
numberSort[i] = numberSort[j];
numberSort[j] = numberSort[temp];
}
}
}
}
Output1.setText("Unsorted Numbers " + unSortedNumbers);
Output2.setText("Sorted Numbers " + numberSort);
unSortedNumbers.clear();
numberSort = null;
}
So when I run that, the unSortedNumbers are displayed properly in output1, but instead of displaying the sorted numbers in output2, it displays this :
Sorted Numbers [Ljava.lang.Integer;#7a279c
I'm not sure why this is happening, my could is probably wrong somewhere, If you can help, thank you!
What you are seeing is the result of the default toString() method being called on an array object. [Ljava.lang.Integer tells you it is an array of Integers and the #7a279c gives you the hex string of the hashcode. Do as ZouZou suggests and use Arrays.toString(unSortedNumbers);
First of all, I have seen a similar question relating to C++, but I didn't quite understand it - plus my question is about Java.
Basically I have coded two methods that can use SelectionSort and BubbleSort on an array parsed in. While I believe I have the methods working correctly (I have run tests and they all have sorted the numbers in ascending order), I am not sure if I am counting the number of comparisons and number swaps correctly. If someone is able to test my code below and offer some feedback, I will be very grateful.
Note: I can zip up my Java project files and send them to anyone if needed.
BubbleSort method:
public String bubbleSort(int[] numbers)
{
System.out.println("******|Bubble Sort|******");
StringBuilder originalArray = new StringBuilder();
for(int i = 0; i <= numbers.length - 1; i++)
{
originalArray.append(numbers[i] + " ");
}
System.out.println("Original array: " + originalArray);
int temp; // temporary variable
//Set boolean variable to true,
//to allow the first pass.
boolean pass = true;
int comparisons = 0;
int swaps = 0;
//While a pass can be made,
while(pass)
{
//Set the boolean value to false,
//indicating a number swap could
//be made.
pass = false;
for(int i = 0; i < numbers.length - 1; i++)
{
//increment the number of comparisons by 1.
comparisons++;
if(numbers[i] > numbers[i+1])
{
temp = numbers[i];
numbers[i] = numbers[i + 1];
numbers[i+1] = temp;
//increment the amount of swaps made by 1,
//to put numbers in correct order.
swaps++;
pass = true;
}
}
}
//Create a StringBuilder object - to hold
//the output of sorted numbers.
StringBuilder sb = new StringBuilder();
//Loop through the now sorted array - appending
//each subsequent number in the array to the
//StringBuilder object.
for(int i = 0; i < numbers.length; i++)
{
sb.append(numbers[i] + " ");
}
//Return the final results of the sorted array.
return "Sorted Array (asc): " + sb.toString() + "\nComparisons made: " + comparisons
+ "\nSwaps made: " + swaps;
}
SelectionSort method
public String selectionSort(int[] numbers)
{
System.out.println("******|Selection Sort|******");
StringBuilder originalArray = new StringBuilder();
int comparisons = 0;
int swaps = 0;
for(int i = 0; i <= numbers.length - 1; i++)
{
originalArray.append(numbers[i] + " ");
}
System.out.println("Original array: " + originalArray);
//Declare variable to hold first element
int first;
//declare temporary variable, to be used in
//swapping integers.
int temp;
for(int x = numbers.length - 1; x > 0; x--)
{
first = 0;
comparisons++;
for(int y = 1; y <= x; y++)
{
//comparisons++;
if(numbers[y] > numbers[first])
{
first = y;
//comparisons++;
swaps++;
}
temp = numbers[first];
numbers[first] = numbers[x];
numbers[x] = temp;
//swaps++;
}
}
//Create a StringBuilder object - to hold
//the output of sorted numbers.
StringBuilder sb = new StringBuilder();
//Loop through the now sorted array - appending
//each subsequent number in the array to the
//StringBuilder object.
for(int i = 0; i < numbers.length; i++)
{
sb.append(numbers[i] + " ");
}
//Return the final results of the sorted array.
return "Sorted Array (asc): " + sb.toString() + "\nComparisons made: " + comparisons
+ "\nSwaps made: " + swaps;
}
For BUBBLE SORT:
Key comparisons -> (n*(n-1))/2
Item assignments (swaps) -> 3*(n-1)
For SELECTION SORT:
Key comparisons -> (n*(n-1))/2 (same as bubble)
Item assignments (swaps) -> (n*(n-1))/4
(Note that n is the number of your array size)