Java arrays formatting - java

I am nearly done with my project (technically it's finished), but I am having a big problem with little detail such as output formatting. I am fairly new to JAVA and would apreciatte any help you can provide.
I need to output 2 arrays (String and Int) in some sort of table format.
Example:
England 4.6
USA 2.6
Japan 7.8
etc
I need exact spacing between the characters. I'll give you one part of my code: (I can apply the logic to the rest of the program)
double beerStrenghts [] = new double [10];
for(int x = 0; x < beerStrenghts.length; x++){
beerStrenghts[x] = beerStrenghts()[x];
}
String beerName [] = new String [10];
for(int x = 0; x < beerName.length; x++){
beerName[x] = (beerName()[x]);
}
String lookup;
Scanner keyboard = new Scanner(System.in);
System.out.println("Please enter search criteria. Min 3 characters.");
lookup = keyboard.nextLine();
while(lookup.length() < 3){
System.out.println("Please enter at least 3 characters");
lookup = keyboard.nextLine();
}
Formatter fmt = new Formatter();
int indexInt;
boolean found;
for(int x = 0; x< beerName.length; x++){
found = beerName[x].toUpperCase().contains(lookup.toUpperCase());
if(found){
fmt.format("%12s%3d",beerName[x], beerStrenghts[x]);
System.out.println(fmt);
}
}
}
public static String [] beerName(){
String[] beerName = new String[10];
beerName[0] = "Heineken";
beerName[1] = "Bud Light";
beerName[2] = "Coors Light";
beerName[3] = "Leffe Blonde";
beerName[4] = "Budweiser";
beerName[5] = "Erdinger Non-Alcoholic";
beerName[6] = "Bud Premier Select";
beerName[7] = "Corona";
beerName[8] = "Barefoot Bohemian";
beerName[9] = "3 Monts";
return beerName;
}
public static double [] beerStrenghts(){
double beerStrenghts [] = new double [10];
beerStrenghts[0] = 4.0;
beerStrenghts[1] = 4.2;
beerStrenghts[2] = 4.3;
beerStrenghts[3] = 6.6;
beerStrenghts[4] = 5.0;
beerStrenghts[5] = 0.0;
beerStrenghts[6] = 7.4;
beerStrenghts[7] = 4.6;
beerStrenghts[8] = 4.0;
beerStrenghts[9] = 8.5;
return beerStrenghts;

You need to (re)read the javadoc for java.util.Formatter. In particular, it says that the formatting code d is for decimal integers. You are dealing with doubles, so the f code is probably more your style. (I'm just guessing though since you've been very light on details.)
Try something like
fmt.format("%-12s%3.1f",beerName[x], beerStrenghts[x]);

just change %3d to %.03for %.3f
like :
fmt.format("%-12s %.03f", beerName[x], beerStrenghts[x]);
%d is used for formatting integers.
also have a look at StringBuilder if you want different locales i.e different ways of formatting for different regions.
More about formatters with string builders here:https://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html

Big thanks for all help guys. And apologies for not providing enough details... I am also new in stack overflow.
This is my college project indeed (small part of it). Unfortunately majority of solutions-problems haven't being covered during classes - but I am doing my own researches(going very very well - almost done, formatting is the last part) and though I'll give my shoot here :)
Thanks for java.until.formatter reference dcsohl - I'll definitely go through it.
The solution given is almost working but I cant figure out what is the problem this time. Current output while searching for "bud":
Bud Light 4.2
Bud Light 4.2Budweiser 5.0
Bud Light 4.2Budweiser 5.0Bud Premier Select 7.4

Related

Assigning properties to an object in Java from a text file

I'm currently building a gamebook text based adventure program which will accept a certain format of txt file which looks like the one below.
Now this may all seem pretty simple however, I need to create Section objects in order for my game to work properly. As you can see above, the sections are often different sizes depending on how many possible choices they have to their appropriate story text. My section object has the declaration of
Section(String storytext, String choiceText, int choiceSections)
And I need to pull the appropriate details from this text file. I was reading through some forums and found an somewhat appropriate looking approach to the reading through the text file. The code was as follows which works in triplets, not necessarily good for me as my text files come in variable lengths. And obviously this is just an example of code, I would need to parse out both integers and strings.
Car[] car = new Car[length/3];
for (int i = 0; i < length/3; i ++) //
{
int startReading = Integer.parseInt(inputFile.readLine());
int endReading = Integer.parseInt(inputFile.readLine());
int liter = Integer.parseInt(inputFile.readLine());
car[i] = new Car (startKm, endKm, litre);
}
This seems like it would work for me however, I need my loop to update dynamically based upon a few criteria. #1 > The number on the first line which is the total number of section objects which will be created. #2 > The number on the total choices line which will determine how many more lines the line reader needs to run through before stopping and creating the object. I'm quite lost on how to create a proper loop which will create my objects based on this criteria for these text files.
6 < Number of "sections" in the game
1 < Section number (1)
While making a peanut butter and jam sandwich one evening you discover that you’ve run out of strawberry jam. < Story text associated with the section
2 < Number of possible choices
5 < The choice below leads to this section
If you make do with grape jelly, click here. < This is one of the choices
4 < The choice below leads to this section
If you head out to the store to buy strawberry jam, click here. < This is one of the choices
2 < Section number (2)
You arrive home and begin making a fresh sandwich with your favourite condiment. You lovingly spread the peanut butter and the strawberry jam, salivating at the wonderful aroma. Unable to resist any longer, you take a bite. Utter bliss envelopes you, the perfect blend of flavours a cascade of awesomeness filling your consciousness. < Story text associated with this section
0 < Number of possible choices
3 < Section Number (3)
Your stomach immediately starts to hurt. Pain stabs at your abdomen and you double over, gasping for breath. The floor crashes up and darkness clouds your vision. < Story text associated with this section
0 < Number of possible choices
4 < Section Number (4)
You rush to the grocery store and look for your favourite brand of strawberry jam. You are surprised to find a new variety, fieldberry, on the shelf beside the familiar jar. < Story text associated with this section
2 < Number of possible choices
2 < The choice below leads to this section
If you buy the strawberry jam, click here. < This is one of the choices
6 < The choice below leads to this section
If you buy the new fieldberry jam, click here. < This is one of the choices
5 < Section Number (5)
You dig around in the fridge for a while and find the grape jelly you remembered was back there. It smells a bit funky, but you slather it onto your bread just the same, holding your breath a bit. < Story text associated with this section
2 < Number of possible choices
3 < The choice below leads to this section
If you eat the smelly sandwich, click here. < This is one of the choices
4 < The choice below leads to this section
If you toss it in the garbage and go out to buy jam, click here. < This is one of the choices
6 < Section Number (6)
You arrive home and begin making a fresh sandwich with your exciting new
condiment. You lovingly spread the peanut butter and the fieldberry jam, salivating at the wonderful aroma. Unable to resist any longer, you take a bite. < Story text associated with this section
1 < Number of possible choices
//do not know the choice here yet.
3 < Choice section you are led too, 3 represents winning so it finishes at this point.
This will do:
public class Main {
public static void main(String[] args) throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader(
"C:\\path\\to\\file"))) {
String line = br.readLine().trim(); // may throw IOException
int num_of_sections = Integer.parseInt(line);
List<Section> sections = new ArrayList<>(num_of_sections);
for (int j = 1; j <= num_of_sections; ++j) {
line = _skip_empty(br);
int section_number = Integer.parseInt(line);
String section_text = _skip_empty(br);
line = _skip_empty(br);
int num_choices = Integer.parseInt(line);
List<Choice> choices = new ArrayList<>(num_choices);
for (int choice = 0; choice < num_choices; ++choice) {
line = _skip_empty(br);
int go_to_section = Integer.parseInt(line);
String choice_text = _skip_empty(br);
choices.add(new Choice(go_to_section, choice_text));
}
sections.add(new Section(section_number, section_text, choices));
}
}
}
private static class Section {
private final int sectionNumber;
private final String storyText;
private final List<Choice> choices;
Section(int sectionNumber, String storyText, List<Choice> choices) {
this.sectionNumber = sectionNumber;
this.storyText = storyText;
this.choices = choices;
}
public String getStoryText() {
return storyText;
}
public List<Choice> getChoices() {
return choices;
}
public int getSectionNumber() {
return sectionNumber;
}
}
private static class Choice {
private final int leadsToSection;
private final String choiceText;
Choice(int leadsToSection, String choiceText) {
this.leadsToSection = leadsToSection;
this.choiceText = choiceText;
}
public int getLeadsToSection() {
return leadsToSection;
}
public String getChoiceText() {
return choiceText;
}
}
private static String _skip_empty(BufferedReader br) throws IOException {
String line;
do {
line = br.readLine();
if (line == null) return ""; // winning choice does that
line = line.trim();
} while (line.isEmpty());
return line;
}
}
As you see I changed your Section class to accept a list of choices - that's more appropriate

Extracting Phone Number with Call Text from String using Reg exp

Ok Here is my example text... everything is
THEPONDIS15AWAYLOOKATTHOSEBASS5POUNDERSWELLLITATNIGHTALLAROUNDQUIETSEMICOUNTRYAREASTILLMOREBUTCALLMENORENTALNOLEASEANDPLEASEWENEEDNOREALTORSASMYWIFEDOES3176665440ANDCANNOTKEEPALLTHEMAINTANCEOFABIGHOUSEWANNAGOSOUTHTHANKSCALLMETHANKS
As you can see the Call and the phone number are within so far of eachother within 60 chars or so. So I been trying to right an expression to find this, determine that CALL is within 60 chars or so and then pull the phone number if it is..
I know that I would need something like...
Pattern p11 = Pattern.compile("[0-9]{11}");
Pattern p10 = Pattern.compile("[0-9]{10}");
Pattern p7 = Pattern.compile("[0-9]{7}");
In order to determine if its possibly an actual phone number since it could be 13173333333 or just 3173333333 or just 3333333
What about the rest? I know I would probably have to do a type of substring or something, but Its giving me a lot more difficulty then I thought it would.
I tried doing this...
String PHONENUMBER = "";
Pattern p11 = Pattern.compile("[0-9]{11}");
Pattern p10 = Pattern.compile("[0-9]{10}");
Pattern p7 = Pattern.compile("[0-9]{7}");
Matcher m11 = p11.matcher(Number);
Matcher m10 = p10.matcher(Number);
Matcher m7 = p7.matcher(Number);
String Call = "CALL";
String Text = "TEXT";
String Message = "MESSAGE";
if (Number.contains(Call)) {
int Numindex = Number.indexOf(Call);
int low = Numindex - 30;
int high = Numindex + 35;
if (low < 0) {
low = 0;
}
if (high > Number.length()) {
high = Number.length();
}
String extract = Number.substring(low, high);
m11 = p11.matcher(extract);
m10 = p10.matcher(extract);
m7 = p7.matcher(extract);
if (m11.find() == true) {
PHONENUMBER = m11.group();
} else if (m10.find() == true) {
PHONENUMBER = m10.group();
} else if (m7.find() == true) {
PHONENUMBER = m7.group();
}
But for some reason its not working out for me
EDIT #1 Requested for Original Text....
The Pond is 15' away- look at those bass- 5 Pounders-- well lit at night all around- quiet Semi Country area...still more but Ca ll me- NO RENTAL/No Lease and Please- we need NO Realtors as my Wife does 317 6 6.6-54.4 0 and cannot keep all the maintance of a big House- wanna go South Thanks call me!Call Me Thanks!
As you can see from the original text, it only makes sense to remove the spaces and all special characters then just do a simple expression comparison to find the phone number, then just find if the word "call" is within 60 chars. Obviously this isn't the ONLY paragraph there are hundreds more.
I'll be honest this seems like you are doing it in an extremely difficult way. However here is an idea on how you could go about doing it.
First get the range you want to check for the number let's say it's 0(low)-15(high)
then write a for loop to loop through that range of characters. The below code is an example of how you could set it up to loop through the section of the string you want checking the characters along the way to see if it matches a phone number. Take in mind this doesn't take in account reaching the end of the String to soon which would result in an index out of bounds exception nor does it take in account if it is too large of a number but I will let you figure those things out.
String number = "123HEY1234567890HOWIS";
int realNum = 0; //if this hits exactly 10 then it is a real phone number
int low = 0;
int high = number.length();
for(int i = low; i < high;i++){
//check if the current char is a number
if(number.substring(i, i + 1).matches("[0-9]")){
//if yes then increment
realNum++;
System.out.println(realNum);
//checks if realNum is 10 and makes sure that the next char isn't a number also
if(realNum == 10){
low = i - 9;
high = i;
System.out.println("match");
break;
}
}else{
//if no then reset the checker back to 1
realNum = 0;
}
}
System.out.println("All Done");
Hopefully this at least gets you on the right path.
I would use https://github.com/googlei18n/libphonenumber and not regex for finding phone numbers. The library works as you would expect
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
Iterable<PhoneNumberMatch> numbers = phoneUtil.findNumbers(text, Locale.US.getCountry());
List<String> data = new ArrayList<>();
numbers.forEach(number -> {
String s = number.rawString();
// your phone numbers
});

Debugging School Project

Right, I am working on a program for school the purpose of the program is to find the minimum number of coins, I am a novice programmer and this is my first time so I dont know the thousands of other things and what not other people do. I wrote the code and it works, but I seem to have found a bug/glitch or w/e you want to call it.
my code
import java.util.Scanner;
public class Coin {
public static void main (String[] Args) {
int quarters = 25;
int dimes = 10;
int nickles = 5;
int pennies = 1;
System.out.println("Enter in a number between 1-99");
// "Input" Part of Code (Remember this and go back for reference)
Scanner Userinput = new Scanner(System.in);
int stuff = Userinput.nextInt();
int q = stuff/quarters;
String A = "Number of Quarters:" +q;
System.out.println(A);
int hold = stuff%quarters;
int d = hold/dimes;
String B = "Number of Dimes:" +d;
System.out.println(B);
int hold1 = stuff%dimes;
int n = hold1/nickles;
String C = "Number of Nickles:" +n;
System.out.println(C);
int hold2 = stuff%nickles;
int p = hold2/pennies;
String D = "Number of Pennies:" +p;
System.out.println(D);
System.out.println("Thank you for Using My Program");
}
}
Now, everything works fine I can input any number I like and get the desired result, however for some odd reason I cannot fathom I type in any number between 75-79 and there is an added Nickle for some odd reason and I have spent the better part of 2 hours trying to figure out exactly what is wrong but cannot. Hav tried dozens of toher numbers and they work fine except for that one little area.
Can someone tell me by chance what might be wrong?
Your hold = ... lines should be based on the previous hold value rather than the full amount (stuff).
int hold2 = hold%nickles;
You need to subtract off what has already been accounted for when adding previous, larger coins.
For example, if I say 77, then the program will check 77%10 and return 7. You would want to adjust your "stuff" value by any previously added coins. So in this case, after adding 3 quarters (75) we would want to set stuff = stuff - 75 (stuff -= 75).
EDIT: to be more precise, after every calculation you could run
stuff -= q * quarters;
of course, changing the variables to be appropriate for each part of your code.

Scaling RGB values in Pi

So for extra credit for my math class I'm writing a program to visualize pi. Every 6 digits is converted to a hex color.
However, I'm running into an error when I try to scale the colors (since with 2 digits each for r, g, and b I can only go up to 99 and I want to go to 255). I go through a few thousand digits of pi and run this scale function on each set of 6 and then write it to a pixel in a BufferedImage, but I keep getting a StringIndexOutOfBoundsException. When I tried setting retArray[i+1] = subArray[0] I get the same error but this time at line 5. Any idea what's going on?
private String scale(int org){
tmp = Integer.toString(org);
retArray = new char[6];
for(int i=0; i<=4; i+=2){
tmpsub = tmp.substring(i, i+2); //line 5
int2 = Integer.parseInt(tmpsub);
tmpint = (((float)(int2)/99)*255);
intie = (int)(tmpint);
tmpsub = Integer.toHexString(intie);
subArray = tmpsub.toCharArray();
retArray[i] = subArray[0];
retArray[i+1] = subArray[1]; //String Index Exception on this line
}
retString = "";
for(int i=0; i<retArray.length; i++)
retString+=retArray[i];
return retString;
}
Thanks so much for any help with this problem. Hopefully it's something obvious that I don't see.
The problem is with Integer.toHexString().
If you give it a value that is less than 0x10 (16 in decimal,) you'd get a string of length one as a result, and then subArray[1] would throw an exception.

Why is just reading a small file taking so long?

I'm doing what seems like a simple read from a data file, and it's taking for fricking ever. (And by that, I mean 300ms.) This is the code in question:
BufferedReader f = new BufferedReader(new FileReader("input.txt"));
StringTokenizer st = new StringTokenizer(f.readLine());
int var1 = Integer.parseInt(st.nextToken())
int var2 = Integer.parseInt(st.nextToken());
Integer[][] people = new Integer[var1][];
for(int i = 0; i < var2; i++)
f.readLine();
for(Integer i = 0; i < var1; i++)
{
StringTokenizer line = new StringTokenizer(f.readLine(), " \t\n\r\f,");
line.nextToken();
Integer[] list = new Integer[line.countTokens()];
for(int j = 0; j < drinks.length; j++)
list[j] = Integer.parseInt(line.nextToken());
people[i] = list;
}
And this is the relevant time output:
sammysmbp:fridgemadness_lean sfishman$ time java fridgemadness
real 0m0.311s
user 0m0.277s
sys 0m0.056s
Is it just me or is that really, really slow. It's only going through 51 lines of input in this example.
Just guessing, but probably a lot of the time is used up just for the jvm to start up.
Print a timestamp just before and after the relevant code. If my guess is correct a little server taking requests might help to eliminate the startup time.
You don't need \r or \n in the pattern, readLine() has already removed them.
JVM startup aside, most of the time will be spent in reading to the desired position if the file is at all long. Maybe a text file of lines isn't the correct data structure.

Categories

Resources