BinaryString Comparison Java Beginner - java

I have the current code:
public class Individual{
static int DNA_LOWER_DOMAIN = -100;
static int DNA_UPPER_DOMAIN = 100;
private double fitness = 0.0;
private int x_coordinate = 0;
private String bit_x_coordinate;
Individual(){
int number = DNA_LOWER_DOMAIN + (int)(Math.random() * (DNA_UPPER_DOMAIN - DNA_LOWER_DOMAIN) + 1);
x_coordinate = number;
bit_x_coordinate = Integer.toBinaryString(x_coordinate);
}
public void store_gene(int i, int get_gene) {
bit_x_coordinate = bit_x_coordinate.replace(bit_x_coordinate.charAt(i),(char) get_gene);
}
}
The function that calls store_gene
private static Individual crossover(Individual inhabitant1, Individual inhabitant2){
Individual child = new Individual();
for(int i = 0; i < inhabitant1.size(); i++){
if(Math.random() <= uniformalRate){
child.store_gene(i, inhabitant1.get_gene(i));
}
else{
child.store_gene(i, inhabitant2.get_gene(i));
}
}
return child;
}
anyway when I go to compare using the index of the binary string, I have an out of bounds error because negative integers will be longer than positive ones, any idea how I can solve this problem?

ToBinaryString() doesn't print the leading zeros. You have to pad the String.

Ive solved the problem like this
Individual(){
int number = DNA_LOWER_DOMAIN + (int)(Math.random() * (DNA_UPPER_DOMAIN - DNA_LOWER_DOMAIN) + 1);
x_coordinate = number;
bit_x_coordinate = Integer.toBinaryString(x_coordinate);
if(bit_x_coordinate.length() < 32){
int number_of_bits = bit_x_coordinate.length();
for(int i = 0; i < (32-number_of_bits); i++){
bit_x_coordinate = "0" + bit_x_coordinate;
}
}

Related

Why is my random number generator becoming an unused assignment when using it to input values for 2d array?

I have been making a basic game of battleship and to get the CPU to choose ship locations on a 2d array I am making two random number generators to pick values from 1 to 8 on a separate method. For some reason, the random generators show up as unused and I don't know why. so far this is what I have. If anyone knows what I'm doing wrong please let me know.
//calls method
board3 = CPUship(board3);
//displays result of method
for (int i = 0; i < board3.length; i++) {
for (int j = 0; j < board3.length; j++) {
System.out.print(board3[i][j]);
}
System.out.println("");
}
public static String[][] CPUship(String[][] board3) {
int rowGenerate;
int colGenerate;
boolean valid2 = false;
for (int CPUships = 0; CPUships < 6; CPUships++) {
while (!valid2) {
rowGenerate = (int) (9 * Math.random() + 0);
colGenerate = (int) (9 * Math.random() + 0);
if (!board3[rowGenerate][colGenerate].equalsIgnoreCase("#")) {
board3[rowGenerate][colGenerate] = "#";
valid2 = true;
}
}
valid2 = false;
}
return board3;
}
Here should be a complete code
public static String[][] CPUship(String[][]board3){
int rowGenerate;
int colGenerate;
for (int CPUships = 0; CPUships < 6; CPUships++) {
boolean valid2=false;
while (!valid2){ //instead of valid = false "
rowGenerate = (int) ( 9* Math.random() + 0);
colGenerate = (int) ( 9* Math.random() + 0);
if (!board3[rowGenerate][colGenerate].equalsIgnoreCase ("#")){
board3[rowGenerate][colGenerate]="#";
valid2=true;
}
//removed the valid2=false, it does not "reset" automatically
//removed the CPUships++ ... already done by the for loop
}
}
return board3;
}
or use break instead of the valid boolean
public static String[][] CPUship(String[][]board3){
int rowGenerate;
int colGenerate;
for (int CPUships = 0; CPUships < 6; CPUships++) {
while (true){ //instead of valid = false "
rowGenerate = (int) ( 9* Math.random() + 0);
colGenerate = (int) ( 9* Math.random() + 0);
if (!board3[rowGenerate][colGenerate].equalsIgnoreCase ("#")){
board3[rowGenerate][colGenerate]="#";
break;
}
//removed the valid2=false, it does not "reset" automatically
//removed the CPUships++ ... already done by the for loop
}
}
return board3;
}

Maximum consecutive repeats of a substring in a given string using string library in Java

I'm trying to find the maximum consecutive repeats of a substring in a given string. I'm using substring(), equals(), and length() methods from the String library. However, I don't get the correct result. Here's my code-
public static int maxRepeats(String dna) {
int max = 0;
int count = 0;
for (int i = 0; i < dna.length() - 3; i++) {
String s = dna.substring(i, i + 3);
if (s.equals("CAG")) {
count++;
i += 2;
}
if (!s.equals("CAG")) {
max = count;
count = 0;
}
}
return max;
}
Let for example dna= "CAGCAGCAGTTCAGCAGCAGCAGTTCAGCAGCAG"
Then, max consecutive repeats of substring "CAG" = 4 ---> expected output
But for this substring or any substring, this is the result I get-
max repeats = 0
Would be grateful if someone pointed out where am I wrong :-)
The problem with your code was you are not saving the max value properly . It was getting overridden to value 0 when ever the substring is not equal to "CAG". Instead you only need to set the value of count=0 in else condition and not max =0. Check this code. It should work for you
int max = 0;
int count = 0;
for (int i = 0; i < dna.length() - 3; i++) {
String s = dna.substring(i, i + 3);
if (s.equals("CAG")) {
count++;
i += 2;
} else {
count=0;
}
if (count>max) {
max = count;
}
}
The problem is you are comparing for not equal to CAG and it is not necessary, resulting in you not saving the max correctly. Also, it is not necessary to check for count on each iteration.
public static int maxRepeats(String dna) {
int max = 0;
int count = 0;
for (int i = 0; i <= dna.length() - 3; i++) {
String s = dna.substring(i, i + 3);
if (s.equals("CAG")) {
count++;
i += 2;
} else {
// only check max when CAG is not present.
if (count > max) {
max = count;
}
// but reset counter regardless.
count = 0;
}
}
return Math.max(max,count);
}
Another alternative is to use regular expressions.
public static int maxRepeats(String dna) {
// find the longest repeats of CAG
Matcher m = Pattern.compile("(CAG)*").matcher(dna);
int longest = 0;
while (m.find()) {
String f = m.group();
if (f.length() > longest) {
longest = f.length();
}
}
// the longest string must be divisible by 3 so...
return longest/3;
}
Method 1:
/**
* #param pattern string being searched
* #param text string being searched in
* #return max number of times pattern can be self-appended and remains a
* substring of text
*/
int maxRepeats(String pattern, String text) {
int max = 0;
int count = 0;
int i = 0;
while (i <= text.length() - pattern.length()) {
String s = text.substring(i, i + pattern.length());
if (s.equals(pattern)) {
count++;
i += pattern.length();
} else {
max = Math.max(max, count);
count = 0;
i++;
}
}
return Math.max(max, count);
}
Method 2:
int maxRepeats(String pattern, String text) {
String s = pattern;
int max = 0;
while (s.length() <= text.length()) {
if (text.contains(s)) {
max++;
s += pattern;
} else {
break;
}
}
return max;
}

Numbers too big for variables

I am to find the last ten digits of 1^1 + 2^2 + 3^3.. + 1000^1000.
Is there any way to find this out with pure logic? I think you can't store a number that big.
This question is from a math competition, but I thought of trying to do this in Java.
You don't need to store number that big, you just need the last ten digits. You can store this in a long.
An efficient way to calculate large powers is to multiply and the squares e.g. 19^19 = 19 * 19^2 * 19 ^ 16 = 19 * 19 ^ 2 * 19^2^2^2^2. When you have value which is greater than 10^10 you can truncate the last 10 digits.
BTW the last ten digits of 1000^1000 is 0000000000 and when your add this to your sum, it's the same as adding zero ;)
Edit: While you don't have to use BigInteger, it is simpler to write.
BigInteger tenDigits = BigInteger.valueOf(10).pow(10);
BigInteger sum = BigInteger.ZERO;
for (int i= 1; i <= 1000; i++) {
BigInteger bi = BigInteger.valueOf(i);
sum = sum.add(bi.modPow(bi, tenDigits));
}
sum = sum.mod(tenDigits);
modPow is more efficient than pow with mod seperately as it doesn't have to calculate very large numbers, only the result of the mod.
You could use BigIntegers...
public static void main(String[] args) {
BigInteger acc = BigInteger.ZERO;
for (int k = 1; k <= 1000; k++) {
BigInteger pow = BigInteger.valueOf(k).pow(k);
acc = acc.add(pow);
}
System.out.println(acc);
}
I believe the problem comes from Project Euler, so it's not just a math problem; it should require some computation as well. I don't know how it could be solved with pencil and paper other than by duplicating the calculations a computer might make. I can't see much in the way of a purely mathematical solution. Mathematics can help us optimize the code, however.
To raise a^n, find the binary expansion of n:
n = n_k x 2^k + n_(k-1) x 2^(k-1) + ... + n_0 x 2^0
where n_i = 0 or 1 are the binary digits of n with the zeroth digit on the right. Then
a^n = a^(n_k x 2^k) x a^(n_(k-1) x 2^(k-1)) x ... x a^(n_0 x 2^0).
We can ignore any factors where n_i = 0, since the factor is then a^0 = 1. The process can be written as an algorithm which is O(log n) time and O(1) space (see below).
Next, as a challenge, in order to avoid the use of BigInteger, we can break the calculation into two parts: finding the answer mod 2^10 and finding the answer mod 5^10. In both cases the numbers in the relevant ranges and products of numbers in the relevant ranges fit into longs. The downside is that we have to use the Chinese Remainder Theorem to recombine the results, but it's not that hard, and it's instructive. The hardest part of using the Chinese Remainder Theorem is finding inverses mod m, but that can be accomplished in a straightforward manner using a modification of the Euclidean algorithm.
Asymptotic running time is O(n log n), space is O(1), and everything fits into a few long variables, no BigInteger or other sophisticated library required.
public class SeriesMod1010 {
public static long pow(long a,long n,long m) { // a^n mod m
long result = 1;
long a2i = a%m; // a^2^i for i = 0, ...
while (n>0) {
if (n%2 == 1) {
result *= a2i;
result %= m;
}
a2i *= a2i;
a2i %= m;
n /= 2;
}
return result;
}
public static long inverse(long a, long m) { // mult. inverse of a mod m
long r = m;
long nr = a;
long t = 0;
long nt = 1;
long tmp;
while (nr != 0) {
long q = r/nr;
tmp = nt; nt = t - q*nt; t = tmp;
tmp = nr; nr = r - q*nr; r = tmp;
}
if (r > 1) return -1; // no inverse
if (t < 0) t += m;
return t;
}
public static void main(String[] args) {
long twoTo10 = 1024;
long sum210 = 0;
for (long i=1; i<=1000; i++) {
sum210 += pow(i,i,twoTo10);
sum210 %= twoTo10;
}
long fiveTo10 = 9_765_625;
long sum510 = 0;
for (long i=1; i<=1000; i++) {
sum510 += pow(i,i,fiveTo10);
sum510 %= fiveTo10;
}
// recombine the numbers with the Chinese remainder theorem
long tenTo10 = 10_000_000_000L;
long answer = sum210 * inverse(fiveTo10,twoTo10) * fiveTo10
+ sum510 * inverse(twoTo10,fiveTo10) * twoTo10;
answer %= tenTo10;
System.out.println(answer);
}
}
use BigIntegers :
import java.math.BigInteger;
public class Program {
public static void main(String[] args) {
BigInteger result = new BigInteger("1");
BigInteger temp = new BigInteger("1");
BigInteger I;
for(int i = 1 ; i < 1001 ; i++){
I = new BigInteger(""+i);
for(int j = 1 ; j < i ; j++){
temp = temp.multiply(I);
}
result = result.multiply(temp);
temp = new BigInteger("1");
}
System.out.println(result);
}
}
It can be solved without BigInteger, because you need to store only 10 last digits on every addition or multiplication operation, using % to avoid overflow:
int n = 1000;
long result = 0;
long tenDigits = 10_000_000_000L;
for (int i = 1; i <= n; i++) {
long r = i;
for (int j = 2; j <= i; j++) {
r = (r * i) % tenDigits;
}
result += r;
}
return result % tenDigits;
Complexity is O(N^2), supposed that multiplication runs in constant time.
Answer: 9110846700.
The decimal base uses 0...9 (10 digits) to represent digits, a number that is in the second position right to left represents Digits * base.length^l2rPosition. Using this logics you can create a class that "pretty much does what your primary school teacher told you to, back when we used paper to calculate stuff, but with a baseN number and base-to-base conversions" I have done this class fully functional in C#, but I don't have time to translate it completely to java, this is about the same logics behind java.math.BigInteger. (with less performance I bet for I used a lot of lists >_>" No time to optimize it now
class IntEx {
ArrayList<Integer> digits = new ArrayList<>();
long baseSize = Integer.MAX_VALUE+1;
boolean negative = false;
public IntEx(int init)
{
set(init);
}
public void set(int number)
{
digits = new ArrayList<>();
int backup = number;
do
{
int index = (int)(backup % baseSize);
digits.add(index);
backup = (int) (backup / baseSize);
} while ((backup) > 0);
}
// ... other operations
private void add(IntEx number)
{
IntEx greater = number.digits.size() > digits.size() ? number : this;
IntEx lesser = number.digits.size() < digits.size() ? number : this;
int leftOvers = 0;
ArrayList<Integer> result = new ArrayList<>();
for (int i = 0; i < greater.digits.size() || leftOvers > 0; i++)
{
int sum;
if (i >= greater.digits.size())
sum = leftOvers;
else if(i >= lesser.digits.size())
sum = leftOvers + greater.digits.get(i);
else
sum = digits.get(i) + number.digits.get(i) + leftOvers;
leftOvers = 0;
if (sum > baseSize-1)
{
while (sum > baseSize-1)
{
sum -= baseSize;
leftOvers += 1;
}
result.add(sum);
}
else
{
result.add(sum);
leftOvers = 0;
}
}
digits = result;
}
private void multiply(IntEx target)
{
ArrayList<IntEx> MultiParts = new ArrayList<>();
for (int i = 0; i < digits.size(); i++)
{
IntEx thisPart = new IntEx(0);
thisPart.digits = new ArrayList<>();
for (int k = 0; k < i; k++)
thisPart.digits.add(0);
int Leftovers = 0;
for (int j = 0; j < target.digits.size(); j++)
{
int multiFragment = digits.get(i) * (int) target.digits.get(j) + Leftovers;
Leftovers = (int) (multiFragment / baseSize);
thisPart.digits.add((int)(multiFragment % baseSize));
}
while (Leftovers > 0)
{
thisPart.digits.add((int)(Leftovers % baseSize));
Leftovers = (int) (Leftovers / baseSize);
}
MultiParts.add(thisPart);
}
IntEx newNumber = new IntEx(0);
for (int i = 0; i < MultiParts.size(); i++)
{
newNumber.add(MultiParts.get(i));
}
digits = newNumber.digits;
}
public long longValue() throws Exception
{
int position = 0;
long multi = 1;
long retValue = 0;
if (digits.isEmpty()) return 0;
if (digits.size() > 16) throw new Exception("The number within IntEx class is too big to fit into a long");
do
{
retValue += digits.get(position) * multi;
multi *= baseSize;
position++;
} while (position < digits.size());
return retValue;
}
public static long BaseConvert(String number, String base)
{
boolean negative = number.startsWith("-");
number = number.replace("-", "");
ArrayList<Character> localDigits = new ArrayList<>();
for(int i = number.toCharArray().length - 1; i >=0; i--) {
localDigits.add(number.charAt(i));
}
// List<>().reverse is missing in this damn java. -_-
long retValue = 0;
long Multi = 1;
char[] CharsBase = base.toCharArray();
for (int i = 0; i < number.length(); i++)
{
int t = base.indexOf(localDigits.get(i));
retValue += base.indexOf(localDigits.get(i)) * Multi;
Multi *= base.length();
}
if (negative)
retValue = -retValue;
return retValue;
}
public static String BaseMult(String a, String b, String Base)
{
ArrayList<String> MultiParts = new ArrayList<>();
// this huge block is a tribute to java not having "Reverse()" method.
char[] x = new char[a.length()];
char[] y = new char[b.length()];
for(int i = 0; i < a.length(); i++) {
x[i] = a.charAt(a.length()-i);
}
for(int i = 0; i < b.length(); i++) {
y[i] = a.charAt(a.length()-i);
}
a = new String(x);
b = new String(y);
// ---------------------------------------------------------------------
for (int i = 0; i < a.length(); i++)
{
ArrayList<Character> thisPart = new ArrayList<>();
for (int k = 0; k < i; k++)
thisPart.add(Base.charAt(0));
int leftOvers = 0;
for (int j = 0; j < b.length(); j++)
{
// Need I say repeated characters in base may cause mayhem?
int MultiFragment = Base.indexOf(a.charAt(i)) * Base.indexOf(b.charAt(j)) + leftOvers;
leftOvers = MultiFragment / Base.length();
thisPart.add(Base.charAt(MultiFragment % Base.length()));
}
while (leftOvers > 0)
{
thisPart.add(Base.charAt(leftOvers % Base.length()));
leftOvers = leftOvers / Base.length();
}
char[] thisPartReverse = new char[thisPart.size()];
for(int z = 0; z < thisPart.size();z++)
thisPartReverse[z] = thisPart.get(thisPart.size()-z);
MultiParts.add(new String(thisPartReverse));
}
String retValue = ""+Base.charAt(0);
for (int i = 0; i < MultiParts.size(); i++)
{
retValue = BaseSum(retValue, MultiParts.get(i), Base);
}
return retValue;
}
public static String BaseSum(String a, String b, String Base)
{
// this huge block is a tribute to java not having "Reverse()" method.
char[] x = new char[a.length()];
char[] y = new char[b.length()];
for(int i = 0; i < a.length(); i++) {
x[i] = a.charAt(a.length()-i);
}
for(int i = 0; i < b.length(); i++) {
y[i] = a.charAt(a.length()-i);
}
a = new String(x);
b = new String(y);
// ---------------------------------------------------------------------
String greater = a.length() > b.length() ? a : b;
String lesser = a.length() < b.length() ? a : b;
int leftOvers = 0;
ArrayList<Character> result = new ArrayList();
for (int i = 0; i < greater.length() || leftOvers > 0; i++)
{
int sum;
if (i >= greater.length())
sum = leftOvers;
else if (i >= lesser.length())
sum = leftOvers + Base.indexOf(greater.charAt(i));
else
sum = Base.indexOf(a.charAt(i)) + Base.indexOf(b.charAt(i)) + leftOvers;
leftOvers = 0;
if (sum > Base.length()-1)
{
while (sum > Base.length()-1)
{
sum -= Base.length();
leftOvers += 1;
}
result.add(Base.charAt(sum));
}
else
{
result.add(Base.charAt(sum));
leftOvers = 0;
}
}
char[] reverseResult = new char[result.size()];
for(int i = 0; i < result.size(); i++)
reverseResult[i] = result.get(result.size() -i);
return new String(reverseResult);
}
public static String BaseConvertItoA(long number, String base)
{
ArrayList<Character> retValue = new ArrayList<>();
boolean negative = false;
long backup = number;
if (negative = (backup < 0))
backup = -backup;
do
{
int index = (int)(backup % base.length());
retValue.add(base.charAt(index));
backup = backup / base.length();
} while ((backup) > 0);
if (negative)
retValue.add('-');
char[] reverseRetVal = new char[retValue.size()];
for(int i = 0; i < retValue.size(); i++)
reverseRetVal[i] = retValue.get(retValue.size()-i);
return new String(reverseRetVal);
}
public String ToString(String base)
{
if(base == null || base.length() < 2)
base = "0123456789";
ArrayList<Character> retVal = new ArrayList<>();
char[] CharsBase = base.toCharArray();
int TamanhoBase = base.length();
String result = ""+base.charAt(0);
String multi = ""+base.charAt(1);
String lbase = IntEx.BaseConvertItoA(baseSize, base);
for (int i = 0; i < digits.size(); i++)
{
String ThisByte = IntEx.BaseConvertItoA(digits.get(i), base);
String Next = IntEx.BaseMult(ThisByte, multi, base);
result = IntEx.BaseSum(result, Next, base);
multi = IntEx.BaseMult(multi, lbase, base);
}
return result;
}
public static void main(String... args) {
int ref = 0;
IntEx result = new IntEx(0);
while(++ref <= 1000)
{
IntEx mul = new IntEx(1000);
for (int i = 0; i < 1000; ++i) {
mul.multiply(new IntEx(i));
}
result.add(mul);
}
System.out.println(result.toString());
}
}
Disclaimer: This is a rough translation/localization from a C# study, there are lots of code omitted. This is "almost" the same logics behind java.math.BigInteger (you can open BigInteger code on your favorite designer and check for yourself. If may I be forgetting a overloaded operator behind not translated to java, have a bit of patience and forgiveness, this example is just for a "maybe" clarification of the theory.
Also, just a sidenote, I know it is "Trying to reinvent the wheel", but considering this question has academic purpose I think its fairly rasonable to share.
One can see the result of this study on gitHub (not localized though), I'm not expanding that C# code here for its very extensive and not the language of this question.
This gives the correct answer without excess calculations. A Long is sufficient.
public String lastTen() {
long answer = 0;
String txtAnswer = "";
int length = 0;
int i = 1;
for(i = 1; i <= 1000; i++) {
answer += Math.pow(i, i);
txtAnswer = Long.toString(answer);
length = txtAnswer.length();
if(length > 9) break;
}
return txtAnswer.substring(length-10);
}

Java--Making 10-integer ordering program recursive

I have a simple problem - I need to order 10 numbers. I had an idea how to do this recursively: Make an array of the 10 numbers, take the maximum of the ten numbers, take it out of the array, and repeat the same function with the nine numbers left. The problem was that I did not know how to implement that. I wrote the program, and it works, only it has a part that repeats all the time but with new arrays, because you cannot change the size of the array.
/* package whatever; // don't place package name! */
import java.util.*;
import java.lang.*;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone {
public static void main (String[] args) throws java.lang.Exception {
int[] sortedArray = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
Scanner input = new Scanner(System.in);
int in0 = input.nextInt();
int in1 = input.nextInt();
int in2 = input.nextInt();
int in3 = input.nextInt();
int in4 = input.nextInt();
int in5 = input.nextInt();
int in6 = input.nextInt();
int in7 = input.nextInt();
int in8 = input.nextInt();
int in9 = input.nextInt();
int[] numArray = new int[]{in0, in1, in2, in3, in4, in5, in6, in7, in8, in9};
int numArrayLength = numArray.length;
recursiveSort(numArray);
for (int i=0;i<numArrayLength;i++) {
System.out.print(numArray[i]+",");
}
sortedArray[0] = numArray[0];
System.out.println(" ");
int[] numArray2 = Arrays.copyOfRange(numArray, 1, numArrayLength);
int numArray2Length = numArray2.length;
recursiveSort(numArray2);
for (int j=0;j<numArray2Length;j++) {
System.out.print(numArray2[j]+",");
}
sortedArray[1] = numArray2[0];
System.out.println(" ");
int[] numArray3 = Arrays.copyOfRange(numArray2, 1, numArray2Length);
int numArray3Length = numArray3.length;
recursiveSort(numArray3);
for (int k=0;k<numArray3Length;k++) {
System.out.print(numArray3[k]+",");
}
sortedArray[2] = numArray3[0];
System.out.println(" ");
int[] numArray4 = Arrays.copyOfRange(numArray3, 1, numArray3Length);
int numArray4Length = numArray4.length;
recursiveSort(numArray4);
for (int k=0;k<numArray4Length;k++) {
System.out.print(numArray4[k]+",");
}
sortedArray[3] = numArray4[0];
System.out.println(" ");
int[] numArray5 = Arrays.copyOfRange(numArray4, 1, numArray4Length);
int numArray5Length = numArray5.length;
recursiveSort(numArray5);
for (int k=0;k<numArray5Length;k++) {
System.out.print(numArray5[k]+",");
}
sortedArray[4] = numArray5[0];
System.out.println(" ");
int[] numArray6 = Arrays.copyOfRange(numArray5, 1, numArray5Length);
int numArray6Length = numArray6.length;
recursiveSort(numArray6);
for (int k=0;k<numArray6Length;k++) {
System.out.print(numArray6[k]+",");
}
sortedArray[5] = numArray6[0];
System.out.println(" ");
int[] numArray7 = Arrays.copyOfRange(numArray6, 1, numArray6Length);
int numArray7Length = numArray7.length;
recursiveSort(numArray7);
for (int k=0;k<numArray7Length;k++) {
System.out.print(numArray7[k]+",");
}
sortedArray[6] = numArray7[0];
System.out.println(" ");
int[] numArray8 = Arrays.copyOfRange(numArray7, 1, numArray7Length);
int numArray8Length = numArray8.length;
recursiveSort(numArray8);
for (int k=0;k<numArray8Length;k++) {
System.out.print(numArray8[k]+",");
}
sortedArray[7] = numArray8[0];
System.out.println(" ");
int[] numArray9 = Arrays.copyOfRange(numArray8, 1, numArray8Length);
int numArray9Length = numArray9.length;
recursiveSort(numArray9);
for (int k=0;k<numArray9Length;k++) {
System.out.print(numArray9[k]+",");
}
sortedArray[8] = numArray9[0];
System.out.println(" ");
int[] numArray10 = Arrays.copyOfRange(numArray9, 1, numArray9Length);
int numArray10Length = numArray10.length;
recursiveSort(numArray10);
for (int k=0;k<numArray10Length;k++) {
System.out.print(numArray10[k]+",");
}
sortedArray[9] = numArray10[0];
System.out.println(" ");
sortedArray[2] = numArray3[0];
for (int dasdasd=0;dasdasd<sortedArray.length;dasdasd++) {
System.out.print(sortedArray[dasdasd]+",");
}
}
private static int[] recursiveSort(int numArray[]) {
int numArrayLength = numArray.length;
int maximum = 0;
for (int i=0;i<numArrayLength;i++) {
if (numArray[i] > maximum) {
maximum = numArray[i];
}
}
int indexOfMaximum = -1;
for (int j=0;j<numArrayLength;j++) {
if (numArray[j] == maximum) {
indexOfMaximum = j;
break;
}
}
int temporary = numArray[0];
numArray[0] = numArray[indexOfMaximum];
numArray[indexOfMaximum] = temporary;
return numArray;
}
}
As you can see, the
int[] numArray(n) = Arrays.copyOfRange(numArray(n-1), 1, numArray(n-1)Length);
int numArray(n)Length = numArray(n).length;
recursiveSort(numArray(n));
for (int k=0;k<numArray(n)Length;k++) {
System.out.print(numArray(n)[k]+",");
}
sortedArray[(n-1)] = numArray(n)[0];
System.out.println(" ");
constantly repeats, so there is probably a recursive solution that will work nicely. Maybe I can do something using ArrayLists because their size can change...
Any help will be appreciated!
Thank you!
I suggest a recursive routine that uses an explicit start index for the part that remains to be sorted:
private static void recursiveSort(int[] array, int start) {
if (start < array.length - 1) {
int maximum = array[start];
int maximumIndex = start;
for (int i = start + 1; i < array.length; ++i) {
if (array[i] > maximum) {
maximum = array[i];
maximumIndex = i;
}
}
if (maximumIndex != start) {
int tmp = array[start];
array[start] = array[maximumIndex];
array[maximumIndex] = tmp;
}
recursiveSort(array, start + 1);
}
}
This actually does recursion (unlike your code, which iterates calling a routine named "recursiveSort" but isn't recursive at all). The whole process would be started by calling:
recursiveSort(numArray, 0);
When it returns, the array will be sorted in descending order.
As a general heuristic, when you are struggling with how to make a method recursive, you should consider adding arguments to the method to help with the bookkeeping.
Is this homework or you just need to have the numbers ordered? Java has an easy way to do this if you use ArrayList() instead of array[]. You would just need to call Collections.sort(yourArrayList);
I suggest not trying to make your own sorting algorithm. Many smart people have already done that hard work for you.
The "recursive" sort that you were trying to implement (aka bubble sort which Ted has shown you how to truly make recursive) will work, but it is grossly inefficient. See a comparison of sorting algorithms here.
Below is a demo of the algorithm you were trying to implement compared to a shell sort, one of the fastest sorting algorithms available. The implementation I used was taken from here. Run it and you will see that shell sort is on average 7 to 8 times faster than bubble sort.
public class SortingDemo {
// Methods required for Shell sort
public static void shellSort(Comparable[] a) {
int N = a.length;
int h = 1;
while (h < N/3) h = 3*h + 1;
while (h >= 1) {
for (int i = h; i < N; i++) {
for (int j = i; j >= h && less(a[j], a[j-h]); j -= h) {
exch(a, j, j-h);
}
}
assert isHsorted(a, h);
h /= 3;
}
assert isSorted(a);
}
private static boolean less(Comparable v, Comparable w) {
return (v.compareTo(w) < 0);
}
private static void exch(Object[] a, int i, int j) {
Object swap = a[i];
a[i] = a[j];
a[j] = swap;
}
private static boolean isSorted(Comparable[] a) {
for (int i = 1; i < a.length; i++)
if (less(a[i], a[i-1])) return false;
return true;
}
private static boolean isHsorted(Comparable[] a, int h) {
for (int i = h; i < a.length; i++)
if (less(a[i], a[i-h])) return false;
return true;
}
// Method required for "recursive" sort
private static void recursiveSort(Integer[] array, int start) {
if (start < array.length - 1) {
int maximum = array[start];
int maximumIndex = start;
for (int i = start + 1; i < array.length; ++i) {
if (array[i] > maximum) {
maximum = array[i];
maximumIndex = i;
}
}
if (maximumIndex != start) {
int tmp = array[start];
array[start] = array[maximumIndex];
array[maximumIndex] = tmp;
}
recursiveSort(array, start + 1);
}
}
public static void main(String[] args) {
int desiredArraySize = 1000;
int minSizeOfNumberInArray = 0;
int maxSizeOfNumberInArray = 100;
Integer[] array = new Integer[desiredArraySize]; // Used Integer instead of int to utilize Comparable interface
for(int i = 0; i < array.length; i++) {
int randomInt = (int) Math.random() * (maxSizeOfNumberInArray - minSizeOfNumberInArray);
array[i] = randomInt;
}
long startTime = System.nanoTime();
recursiveSort(array, 0);
long endTime = System.nanoTime();
long recursiveSortTime = endTime - startTime;
System.out.println(String.format("\"Recursive\" sort completed in %d ns", recursiveSortTime));
startTime = System.nanoTime();
shellSort(array);
endTime = System.nanoTime();
long shellSortTime = endTime - startTime;
System.out.println(String.format("Shell sort completed in %d ns", shellSortTime));
System.out.println(String.format("\"Recursive\" sort took %f times longer", (float)recursiveSortTime / (float)shellSortTime));
}
}
When learning programming, both writing your own sorting algorithms and your own recursive algorithms are great exercises for solidifying your understanding of how things work. It's time well invested, even if someone's already done it better.
You noticed a pattern that repeats, and associated that with recursion. When evaluating whether recursion is a good fit, I would encourage you to tweak that thought process with the notion of "divide-and-conquer". If you're solving only one element with each recursion, then your stack will grow very deep, which should be avoided. If you can split your problem into roughly even chunks and process each chunk recursively, then recursion will be a good fit. Otherwise, a loop is already an excellent fit for repeating patterns.

Java sequences print

How do i write simpla Java sequence in my editor (using notepad++)?
I am familiar with the basics but having trouble getting this one to print in my cmd.
int a = 1; a = a + a; a = a + a; a = a + a; ...
This should be what your looking for.
public static void main(String[] args)
{
int startValue = 1;
int numberOfAdditions = 10;
int currentValue = startValue;
for(int i = 0;i<numberOfAdditions;i++)
{
//do opperations here
currentValue = currentValue+currentValue;
//print out value
System.out.println(currentValue);
}
}
Try this:
int a = 1;
for (int i = 0 ; i < MAX_PRINTS ; i++) {
System.out.println(a);
a *= 2;
}
Or if you want to print until a certain value is reached:
int a = 1;
while (a <= MAX_VALUE) {
System.out.println(a);
a *= 2;
}

Categories