How to calculate difference between String times - java

I have a string of: "9AM-5PM"
I would like to subtract these two numbers and find the difference in hours.

int intervalHours(String input) {
String[] ts = input.split("-"); // {"9AM", "5PM"}
return toHours(ts[1]) - toHours(ts[0]);
}
int toHours(String t) {
int h = Integer.parseInt(t.substring(0, t.length() - 2));
if (t.endsWith("PM"))
return h == 12 ? 12 : (h + 12);
else
return h == 12 ? 0 : h;
}
// ...
System.out.println(intervalHours("9AM-5PM"));

public void time()
{
String t="12AM-5PM";``
StringTokenizer st=new StringTokenizer(t,"-");
String initialTime=st.nextToken();
String finalTime=st.nextToken();
int t1=0;
int t2=0;
if(initialTime.contains("AM"))
{
t1=Integer.valueOf(initialTime.replace("AM",""));
}
else
{
t1=Integer.valueOf(initialTime.replace("PM",""))+12;
}
if(finalTime.contains("AM"))
{
t2=Integer.valueOf(finalTime.replace("AM",""));
}
else
{
t2=Integer.valueOf(finalTime.replace("PM",""))+12;
}
System.out.println(t2-t1);
}

Related

Which data structure is good for equation solving

I planned to develop an equation solver from basic and able to do basic mathematics operations using below code. I have used a token stack structure which will used to store the deliminator and number token. Though this implementation is too basic, I want to improve it on later version. I just need some helps the way I use the data structure to store the token as a set of stacks. Please kindly suggest any mistake ?
import java.util.ArrayList;
import java.util.Stack;
class TokenStack<N, D> {
private Stack<N> numberStack;
private Stack<D> delimStack;
public TokenStack() {
numberStack = new Stack<N>();
delimStack = new Stack<D>();
}
public void pushN(N num) {
numberStack.push(num);
}
public N popN() {
return numberStack.pop();
}
public void pushD(D delim) {
delimStack.push(delim);
}
public D popD() {
return delimStack.pop();
}
public boolean isEmptyN() {
return numberStack.isEmpty();
}
public boolean isEmptyD() {
return delimStack.isEmpty();
}
}
public class GeneralST {
private static final char SPACE_DELIM = ' ';
private static final char ADD_DELIM = '+';
private static final char SUB_DELIM = '-';
private static final char MUL_DELIM = '*';
private static final char DIV_DELIM = '/';
protected static final char EQU_DELIM = '=';
private TokenStack<String, Character> tokens = new TokenStack<String, Character>();
protected ArrayList<Character> acceptedDelims = new ArrayList<Character>();
protected ArrayList<Character> mathsDelims = new ArrayList<Character>();
protected double result;
public double getResult() {
return result;
}
protected void setupDelims() {
acceptedDelims.add(SPACE_DELIM);
mathsDelims.add(ADD_DELIM);
mathsDelims.add(SUB_DELIM);
mathsDelims.add(MUL_DELIM);
mathsDelims.add(DIV_DELIM);
acceptedDelims.addAll(mathsDelims);
}
private void tokenize(String str) {
String reverse = "";
for (int i = str.length() - 1; i >= 0; i--) {
char charAt = str.charAt(i);
if (i > 1) {
char charPre = str.charAt(i - 1);
if (acceptedDelims.indexOf(charAt) == -1 && (charPre == '-' || charPre == '+')) {
reverse = reverse + charPre + charAt;
i--;
} else {
reverse = reverse + charAt;
}
} else {
reverse = reverse + charAt;
}
}
int i = 0;
while (reverse.length() > 2) {
char charAt = reverse.charAt(i);
char chartNext = reverse.charAt(i + 1);
if (acceptedDelims.indexOf(charAt) != -1 && acceptedDelims.indexOf(chartNext) != -1) {
String previous = reverse.substring(0, i);
if (!previous.equals("") && !previous.equals(" ")) {
tokens.pushN(previous);
}
if (mathsDelims.indexOf(charAt) != -1) {
tokens.pushD(charAt);
}
reverse = reverse.substring(i + 1);
i = i - previous.length() - 1;
}
i++;
}
if (!reverse.equals("")) {
tokens.pushN(reverse);
}
}
private double equate() {
double val = 0;
int step = 1;
int side = 1;
while (!tokens.isEmptyN() && !tokens.isEmptyD()) {
char delim = tokens.popD();
double val1 = Double.valueOf(tokens.popN());
double val2 = side * Double.valueOf(tokens.popN());
switch (delim) {
case ADD_DELIM:
val = val1 + val2;
break;
case SUB_DELIM:
val = val1 - val2;
break;
case MUL_DELIM:
val = val1 * val2;
break;
case DIV_DELIM:
try {
val = val1 / val2;
break;
} catch (Exception exception) {
exception.printStackTrace();
break;
}
case EQU_DELIM:
val = val1 - val2;
side = -1;
delim = '-';
}
String outString = "Step %d : %s %c %s = %f";
String printString = String.format(outString, step, val1, delim, val2, val);
step++;
System.out.println(printString);
tokens.pushN(String.valueOf(val));
}
return val;
}
public GeneralST(String str) {
System.out.println("--------------------------------------");
System.out.println("[EXP] : " + str);
setupDelims();
tokenize(str);
result = equate();
System.out.println("--------------------------------------");
}
public void PrintResult() {
System.out.println("Result = " + result);
}
}
class EquateST extends GeneralST {
public EquateST(String str) {
super(str);
}
#Override
protected void setupDelims() {
mathsDelims.add(EQU_DELIM);
super.setupDelims();
}
public void PrintResult() {
if (result == 0) {
System.out.println("Result = True");
} else {
System.out.println("Result = False");
}
}
}
class Main {
public static void main(String[] args) {
String[] equations = {"6 + 2 + -4 * 4 - 5", "6 + 2 - 4 * 4 = -5", "6 + -2 - 4 = 4 - 5"};
calculate(equations);
}
private static void calculate(String... equations)
{
for (String equation : equations) {
if (equation.contains("=")) {
EquateST equateST = new EquateST(equation);
equateST.PrintResult();
} else {
GeneralST generalST = new GeneralST(equation);
generalST.PrintResult();
}
}
}
}
Sample Results
--------------------------------------
[EXP] : 6 + 2 + -4 * 4 - 5
Step 1 : 6.0 + 2.0 = 8.000000
Step 2 : 8.0 + -4.0 = 4.000000
Step 3 : 4.0 * 4.0 = 16.000000
Step 4 : 16.0 - 5.0 = 11.000000
--------------------------------------
Result = 11.0
--------------------------------------
[EXP] : 6 + 2 - 4 * 4 = -5
Step 1 : 6.0 + 2.0 = 8.000000
Step 2 : 8.0 - 4.0 = 4.000000
Step 3 : 4.0 * 4.0 = 16.000000
Step 4 : 16.0 - -5.0 = 21.000000
--------------------------------------
Result = False
--------------------------------------
[EXP] : 6 + -2 - 4 = 4 - 5
Step 1 : 6.0 + -2.0 = 4.000000
Step 2 : 4.0 - 4.0 = 0.000000
Step 3 : 0.0 - 4.0 = -4.000000
Step 4 : -4.0 - -5.0 = 1.000000
--------------------------------------
Result = False
Your problem is "arithmetic evaluation".
It was mentioned in many book "Algorithm".
Best and simple way to solve it : using stack and "postfix notation".
You can find a lot of article with your favorite programming languages.

Creating a Complex number class 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();
}
}

How to pass a String parameter to a void method? [duplicate]

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..

getting a multi decimal number from a string [duplicate]

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
}

Sort String with possible numbers in it

I've got the following possible addresses as string (not sorted):
"road 21"
"road 1"
"road 186"
"road +21 / 23"
"road +21 / 19"
"another road 21"
"another road 1"
and I want to be able to sort them as (so not on the default String sorting way):
another road 1
another road 21
road 1
road 21
road +21 / 19
road +21 / 23
road 186
How should I do this? I probably have to use a custom comparator, but how should I split the String?
I implemented this in Java and I know it looks weird at first.
If you have any questions feel free to ask me
public class SpecialComparator implements Comparator<String> {
#Override
public int compare(String arg0, String arg1) {
// TODO Auto-generated method stub
String []words1=arg0.split(" ");
String [] words2 = arg1.split(" ");
int i = 0;
if (words1[i].hashCode()>words2[i].hashCode()){
return 1;
}
else if (words1[i].hashCode()<words2[i].hashCode()){
return -1;
}
else if (words1[i].hashCode()==words2[i].hashCode())
return compare(arg0.substring(i+1, arg0.length()), arg1.substring(i+1,arg1.length()));
else if (i == Math.min(words1.length,words2.length)-1 && Math.min(words1.length,words2.length) == words1.length){
return -1;
}
else if (i == Math.min(words1.length,words2.length)-1 && Math.min(words1.length,words2.length) == words2.length){
return 1;
}
else if (i == Math.min(words1.length,words2.length)-1 && words1.length == words2.length){
return 0;
}
else{
return 0;
}
}
public static void main (String[] args){
ArrayList<String> input = new ArrayList<String>();
SpecialComparator a = new SpecialComparator();
input.add("road 21");
input.add("road 1");
input.add("road 186");
input.add("road +21 / 23");
input.add("road +21 / 19");
input.add("another road 21");
input.add("another road 1");
Collections.sort(input,a);
for (String ans : input){
System.out.println(ans);
}
}
}
Your format seems to be :
{name}
{number}
optional slash character
Optional second {number}.
Hence, I would create an object representing this format with those attributes:
public class MyInput {
private String name;
private Integer firstNumber;
private Integer secondNumber;
}
Then parse your input file to create a List<MyInput>.
Finally, you create a custom Comparator can call Collections.sort(yourList, yourCustomComparator)
This issue seems to crop up alot. I have been using Martin Pools NaturalOrderCompartor. You can easily port it into your code.
https://github.com/paour/natorder/blob/master/NaturalOrderComparator.java
it is little bit nasty, but this is my solution for your problem
List<String> list = Arrays.asList("road 21", "road 1", "road 186",
"road +21 / 23", "road +21 / 19", "another road 21",
"another road 1");
Collections.sort(list, new Comparator<String>() {
Integer toNumber(String string) {
try {
return Integer.parseInt(string);
} catch (NumberFormatException e) {
return null;
}
}
#Override
public int compare(String o1, String o2) {
String[] left = o1.split("\\s+");
String[] right = o2.split("\\s+");
for (int i = 0; i < Math.min(left.length, right.length); i++) {
String ls = left[i];
String rs = right[i];
Integer li = toNumber(ls);
Integer ri = toNumber(rs);
if (li != null && ri != null
&& li.intValue() != ri.intValue()) {
return li.intValue() - ri.intValue();
} else if (li != null && ri == null) {
return 1;
} else if (li == null && ri != null) {
return -1;
} else if (li == null && ri == null){
int compared = ls.compareToIgnoreCase(rs);
if (compared != 0) {
return compared;
}
}
}
return left.length - right.length;
}
});
but if you are ok with changing your structure, then go with solution proposed by Arnaud Denoyelle
You can also try following comparator :
class MyComparator implements Comparator<String> {
#Override
public int compare(String o1, String o2) {
o1 = o1.replace("+", "");
o2 = o2.replace("+", "");
String[] a1 = o1.split(" ");
String[] a2 = o2.split(" ");
int length = (a1.length > a2.length) ? a2.length : a1.length;
for (int i = 0; i < length; i++) {
if (!a1[i].equalsIgnoreCase(a2[i])) {
if (!isIntegerRegex(a1[i]) || !isIntegerRegex(a2[i])) {
return o1.compareTo(o2);
}
int f = Integer.parseInt(a1[i]);
int s = Integer.parseInt(a2[i]);
return f - s;
}
}
return a1.length - a2.length;
}
public boolean isIntegerRegex(String str) {
return str.matches("^[0-9]+$");
}
}
And call it:
public String[] sortStrings(String[] input) {
Arrays.sort(input, new MyComparator());
return input;
}

Categories