This question already has an answer here:
What does "Incompatible types: void cannot be converted to ..." mean?
(1 answer)
Closed 3 years ago.
I need to write a Java program for a course I'm taking which looks for genes in a strand of DNA.The Issue I am having is that from the test method, I need to pass printAllgenes(a) to the void printAllgenes method. In the test method I've tried setting 'int a' to 'String a', but in either case an error when compiling explaining that void cannot be converted to int or String. I'm sure its obvious, but I'm very new to programming, so please pardon my ignorance! Thank you.
import java.io.*;
import edu.duke.*;
public class FindProtein {
public void test() {
String a = "atg aaa tab tag atg aaa tga aat ag";
int b = printAllgenes(a);
System.out.println("DNA string is " + a);
System.out.println("Gene found is " + b);
}
public void printAllgenes(String dna) {
int sp = 0; //start point
while (true) {
int start = dna.indexOf("atg,sp");
if (start == -1) {
break;
}
int stop = findStopIndex(dna, start + 3);
if (stop != dna.length()) {
System.out.println(dna.substring(start, stop + 3));
sp = stop + 3;
} else {
sp = sp + 3;
}
}
}
public int findStopIndex(String dna, int index) {
int tga = dna.indexOf("tga", index);
if (tga == -1 || (tga - index) % 3 != 0) {
tga = dna.length();
}
int taa = dna.indexOf("taa", index);
if (taa == -1 || (taa - index) % 3 != 0) {
taa = dna.length();
}
int tag = dna.indexOf("tag", index);
if (tag == -1 || (tga - index) % 3 != 0) {
tag = dna.length();
}
return Math.min(tga, Math.min(taa, tag));
}
}
Try to use just:
printAllgenes(a);
Because printAllgenes method doesn't have any type of return statement.
change return type void to int It will return your count whatever u want to return from printAllgenes(String dns) Method. You will get a int return which will initialize you variable b that is being displayed on Console.
public int printAllgenes(String dna){
int sp = 0; //start point
while (true){
int start = dna.indexOf("atg,sp");
if (start==-1){
break;
}
int stop = findStopIndex(dna,start+3);
if (stop!=dna.length()){
System.out.println(dna.substring(start,stop+3));
sp=stop+3;
}
else{
sp=sp+3;
}
}
return sp;
}
Now Your Test Method Implementation will work fine...
public void test(){
String a= "atg aaa tab tag atg aaa tga aat ag";
int b = printAllgenes(a);
System.out.println("DNA string is " +a);
System.out.println("Gene found is "+b);
}
Thank you..
Related
This is a probable answer of my question in stack overflow.Integer to word conversion
At first I have started with dictionary. Then I came to know it is obsolete. So now I use Map instead of dictionary. My code is work well for number till Millions. But the approach I take here is a naive approach. The main problem of this code is
First: Huge numbers of variable use
2nd: Redundant code block as per program requirement
3rd: Multiple if else statement
I am thinking about this problems
Solution for 2nd problem: using user define function or macros to eliminate redundant code block
Solution for 3rd problem: Using switch case
My code:
public class IntegerEnglish {
public static void main(String args[]){
Scanner in=new Scanner(System.in);
System.out.println("Enter the integer");
int input_number=in.nextInt();
Map<Integer,String> numbers_converter = new HashMap<Integer,String>();
Map<Integer,String> number_place = new HashMap<Integer,String>();
Map<Integer,String> number_2nd = new HashMap<Integer,String>();
numbers_converter.put(0,"Zero");
numbers_converter.put(1,"One");
numbers_converter.put(2,"Two");
numbers_converter.put(3,"Three");
numbers_converter.put(4,"Four");
numbers_converter.put(5,"Five");
numbers_converter.put(6,"Six");
numbers_converter.put(7,"Seven");
numbers_converter.put(8,"Eight");
numbers_converter.put(9,"Nine");
numbers_converter.put(10,"Ten");
numbers_converter.put(11,"Eleven");
numbers_converter.put(12,"Twelve");
numbers_converter.put(13,"Thirteen");
numbers_converter.put(14,"Fourteen ");
numbers_converter.put(15,"Fifteen");
numbers_converter.put(16,"Sixteen");
numbers_converter.put(17,"Seventeen");
numbers_converter.put(18,"Eighteen");
numbers_converter.put(19,"Nineteen");
number_place.put(3,"Hundred");
number_place.put(4,"Thousand");
number_place.put(7,"Million");
number_place.put(11,"Billion");
number_2nd.put(2,"Twenty");
number_2nd.put(3,"Thirty");
number_2nd.put(4,"Forty");
number_2nd.put(5,"Fifty");
number_2nd.put(6,"Sixty");
number_2nd.put(7,"Seventy");
number_2nd.put(8,"Eighty");
number_2nd.put(9,"Ninty");
if(input_number== 0){
System.out.println("zero");
}
else if(input_number>0 && input_number<19){
System.out.println(numbers_converter.get(input_number));
}
else if(input_number>19 && input_number<100){
int rem=input_number%10;
input_number=input_number/10;
System.out.print(number_2nd.get(input_number));
System.out.print(numbers_converter.get(rem));
}
else if(input_number==100){
System.out.println(number_place.get(3));
}
else if(input_number>100 && input_number<1000){
int reminder=input_number%100;
int r1=reminder%10;
int q1=reminder/10;
int quot=input_number/100;
System.out.print(numbers_converter.get(quot) + "hundred");
if(reminder>0 && reminder<20){
System.out.print(numbers_converter.get(reminder));
}
else{
System.out.println(number_2nd.get(q1) + numbers_converter.get(r1));
}
}
else if(input_number==1000){
System.out.println(number_place.get(4));
}
else if(input_number>1000 && input_number<10000){
int rem=input_number%100;
int rem_two=rem%10;
int quotient =rem/10;
input_number=input_number/100;
int thousand=input_number/10;
int hundred = input_number%10;
System.out.print(numbers_converter.get(thousand) + "thousand" + numbers_converter.get(hundred)+ " hundred");
if(rem >0 && rem<20){
System.out.print(numbers_converter.get(rem));
}
else if(rem >19 && rem <100){
System.out.print(number_2nd.get(quotient) + numbers_converter.get(rem_two));
}
}
else if(input_number>10000 && input_number<1000000000){
//Say number 418,229,356
int third_part=input_number%1000;//hold 356
input_number=input_number/1000;//hold 418,229
int sec_part=input_number%1000;//hold 229
input_number=input_number/1000;// hold 418
int rem_m=third_part%100;//hold 56
int rem_m1=rem_m%10;//hold 6
int rem_q=rem_m/10;// hold 5
int q_m=third_part/100;// hold 3
int sec_part_rem=sec_part%100;// hold 29
int sec_part_rem1=sec_part_rem%10;//9
int sec_part_q=sec_part_rem/10;//hold 2
int sec_q=sec_part/100;// hold 2
int input_q=input_number/100;// hold 4
int input_rem=input_number%100;//hold 18
int input_q_q=input_rem/10;//hold 1
int input_rem1=input_rem%10;// hold 8
System.out.print(numbers_converter.get(input_q) + " hundred ");
if(input_rem>0 && input_rem<20){
System.out.print(numbers_converter.get(input_rem)+ " Million ");
}
else{
System.out.print(number_2nd.get(input_q_q) + " " + numbers_converter.get(input_rem1) + " Million ");
}
System.out.print(numbers_converter.get(sec_q) + " hundred ");
if(sec_part_rem >0 && sec_part_rem<20){
System.out.println(numbers_converter.get(sec_part_rem) + " thousand ");
}
else{
System.out.print(number_2nd.get(sec_part_q) + " " + numbers_converter.get(sec_part_rem1) + " thousand ");
}
System.out.print(numbers_converter.get(q_m) + " hundred ");
if(rem_m>0 && rem_m<20){
System.out.print(numbers_converter.get(rem_m));
}
else{
System.out.print(number_2nd.get(rem_q) + " " + numbers_converter.get(rem_m1));
}
}
}
}
Redundant Code Blocks
int rem=input_number%100;
int rem_two=rem%10;
int quotient =rem/10;
input_number=input_number/100;
int thousand=input_number/10;
int hundred = input_number%10;
This type of code block used almost every where. Taking a number divide it with 100 or 1000 to find out the hundred position then then divide it with 10 to find out the tenth position of the number. Finally using %(modular division) to find out the ones position.
How could I include user define function and switch case to minimize the code block.
Instead of storing the results in variables, use a method call:
int remainder100(int aNumber) {
return aNumber % 100;
}
int remainder10(int aNumber) {
return aNumber % 10;
}
...etc.
System.out.println(numbers_converter.get(remainder100(input_number)));
About 3rd problem: I wouldn't use switch ... case, too many cases.
Instead, take advantage that numbering repeats itself every 3 digits. That means the pattern for thousands and millions is the same (and billions, trillions, etc).
To do that, use a loop like this:
ArrayList<String> partialResult = new ArrayList<String>();
int powersOf1000 = 0;
for (int kiloCounter = input_number; kiloCounter > 0; kiloCounter /= 1000) {
partialResult.add(getThousandsMilionsBillionsEtc(powersOf1000++);
partialResult.add(convertThreeDigits(kiloCounter % 1000));
}
Then you can print out the contents of partialResult in reverse order to get the final number.
I'd suggest you break your single main method down into a couple of classes. And if you haven't already create a few unit tests to allow you to easily test / refactor things. You'll find it quicker than starting the app and reading from stdin.
You'll find it easier to deal with the number as a string. Rather than dividing by 10 all the time you just take the last character of the string. You could have a class that does that bit for you, and a separate one that does the convert.
Here's what I came up with, but I'm sure it can be improved. It has a PoppableNumber class which allows the last character of the initial number to be easily retrieved. And the NumberToString class which has a static convert method to perform the conversion.
An example of a test would be
#Test
public void Convert102356Test() {
assertEquals("one hundred and two thousand three hundred and fifty six", NumberToString.convert(102356));
}
And here's the NumberToString class :
import java.util.HashMap;
import java.util.Map;
public class NumberToString {
// billion is enough for an int, obviously need more for long
private static String[] power3 = new String[] {"", "thousand", "million", "billion"};
private static Map<String,String> numbers_below_twenty = new HashMap<String,String>();
private static Map<String,String> number_tens = new HashMap<String,String>();
static {
numbers_below_twenty.put("0","");
numbers_below_twenty.put("1","one");
numbers_below_twenty.put("2","two");
numbers_below_twenty.put("3","three");
numbers_below_twenty.put("4","four");
numbers_below_twenty.put("5","five");
numbers_below_twenty.put("6","six");
numbers_below_twenty.put("7","seven");
numbers_below_twenty.put("8","eight");
numbers_below_twenty.put("9","nine");
numbers_below_twenty.put("10","ten");
numbers_below_twenty.put("11","eleven");
numbers_below_twenty.put("12","twelve");
numbers_below_twenty.put("13","thirteen");
numbers_below_twenty.put("14","fourteen ");
numbers_below_twenty.put("15","fifteen");
numbers_below_twenty.put("16","sixteen");
numbers_below_twenty.put("17","seventeen");
numbers_below_twenty.put("18","eighteen");
numbers_below_twenty.put("19","nineteen");
number_tens.put(null,"");
number_tens.put("","");
number_tens.put("0","");
number_tens.put("2","twenty");
number_tens.put("3","thirty");
number_tens.put("4","forty");
number_tens.put("5","fifty");
number_tens.put("6","sixty");
number_tens.put("7","seventy");
number_tens.put("8","eighty");
number_tens.put("9","ninty");
}
public static String convert(int value) {
if (value == 0) {
return "zero";
}
PoppableNumber number = new PoppableNumber(value);
String result = "";
int power3Count = 0;
while (number.hasMore()) {
String nextPart = convertUnitTenHundred(number.pop(), number.pop(), number.pop());
nextPart = join(nextPart, " ", power3[power3Count++], true);
result = join(nextPart, " ", result);
}
if (number.isNegative()) {
result = join("minus", " ", result);
}
return result;
}
public static String convertUnitTenHundred(String units, String tens, String hundreds) {
String tens_and_units_part = "";
if (numbers_below_twenty.containsKey(tens+units)) {
tens_and_units_part = numbers_below_twenty.get(tens+units);
}
else {
tens_and_units_part = join(number_tens.get(tens), " ", numbers_below_twenty.get(units));
}
String hundred_part = join(numbers_below_twenty.get(hundreds), " ", "hundred", true);
return join(hundred_part, " and ", tens_and_units_part);
}
public static String join(String part1, String sep, String part2) {
return join(part1, sep, part2, false);
}
public static String join(String part1, String sep, String part2, boolean part1Required) {
if (part1 == null || part1.length() == 0) {
return (part1Required) ? "" : part2;
}
if (part2.length() == 0) {
return part1;
}
return part1 + sep + part2;
}
/**
*
* Convert an int to a string, and allow the last character to be taken off the string using pop() method.
*
* e.g.
* 1432
* Will give 2, then 3, then 4, and finally 1 on subsequent calls to pop().
*
* If there is nothing left, pop() will just return an empty string.
*
*/
static class PoppableNumber {
private int original;
private String number;
private int start;
private int next;
PoppableNumber(int value) {
this.original = value;
this.number = String.valueOf(value);
this.next = number.length();
this.start = (value < 0) ? 1 : 0; // allow for minus sign.
}
boolean isNegative() {
return (original < 0);
}
boolean hasMore() {
return (next > start);
}
String pop() {
return hasMore() ? number.substring(--next, next+1) : "";
}
}
}
I was asked in an interview to write code to check if a given string is a palindrome or can be a palindrome by altering some character without using a library function. Here is my Approach
import java.util.Scanner;
public class Palindrom {
static int temp=0;
static char[] cArr;
static boolean chackPotentialPalindrom(char[] cAr){
cArr=cAr;
if(cArr!=null){
char current=cArr[0];
for(int i=1;i<cArr.length;i++){
if(current==cArr[i]){
cArr=removeElement(i);
chackPotentialPalindrom(cArr);
break;
}
}
if(cAr.length==2){
if(cAr[0]==cAr[1]){
cArr=null;
}}
if(temp==0 && cArr!=null){
temp=1;
cArr=removeFirstElement(cArr);
chackPotentialPalindrom(cArr);
}
}
if(cArr==null){
return true;
}else{
return false;
}
}
static char[] removeFirstElement(char[] cAr){
cArr=cAr;
if(cArr!=null){
if(cArr.length >1){
char[] cArrnew=new char[cArr.length-1];
for(int j=1,k=0;j<cArr.length;j++,k++){
cArrnew[k]=cArr[j];
}
return cArrnew;
} else {
return null;
}
} else {
return null;
}
}
static char[] removeElement(int i){
if(cArr.length>2){
char[] cArrnew=new char[cArr.length-2];
for(int j=1,k=0;j<cArr.length;j++,k++){
if(i!=j){
cArrnew[k]=cArr[j];
}else{
k-=1;
}
}
return cArrnew;}
else{
return null;
}
}
public static void main(String[] args) {
Scanner scn=new Scanner(System.in);
while(true){
temp=0;
String s=scn.next();
char[] arr=s.toCharArray();
System.out.println(chackPotentialPalindrom(arr));
}
}
}
Any tips to optimize this code?I could not write this in an interview as they have given a pen and paper to code.It took 3 hrs for me to write this. Can I be a developer?
Title says "without loop" but you need to check all symbol pairs, so using recursion, as you have tried, looks reasonable. But you don't check and use results of recursive calls.
Pseudocode might look like (note we don't need to change source data or extract substring):
Edit to provide possibility to alter one char
boolean checkPotentialPalindrom(char[] cAr, start, end, altcnt){
if (end <= start)
return true
if (cAr[start] != cAr[end])
altcnt = altcnt + 1
if (altcnt > 1)
return false
return checkPotentialPalindrom(cAr, start + 1, end - 1, altcnt)
}
and make the first call with arguments 0, len(cAr-1), 0
Answering to your first question..You have to use recursion to solve this problem. Here is my approach.
public boolean isPalindrom(char[] str, int start, int end) {
if (end <= start)
return true;
if (str[start] != str[end] || arraySize(str) <= 1)
return false;
return isPalindrom(str, start + 1, end - 1);
}
public int arraySize(char[] str) {
int count = 0;
for (char i : str) {
count++;
}
return count;
}
You have tried to implement this algorithm using loops and you can simplify it like this
public boolean isPalindroms(char[] str) {
int diffCount = 0;
int left = 0;
int right = arraySize(str) - 1;
while (right > left) {
if (str[right--] != str[left++]) {
diffCount++;
}
}
return (diffCount < 2);
}
public int arraySize(char[] str) {
int count = 0;
for (char i : str) {
count++;
}
return count;
}
The answer for the second question that you have ask is definitely you can be a good developer. Computer programming is a Craft. Not Some Kind of Rocket Science. You have to master it by crafting it.
using recursive function
calling with left=0 and right = arr.length-1
public static boolean isPalindrom(char[] arr, int left, int right){
if(arr[left++] != arr[right--])
return false;
if(left < right)
isPalindromss(arr, left++, right--);
return true;
}
if you have to use while loop, you can simplify it like following
public boolean isPalindrom(char[] arr){
int left=0;
int right = arr.length-1;
while(left < right){
if(arr[left++] == arr[right--])
continue;
return false;
}
return true;
}
Using StringBuilder, We can do it
public static boolean isPalindrom(String str, int len){
StringBuilder sb= new StringBuilder(str);
if((len > 1) & !(sb.substring(0,len/2 + 1).equals(sb.reverse().substring(0,len/2 + 1))))
return false;
return true;
}
function palin(input, leftIdx = 0, rightIdx = input.length - 1) {
if (leftIdx >= rightIdx) return true;
if (input[leftIdx] != input[rightIdx]) return false;
return palin(input, leftIdx + 1, rightIdx - 1);
}
const testCases = {
air: false,
airia: true,
caria: false,
a: true,
bb: true,
bcdb: false,
zzaaaaz: false,
};
Object.keys(testCases).forEach(test =>
console.log("Test: ", test, " is palindrome: ", palin(test), testCases[test])
);
I have a helper method that I am calling from another method in the same class. When I test it from main, it works fine. But as soon as I use it in the other class, it doesn't work at all. I cannot figure out what is wrong.
This is the helper method:
private boolean checkStack(Stack<String> stack,String check) {
System.out.println(stack);
System.out.println(check);
Stack<String> jump = new Stack<String>();
int count = 0;
String temp = "";
while (!stack.empty()) {
temp = stack.pop();
if (check == temp) {
count++;
}
jump.push(temp);
}
while (!jump.empty()) {
temp = jump.pop();
stack.push(temp);
}
System.out.println(count);
if (count != 0) {
return true;
} else {
return false;
}
}
I will test it from main like so:
pathSoFar.push("00");
pathSoFar.push("01");
pathSoFar.push("20");
pathSoFar.push("23");
System.out.println(pathSoFar);
String checkfor = "20";
System.out.println(test01.checkStack(pathSoFar,checkfor));
But it wont work when I call it from another method:
for (String n : possibleSpots) {
System.out.println();
String check = n;
if (!checkStack(pathSoFar, n)) {
pathSoFar.push(n);
String x = ""+n.charAt(0);
String y = ""+n.charAt(1);
int nextRow = Integer.parseInt(x);
int nextCol = Integer.parseInt(y);
System.out.println(nextRow + "" + nextCol + " = next move.");
if (findPath(wordToFind, pathSoFar, nextRow, nextCol)) {
return true;
}
} else{}
}
This is the method header if that helps:
private boolean findPath(String wordToFind, Stack<String> pathSoFar, int row, int col) {
possibleSpots can contain either String literals or String objects.
The problem lies in the following line
if (check == temp)
Change it to
if (check.equals(temp))
String matching is done with == which will work only for String literals.
That is the reason why it worked for you in one case and it does not work in another case.
To know the difference check the below link:
What is the difference between == vs equals() in Java?
I am a new in java and programming in general.
I am currently doing complex numbers. I know that there might be an answer for this online, but it will also reveal if I used the correct algorithm and so on, so I am trying to avoid other answers around here.
My main issue is that I am having trouble with the Divide class that I made, since in complex number division we are going to return a fraction as an answer, I can't figure out how to have the program return the 2 statements that it calculate, can someone advise what can be done? Here is the part of the division code, it works fine when I check both part 1 and then part 2, but how can i get it to return both of them when calling using that class.
I attached my full code that I made, I know it can be tweaked to have less coding, but that is not my current concern.
Thanks for your help in advance.
class complexN {
int R, I;
complexN(int R, int I) {
this.R = R;
this.I = I;
}
complexN AddCN(complexN A) {
return new complexN(this.R + A.R, this.I + A.I);
}
complexN SubCN(complexN A) {
int AnsR = this.R - A.R;
int AnsI = this.I - A.I;
complexN Sum = new complexN(AnsR, AnsI);
return Sum;
}
complexN MulCN(complexN A) {
int AnsI = (this.R * A.I) + (this.I * A.R);
int AnsR = (this.R * A.R) - (this.I * A.I);
complexN Sum = new complexN(AnsR, AnsI);
return Sum;
}
complexN DivCN(complexN A) {
complexN ComCon = new complexN(A.R, (A.I * -1));
complexN part1 = new complexN(this.R, this.I).MulCN(ComCon);
complexN part2 = A.MulCN(ComCon);
return part1;
}
void print() {
String i = (this.I == 1 ? "" : (this.I == -1 ? "-" : "" + this.I));
if (this.R != 0 && this.I > 0) {
System.out.println(this.R + "+" + i + "i");
}
if (this.R != 0 && this.I < 0) {
System.out.println(this.R + i + "i");
}
if (this.R != 0 && this.I == 0) {
System.out.println(this.R);
}
if (this.R == 0 && this.I != 0) {
System.out.println(i + "i");
}
if (this.R == 0 && this.I == 0) {
System.out.println("0");
}
}
}
class complex {
public static void main(String[] args) {
// TODO Auto-generated method stub
complexN z1 = new complexN(5, 2);
complexN z2 = new complexN(3, -4);
System.out.print("z1 = ");
z1.print();
System.out.print("z2 = ");
z2.print();
System.out.println("---------");
z1.DivCN(z2).print();
}
}
This question already has answers here:
Comparing version number strings (major, minor, revision, beta)
(3 answers)
Closed 7 years ago.
For one of my projects i would like to get a version from a string which has multiple decimals, is it possible to convert it into a multi decimal point double or is it not possible. I would like to use this to see if it is more than the previous one, which would also have multiple decimals.
What I am using at the moment is
if (!vers.equalsIgnoreCase(plugin.getDescription().getVersion())) { // Do stuff
But I would like to make it so I can do
if (vers > plugin.getDescription().getVersion()) { // do stuff
vers is equal to 1.0.1, and the plugin.getDescription().getVersion() is equal to 1.0.2
thanks!
You could implement this way, if you assume all the portions are numbers.
public static int compareVersions(String vers1, String vers2) {
String[] v1 = vers1.split("\\.");
String[] v2 = vers2.split("\\.");
for (int i = 0; i < v1.length && i < v2.length; i++) {
int i1 = Integer.parseInt(v1[i]);
int i2 = Integer.parseInt(v2[i]);
int cmp = Integer.compare(i1, i2);
if (cmp != 0)
return cmp;
}
return Integer.compare(v1.length, v2.length);
}
and
System.out.println(compareVersions("1.0.1", "1.0.2"));
System.out.println(compareVersions("1.0.1", "1.0"));
System.out.println(compareVersions("1.0.2", "1.0.10"));
prints
-1
1
-1
A more complex version supports letters inside versions
public static int compareVersions(String vers1, String vers2) {
String[] v1 = vers1.split("\\.");
String[] v2 = vers2.split("\\.");
for (int i = 0; i < v1.length && i < v2.length; i++) {
String [] w1 = v1[i].split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)");
String [] w2 = v2[i].split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)");
for(int j=0;j<w1.length&&j<w2.length;j++) {
try {
int i1 = Integer.parseInt(w1[j]);
int i2 = 0;
try {
i2 = Integer.parseInt(w2[j]);
} catch (NumberFormatException e) {
return -1;
}
int cmp = Integer.compare(i1, i2);
if (cmp != 0)
return cmp;
} catch (NumberFormatException e) {
try {
Integer.parseInt(w2[j]);
return +1;
} catch (NumberFormatException e1) {
int cmp = w1[j].compareTo(w2[j]);
if (cmp != 0)
return cmp;
}
}
}
int cmp = Integer.compare(w1.length, w2.length);
if (cmp != 0)
return cmp;
}
return Integer.compare(v1.length, v2.length);
}
and
System.out.println(compareVersions("1.0.2", "1.0.2a"));
System.out.println(compareVersions("1.0.2b", "1.0.2a"));
System.out.println(compareVersions("1.8.0_66", "1.8.0_65"));
System.out.println(compareVersions("1.7.0_79", "1.8.0_65"));
prints
-1
1
1
-1
It seems that you would like to compare versions. Or to take decisions based on some string represented version. If the plugin.getDescription().getVersion() is a String, then you should be able to use a simple String comparison to establish the order between versions. Something like this should work:
String pluginVersion=plugin.getDescription().getVersion();
if (ensureValidVersion(pluginVersion)
&& compareVersions(vers,pluginVersion)>0) {
// do staff is vers is greater then plugin version
}
ensureValidVersion method will validate if you have a valid version number representation. And compareVersions will do a comparison for each version subcomponent.
Assuming you have a version number of the following form: x.y.z
You can use a similiar approach as suggested by Viacheslav Vedenin:
String versionNumber = "1.3.45";
String[] singleParts = versionNumbers.split(".");
int[] versionParts = new int[singleParts.length];
for(int i=0; i<singleParts.length; i++) {
versionParts[i] = Integer.parseInt(singleParts[i]);
}
Now you have an array of the single parts of your version number. To compare it to a previous one you could do as follow:
public static boolean isGreater(int[] firstVersion, int[] secondVersion) {
if(secondVersion.length > firstVersion.length) {
return false;
}else {
if(firstVersion.length > secondVersion.length) {
return true;
}else {
for(int k=0; k< firstVersion.length; k++) {
int v1 = firstVersion[k];
int v2 = secondVersion[k];
if(v1 < v2) {
return true;
}
}
return false;
}
}
}
If you want to compare versions using the equality/inequality operators (==, <, >, <=, and >=), you have two options.
Use a language like C++ that supports operator overloading
Set a limit on the length for each string in major.minor.build and convert each version to an integer before comparing them. For example, if the limit on each of them is 3 (i.e. the longest version you can have is abc.def.ghi), then you can just use build + minor * 10^3 + major * 10^6.
Alternatively, you can just implement Comparable<Version> and have a nice OOP solution.
public class Example {
static class Version implements Comparable<Version> {
private int major;
private int minor;
private int build;
public Version(String s) {
final String[] split = s.split("\\.");
major = Integer.parseInt(split[0]);
minor = Integer.parseInt(split[1]);
build = Integer.parseInt(split[2]);
}
public int getMajor() {
return major;
}
public int getMinor() {
return minor;
}
public int getBuild() {
return build;
}
#Override
public int compareTo(Version v) {
if (getMajor() < v.getMajor()) {
return -1;
} else if (getMajor() > v.getMajor()) {
return 1;
} else {
if (getMinor() < v.getMinor()) {
return -1;
} else if (getMinor() > v.getMinor()) {
return 1;
} else {
if (getBuild() < v.getBuild()) {
return -1;
} else if (getBuild() > v.getBuild()) {
return 1;
} else {
return 0;
}
}
}
}
}
public static void main(String[] args) {
String s1 = "1.0.1";
String s2 = "1.0.2";
compare(s1, s2);
compare(s1, s1);
compare(s2, s2);
compare(s2, s1);
}
private static void compare(String s1, String s2) {
Version v1 = new Version(s1);
Version v2 = new Version(s2);
final int compareTo = v1.compareTo(v2);
if (compareTo == -1) {
System.out.println(s1 + " was released before " + s2);
} else if (compareTo == 0) {
System.out.println(s1 + " is the same as " + s2);
} else {
System.out.println(s1 + " was released after " + s2);
}
}
}
Output:
1.0.1 was released before 1.0.2
1.0.1 is the same as 1.0.1
1.0.2 is the same as 1.0.2
1.0.2 was released after 1.0.1
String[] numbers = version.split(".");
String[] numbers2 = version2.split(".");
int index = numbers.length-1;
while(numbers[index] != "."){
index--;
}
String lastnumber = version.substring(index+1, numbers.length];
index = numbers2.length-1;
while(numbers2[index] != "."){
index--;
}
String lastnumber2 = version.substring(index+1, numbers2.length];
if(lastnumber > lastnumber2){
//later version
}else{
//use the same thing to check the other numbers
}