Reputation: 11
I'm a Java beginner and this is for my software class. The general project is pretty simple, it asks you to tell the user what their sales tax is and what their new total is based on that, based on which US state they're in. I'm trying to make it so when they input (through the Scanner), for example, "Wisconsin" after the "which state are you in" prompt, I get the value of ".05" to use since that's Wisconsin's state tax.
I have made both arrays, I just don't know how to access a value from an array using values from another. Everything is in the correct corresponding order, as in Alabama's tax rate is 4% (.04), Alaska's is 0%, and so on.
import java.util.Scanner;
public class SalesTax {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
double sale;
double salesTax;
double total;
double[] taxRate = { .04, 0, .56, .65, .75,
.29, .0635, 0, .06, .04,
.04, .06, .0625, .07, .06,
.065, .06, .04, .055, .06,
.0625, .06, .06875, .07, .04225, 0,
.055, .0685, 0, .07, .05125,
.04, .0475, .05, .0575, .045,
0, .06, .07, .06, .04,
.07, .0625, .0595, .06, .0530,
.065, .06, .05, .04, .0575 };
String[] states = { "Alabama", "Alaska", "Arizona", "Arkansas", "California",
"Colorado", "Connecticut", "Delaware", "Florida", "Georgia",
"Hawaii", "Idaho", "Illinois", "Indiana", "Iowa",
"Kansas", "Kentucky", "Louisiana", "Maine", "Maryland",
"Massachusetts", "Michigan", "Minnesota", "Mississippi", "Missouri",
"Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey",
"New Mexico", "New York", "North Carolina", "North Dakota", "Ohio",
"Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina",
"South Dakota", "Tennessee", "Texas", "Utah", "Vermont",
"Virginia", "Washington", "West Virginia", "Wisconsin", "Wyoming" };
System.out.println("Enter the state you are in (please type the full name): ");
states = input.nextLine();
System.out.println("Enter the amount of the sale: ");
sale = input.nextDouble();
}
}
I'm really just not sure where to go from here. Once I'm able to reference the value I should be able to code the rest of it easily. If more information is needed, let me know.
Upvotes: 0
Views: 260
Reputation: 1369
What you really should use is a HashMap
like data structure. It's pretty simple and builds on @Scary Wombat's answer's second suggestion
Create a class called Entry
with this 2 fields: a String
field called state
and a field called taxRate
of type double
.
Create another class called TaxRateTable
(or whatever you want to call it that makes sense to you) and have only a single field and that is an array of objects of type Entry
i.e. an array of Entry
.
You have to store the records of 50 states and their corresponding tax rates. So have the array size as 67. Now all we need to do is find out a way to insert an Entry
to the array in such a way, that when I am looking for a particular Entry
(by name of course in your case), we do not use a loop to navigate to the location but directly jump to the exact location of the entry that we are looking for.
How do we do that? (this is the heart of the solution)
We create a function that takes in the name of a state and then spits out a number between 0 and 66 (inclusive), and for each state's name it returns a distinct number (can you guess where we are going with this?)
Once we get the number, this number will now become the index of the Entry
in the array.
So how does the function look like?
static int calculateIndex(String name) {
int sumTotal = 0;
for (int i = 0; i < name.length(); i++) {
sumTotal += name.charAt(i);
}
return ((13*sumTotal) % 127) % 67;
}
Then make a method called putTaxRateEntryOfState
which takes the name of the the state and the tax rate. Create an Entry
object using the arguments, find out the index with the function mentioned above and then simply assign the Entry
as a value of at the obtained index in the array of Entry
.
Now create a method called getTaxRateOfState
which takes the name of the state as the only argument. Get the index in which the entry is stored in the array by calling the function calculateIndex
mentioned above and then using that index to access the exact entry that you are looking for in the array.
Explanation
The data structure that is used is known as a Hashtable. It can find a given element and also insert one very fast (In constant time).
As you can see, the items in the data structures are not ordered.
The size of a hashtable (meaning the total size of the array of Entry
) is usually chosen as being around 1.3x larger the total number of values to be saved in the array. And that's why it's 67 in this case which is roughly 1.3x greater than 50 which is the total number of values to put in.
What's going on with the calculateIndex
function?
This function is called a hash function. There are many kind of hash functions that have been engineered for various kinds of needs. In our case, since we know all the data beforehand, we use a hash function known as Perfect Hash Function. It is used mostly when all the input is known beforehand.
The it has the form:
index = (k*x mod p) mod n
In this case I went with k = 13, and p = 127 (both prime numbers).
Important!
It is highly possible that the hash function calculates the same index for different values. And this is called a hash collision, it's normal and you should expect it. And there are multiple techniques to resolve this.
But if you do not want to do all of the above and simply implement a one shot solution then you can use Java's HashMap
class
Upvotes: 0
Reputation: 41
The previous response is right, but for that you need to be absolutely sure both arrays have the same size always, if not it will fail.
If you are not sure, you could use a HashMap<String, Double> map
And from there you could do a `map.put("Alabama", 0.04); and like so for each.
Then you could loop through map.keySet() and when you find the state desired you just do map.get(state)
Upvotes: 4
Reputation: 44844
You can get and keep the index of the chosen state and then use it directly to get the value from the amounts.
int index = -1;
for (int i = 0; i < states.length; i++) {
if (states[i].equals (chosenState)) {
index = i;
break;
}
}
if (index >= 0) {
tr = taxRate[index]; // is what you want
}
But probably a better but more advanced way would be to create a class that contains the name and taxRate and to have an Array or List of these objects
Upvotes: 3