how i can optimize this java code? - java

In below code string is passed in a method with numbers separated by space,
now we need to provide sum of smallest two numbers in the string.
public class SumNearZero {
public static int SumNearZero(String s) {
String temp=s;
int t1=0;
for (int i = 0; i <s.length(); i++) {
if(temp.contains(" "))
{
t1++;
temp=temp.substring(temp.indexOf(" ")+1);
}
}
int a[]=new int[++t1];
int index=0;
for(int i=0; i<s.length(); i++)
{
if(s.contains(" "))
{
a[index]=Integer.parseInt(s.substring(0,s.indexOf(" ")));
s=s.substring(s.indexOf(" ")+1);
index++;
}
}
a[index]=Integer.parseInt(s);
for (int i = 0; i < a.length; i++) {
for(int j=0; j<a.length-1; j++)
{
int c=a[j],n=a[j+1];
if(c>n)
{
int t=c;
a[j]=n;
a[j+1]=t;
} } }
int result=a.length>1 ? a[0]+a[1]:a[0];
return result;
}
public static void main(String[] args) {
System.out.println(SumNearZero("35 96 10 20 5"));
}
}
Above code is working fine but i want to reduce the code. if you provide some suggestion regarding this, I'll be happy to learn from you.
Restrictions : use of Collections, predefined methods e.g(String.split(),Arrays.sort()...)

I would suggest you not perform your calculation and display in a constructor, create a static method and invoke it. Next, in that method, create a List of Integer by iterating the substrings generated by splitting your input on one (or more) white space characters. Then, sort the List. Finally, return the sum of the first two elements1. It's also a good to do some error checking for one number (or no numbers). That might look something like
public static int sumNearZero(String s) {
List<Integer> al = new ArrayList<>();
for (String str : s.split("\\s+")) {
al.add(Integer.parseInt(str));
}
if (al.isEmpty()) {
return 0;
}
Collections.sort(al);
if (al.size() == 1) {
return al.get(0);
}
return (al.get(0) + al.get(1));
}
Then invoke it like
public static void main(String[] args) {
System.out.println(sumNearZero("35 96 10 20 5"));
}
I get (as I expected)
15
1once sorted the first two are the minimum, and the last two are the maximum

You can make it faster by using for each loop instead of for loop every time, it is more recommended and faster approach whenever loop is increasing for array, lists etc.
Plus more you can get all numbers in string by using split function which retrives you array of those numbers.and then you can put your logic for getting small numbers.this will reduce counting and increase speed highly in general if you want to learn about optimization then this is definitive guide i suggest you to go through it. and see this answer.

Looks like an exercise, so not giving actual code.
Use String.split and Arrays.sort

Related

trying to print arrays in java [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I had a code I needed to submit and every time I try to run it, I get the same errors over and over again.
Here's the question
Write the following Java methods:
(a). readValues to input ten integer values into an array of integers
TAB from a text file “Values.txt”. This array TAB is passed to the
method as parameter. Assume that the number of students in the file is
equal to the length of the array.
(b). oddValues that takes the array TAB as parameter and returns the
number of odd values found in TAB.
(c). replaceOdd that takes the array TAB as a parameter. It should
replace every odd value in TAB by the sum of all odd values.
Hint: your method must first compute the sum of all odd values.
(d). printValues that takes the array TAB as a parameter and prints
its content on the screen.
(e). main that declares the array TAB and calls the above four
methods.
N.B.: In your program, use the methods and variable names as mentioned
above.
And this is the code:
import java.util.*;
import java.io.*;
public class Finalexam
{
public static void main (String [] args ) throws FileNotFoundException
{
int sum=0;
int [] TAB=new int [10];
ReadValues(TAB);
oddValues(TAB);
replaceOdd(TAB);
printValues(TAB);
System.out.println("The sum is" + sum);
}
public static void ReadValues (int [] TAB)
{
{ int i;
for(i=0; i<10; i++){
Scanner s = new Scanner ("Values.txt") ;
TAB[i]=s.nextInt();
}
}
s.close();
}
public static double oddValues(int[] TAB)
{
int i;
double odd=0;
int fn=0;
for(i=1; i<odd; i++){
while(odd % 2 !=0)
{
odd = fn;
}
break;
}
return fn;
}
public static int replaceOdd(int[] TAB)
{
int re=0;
for(int i=0; i<TAB.length; i++){
re = re/TAB.length;
}
return re;
}
public static void printValues(int[] TAB)
{
int i;
for(i=0; i<10; i++){
System.out.println(TAB[i]+"\t");
}
System.out.println();
}
}
In which part I'm doing wrong? I cant even run it.
Firstly there is a compilation error in your code.
In your method
public static void ReadValues (int [] TAB)
{
{ int i;
for(i=0; i<10; i++){
Scanner s = new Scanner ("Values.txt") ;
TAB[i]=s.nextInt();
}
}
s.close();
}
You have too many extra brackets, well thats not the problem though, the problem is the scanner object s is declared inside the for loop where as you are closing it later outside the loop, since the scope of the variable is not outside the loop, hence the error.
The correct way should be
public static void readValues (int [] tab){
int i;
Scanner s = new Scanner ("Values.txt") ;
for(i=0; i<10; i++){
tab[i]=s.nextInt();
}
s.close();
}
Also there are many thing that will work in your code but is a bad practice or is not following conventions.
Variable names (e.g tab) should always be in camel case. It should only be a capital if it is a constant, which is not in your case.
The method names starts with small letter.
Also you are calling the two methods replaceOdd(TAB) and oddValues(TAB) But the return value is not being used anywhere.
FileNotFoundException will never be thrown
If you closely look at this method below
public static double oddValues(int[] TAB) {
int i;
double odd = 0;
int fn = 0;
for (i = 1; i < odd; i++) {
while (odd % 2 != 0) {
odd = fn;
}
break;
}
return fn;
}
The loop will never execute as odd is 0 so i<odd will always be false. Also the logic for odd is wrong.
public static int replaceOdd(int[] TAB){
int re=0;
for(int i=0; i<TAB.length; i++){
re = re/TAB.length;
}
return re;
}
This method will always return zero, the logic is wrong.
There are many more logical errors. I would suggest you to look into them as well

How do I rearrange an integer so that it is rearranged as its highest possible value in Java? [duplicate]

This question already has answers here:
Scramble each digit of the int a and print out the biggest possible integer
(4 answers)
Closed 2 years ago.
For example, if someone inserts 34603, the output would be 64330. I've started this problem already but I can not think of a solution that works. Also, since this is an assignment, my instructor told me that arrays are not allowed. Here is what I have thus far:
public class loops{
loops(){}
public void biggest(int a){
String as = Integer.toString(a);
int index=0;
int asl = as.length();
while(index<asl){
String num1 = as.substring(index);
String num2 = as.substring((index+1));
int con1 = Integer.parseInt(num1);
int con2 = Integer.parseInt(num2);
if(con1<con2){
System.out.println("con2: "+con2);
}
if(con1>con2){
System.out.println("con1: "+con1);
}
System.out.println("added: "+con1+" "+con2);
index++;
}
}
public static void main(String []args){
loops x = new loops();
x.biggest(4583);
}
}
I would appreciate any and all help/hints, for I am truly lost on this one.
It should be reasonably obvious that the largest possible result is obtained by arranging the digits in descending order. One of the easier and more efficient ways of doing that would be with a counting sort, but the usual forms of that involve using arrays or array-equivalents to accumulate the counts.
So standard Counting Sort is out, along with all standard sort routines aimed at rearranging sequences of items. But you can still take your inspiration from Counting Sort. For example, figure out how many 9 digits are in the input, and form a number from that many 9s. Then figure out how many 8s and append them. Then how many 7s, etc. "Appending" digits to a number can be done arithmetically, so the whole procedure can be done without an array or array equivalent, even if we consider Strings to be array equivalents (as we should).
Details are left as the exercise they are intended to be.
I won't answer the question directly for you but suggest some ideas to help you.
you need to sort the integers in place - ie no arrays/no lists.. just iterate over the integer as a string which you're doing correctly, and progressively swap values so that you end up with a sorted numerical value.
thinking of various sort algorithms, quicksort, mergesort, bubble sort, etc. you effectively pick one of these algorithms and try to implement it.
start with the basic examples for integers to sort and iteratively develop your code to successively generate the correct answer... as test cases try:
no number at all... null
then the empty string ""
then a single digit, so a number 0-9
Next two digits both in order, then out of the sort order
then 3 digits in/out of order
Once you've implemented for 3 digits you should be able to generate your solution for any number of digits.
Note: if you use Integer as the input data type, you will be limited to being able to take a maximum integer value of Integer.MAX_VALUE (which isn't that large). Try to treat the input argument as a String and the individual digits as integers for the comparison (which you are already doing), this way you'll be able to process a much larger input.
import java.util.ArrayList;
import java.util.Collections;
public class loops{
loops(){}
public void biggest(int a){
String as = Integer.toString(a);
int index=0;
int index2=1;
int asl = as.length();
ArrayList<Integer> lista = new ArrayList<Integer>();
while(index<asl){
String num1 = as.substring(index,index2);
int con1 = Integer.parseInt(num1);
lista.add(con1);
index++;
index2++;
}
//order list
Collections.sort(lista);
Collections.reverse(lista);
System.out.println(lista);
//concatenate numbers
}
public static void main(String []args){
loops x = new loops();
x.biggest(34603);
}
}
**anything consult back. **
Ok, I came up with this. It's not the prettiest solution, I recognize that, but it DOES work. Have a look:
public class loops{
public int a,b,c,d,e,f,g,h,i,j;
public loops(){}
public void biggest(int a){
String as = Integer.toString(a);
int index=0;
a = 0;
b = 0;
c = 0;
d = 0;
e = 0;
f = 0;
g = 0;
h = 0;
i = 0;
j = 0;
int asl = as.length();
while(index<asl){
String num3 = as.substring(index,(index+1));
int con3 = Integer.parseInt(num3);
if(con3==9){a++;}
if(con3==8){b++;}
if(con3==7){c++;}
if(con3==6){d++;}
if(con3==5){e++;}
if(con3==4){f++;}
if(con3==3){g++;}
if(con3==2){h++;}
if(con3==1){i++;}
if(con3==0){j++;}
index++;
}
for(int z=0;z<a;z++){
System.out.print("9");
}
for(int y=0;y<b;y++){
System.out.print("8");
}
for(int x=0;x<c;x++){
System.out.print("7");
}
for(int w=0;w<d;w++){
System.out.print("6");
}
for(int v=0;v<e;v++){
System.out.print("5");
}
for(int u=0;u<f;u++){
System.out.print("4");
}
for(int t=0;t<g;t++){
System.out.print("3");
}
for(int s=0;s<h;s++){
System.out.print("2");
}
for(int r=0;r<i;r++){
System.out.print("1");
}
for(int q=0;q<j;q++){
System.out.print("0");
}
public static void main(String []args){
loops x = new loops();
x.biggest(45683408);
}
}
If arrays aren't allowed, then I don't think strings should be allowed either:
static void biggest(int n)
{
long counts=0;
for(; n>0; n/=10)
{
counts += 1L<<((n%10)*4);
}
long result=0;
for (long digit=9; digit>=0; --digit)
{
for(long rep=(counts>>(digit*4))&15; rep>0; --rep)
{
result = result*10 + digit;
}
}
System.out.println(result);
}

Calling method from another class that's an array

I am calling a method from another class. The method contains an integer array. I am trying to stay away from inputting the index manually.
I am trying to search for numbers within a range.
example:
ArrayList: {1,5}, {5,10}, {10,15}
Input: enter 3
Process: search for number within range
output: 1,5
The driver class is storing the objects from the main class called Numbers into ArrayList. The main class have an accessor call getNumbers. getNumbers contains an integer array with 2 elements. The driver is calling getNumbers to validate the entry that users input.
The code below works but I'm told it's consider bad coding to code entering the indexes. I want to know how to output the array from getNumber method without knowing the array length of getNumber?
example of what I have:
for(int i = 0; i < example.size(); i++)
//number is the integer that is inputted.
if(example.get(i).getNumbers()[1] > number &&
example.get(i).getNumbers()[0] <= numbers)
System.out.println(example.get(i));
Should I add another for loop?
example of what I am thinking of:
for(int i = 0; i < example.size(); i++)
for(int j = 0; j < example.get(i).getNumbers.length; j++){
if(example.get(i).getNumbers()[j] > number &&
example.get(i).getNumbers()[j] <= numbers)
System.out.println(example.get(i));
}
}
Edit: Changed how I worded some things and fixed the code of what I think I should do.
The code below works but I'm told it's consider bad coding to code
entering the indexes. I want to know how to output the array from
getNumber method without knowing the array length of getNumber ?
If you don't want to do the validations with array indexes for your first element and second element in the array, then you can solve the problem by modifying your Numbers class as shown below:
(1) Define two int variable members (currently you have only one)
(2) Add a method isInLimits(int input) to validate the range
(3) Override toString() which can be used to print the object as String
Numbers class (modified):
public static class Numbers {
private int firstElement;
private int secondElement;
public int getFirstElement() {
return firstElement;
}
public void setFirstElement(int firstElement) {
this.firstElement = firstElement;
}
public int getSecondElement() {
return secondElement;
}
public void setSecondElement(int secondElement) {
this.secondElement = secondElement;
}
//checks the input is in the range of this object elements
public boolean isInLimits(int input) {
if(input >= firstElement && input < secondElement) {
return true;
} else {
return false;
}
}
#Override
public String toString() {
return "{"+firstElement+","+secondElement+"}";
}
}
Usage of Numbers Class:
public static void main(String[] args) {
int userInput = 10; //get it from user
List<Numbers> example = new ArrayList<>();
//Add Numbers objects to example list
for(int i=0;i< example.size();i++) {
Number numberTemp = example.get(i);
//call Numbers object's isInLimits
if(numberTemp.isInLimits(userInput)) {
System.out.println(numberTemp);
}
}
}

creating java generic data structure

I am building a data structure to learn more about java. I understand this program might be useless.
Here's what I want. I want to create a data structure that store smallest 3 values. if value is high, then ignore it. When storing values than I also want to put them in correct place so I don't have to sort them later. I can enter values by calling the add method.
so let's say I want to add 20, 10, 40, 30 than the result will be [10,20,30]. note I can only hold 3 smallest values and it store them as I place them.
I also understand that there are a lot of better ways for doing this but again this is just for learning purposes.
Question: I need help creating add method. I wrote some code but I am getting stuck with add method. Please help.
My Thinking: we might have to use a Iterator in add method?
public class MyJavaApp {
public static void main(String[] args){
MyClass<Integer> m = new MyClass<Integer>(3);
m.add(10);
m.add(20);
m.add(30);
m.add(40);
}
}
public class MyClass<V extends Comparable<V>> {
private V v[];
public MyClass(int s){
this.v = (V[])new Object[s];
}
public void add(V a){
}
}
Here is a rough sketch of the add method you have to implement.
You have to use the appropriate implementation of the compareTo method when comparing elements.
public void add(V a){
V temp = null;
if(a.compareTo( v[0]) == -1 ){
/*
keeping the v[0] in a temp variable since, v[0] could be the second
smallest value or the third smallest value.
Therefore call add method again to assign it to the correct
position.
*/
temp = v[0];
v[0] = a;
add(temp);
}else if(a.compareTo(v[0]) == 1 && a.compareTo(v[1]) == -1){
temp = v[1];
v[1] = a;
add(temp);
}else if(a.compareTo(v[1]) == 1 && a.compareTo(v[2]) == -1){
temp = v[2];
v[2] = a;
add(temp);
}
}
Therefore the v array will contain the lowerest elements.
Hope this helps.
A naive, inefficient approach would be (as you suggest) to iterate through the values and add / remove based on what you find:
public void add(Integer a)
{
// If fewer than 3 elements in the list, add and we're done.
if (m.size() < 3)
{
m.add(a);
return;
}
// If there's 3 elements, find the maximum.
int max = Integer.MIN_VALUE;
int index = -1;
for (int i=0; i<3; i++) {
int v = m.get(i);
if (v > max) {
max = v;
index = i;
}
}
// If a is less than the max, we need to add it and remove the existing max.
if (a < max) {
m.remove(index);
m.add(a);
}
}
Note: this has been written for Integer, not a generic type V. You'll need to generalise. It also doesn't keep the list sorted - another of your requirements.
Here's an implementation of that algorithm. It consists of looking for the right place to insert. Then it can be optimized for your requirements:
Don't bother looking past the size you want
Don't add more items than necessary
Here's the code. I added the toString() method for convenience. Only the add() method is interesting. Also this implementation is a bit more flexible as it respects the size you give to the constructor and doesn't assume 3.
I used a List rather than an array because it makes dealing with generics a lot easier. You'll find that using an array of generics makes using your class a bit more ugly (i.e. you have to deal with type erasure by providing a Class<V>).
import java.util.*;
public class MyClass<V extends Comparable<V>> {
private int s;
private List<V> v;
public MyClass(int s) {
this.s = s;
this.v = new ArrayList<V>(s);
}
public void add(V a) {
int i=0;
int l = v.size();
// Find the right index
while(i<l && v.get(i).compareTo(a) < 0) i++;
if(i<s) {
v.add(i, a);
// Truncate the list to make sure we don't store more values than needed
if(v.size() > s) v.remove(v.size()-1);
}
}
public String toString() {
StringBuilder result = new StringBuilder();
for(V item : v) {
result.append(item).append(',');
}
return result.toString();
}
}

Java program HugeInteger

I am writing a program that will add 2 arrays that are 40 elements long together. I have to keep the add() method as a HugeInteger (can’t change it to a integer) so when I try to return the sum of the 2 integers it gives me “HugeInteger#77e1ee5d”. Could someone let me know what this means and also tell me how I could fix it.
Thank you
public class HugeInteger {
private int[] integer ;
public HugeInteger(int num[]){
integer =new int [40];
for(int x=1; x<=39; x++){
integer[x]= num[x];
}
}
public void parse(String s){
for(int i=0; i<=s.length(); i++){
integer[i]=Integer.parseInt(s.substring(i,i+1));
}
}
public HugeInteger add(HugeInteger a1){
HugeInteger sum = new HugeInteger(integer);
int cary=0;
for (int i=39; i>=0; i--){
sum.integer[i]=integer[i]+a1.integer[i]+cary;
if(sum.integer[i]>=10){
cary=1;
sum.integer[i]-=10;
}else{
cary=0;
}
}
return sum;
}}
//This is my test program
public class HugeIntegerTest {
public static void main(String[] args) {
int []num={1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
HugeInteger hi= new HugeInteger(num);
System.out.println("Addition: "+hi.add(hi));
}
}
That's the output of the default Object.toString() method. You need to override toString and provide a better implementation yourself. An example:
#Override
public String toString() {
StringBuilder builder = new StringBuilder(integer.length);
for(int digit : integer) {
builder.append(digit);
}
return builder.toString();
}
Note that this implementation does not trim leading zeros, i.e. it will print "0000...000123" instead of just "123". This is left as an exercise for the reader, erm, programmer. ;-)
Another tip: in your constructor, your loop should start at i=0. Otherwise the most significant digit (integer[0]) will always be zero, for example your test program would give you a HugeInteger representing 0 instead of 1039.
You have to write your own version of the toString() for HugeInteger to make it display correctly.

Categories