How to create the FizzBuzz using loops in JAVA - java

I'm writing this problem for school and I have some issues with it. I can't get "printFizzBuzz" to actually go up and calculate the wrapper function "FizzBuzz". I am required to use loops and was attempting to use a FOR loop. Beginner programmer here so no, I haven't used loops much at all. Any tips or pointers? ;)
The instructions are as follows.
public static String FizzBuzz(int number)
{
if( (number%3==0) && (number%5==0)) {
return "FizzBuzz";
}
else if( number%3 == 0 ) {
return "Fizz";
} else if( number%5 == 0 ) {
return "Buzz";
} else {
return ""+number;
}
}
/*
* use a for loop to print the appropriate FizzBuzz values (feel free to
* call the provided FizzBuzz function) for values from from to to,
* including both of those values. Each value should be printed in a separate line.
*/
public static void printFizzBuzz(int from, int to, PrintStream out)
{
for (int i = 1; i <= to; ++i){
FizzBuzz(++i);
}
}

Take a look at the FizzBuzz function:
public static String FizzBuzz(int number)
public static STRING tells you that this function returns a string.
Each time you write
FizzBuzz(++i);
imagine this to be a string like "Fizz"
So in your program what you really wrote is
for (int i = 1; i <= to; ++i){
"Fizz";
}
That doesn't look good right? You actually need to assign this string to something, or do some stuff with it. For example:
for (int i = 1; i <= to; ++i){
String a = "Fizz";
System.out.println(a);
}
Better, this is printing it to the standard output! However your function has already one PrintStream out parameter that you can use to print!
for (int i = 1; i <= to; ++i){
String a = FizzBuzz(i++);
out.println(a);
}
Now let's take a look at the for loop: it creates a variable i that starts from 1 (int i = 1), checks the condition ( i <= to) and if the condition is satisfied it executes the body of the loop. After that it increments i by 1 (++i).
So the first 3 rounds of the loop will be unrolled like this:
int i = 1;
if(i<=to){
String a = FizzBuzz(i++);
out.println(a);
}
++i; //i = 3;
if(i<=to){
String a = FizzBuzz(i++);
out.println(a);
}
++i; //i = 5;
if(i<=to){
String a = FizzBuzz(i++);
out.println(a);
}
++i; //i = 7;
Looks like we still have a problem here. Why is i 3, then 5 and then 7? What happened to 2,4,6? The problem is that you are also incrementing i by 1 when calling FizzBuzz (FizzBuzz(i++)).
This is wrong, the loop is already incrementing i for you by 1, if you increment i by 1 more, it will be incremented by 2 each round.
I'll leave the final fix to you.

Related

Program constantly says missing return statement

My program is supposed to be passed 2 array-lists, arrivals and duration, and should return the number of events that can basically take place without overlap. The last thing I did was add the final else if statement to count the last arrival as an event that could take place. However, my code constantly gives a no return statement error although there is a return statement.
class Results {
public static int maxEvents(List<Integer> arrival,List<Integer> duration) {
int counter = 0;
for (int i = 0; i < arrival.size(); i++) {
if (arrival.get(i) + duration.get(i) <= arrival.get(i+1)) {
counter++;
} else if (arrival.get(i)==arrival.get(i+1)) {
counter++;
i++;
} else if (i == arrival.size()-1) {
counter++;
}
return counter;
}
}
}
The return statement which you have written lies within for loop that is incorrect.
please follow below code
class Results {
public static int maxEvents(List<Integer> arrival,List<Integer> duration) {
int counter = 0;
for (int i = 0; i < arrival.size(); i++) {
if (arrival.get(i) + duration.get(i) <= arrival.get(i+1)) {
counter++;
} else if (arrival.get(i)==arrival.get(i+1)) {
counter++;
i++;
} else if (i == arrival.size()-1) {
counter++;
}
}
return counter;
}
}
The Java compiler requires that all methods with a non-void return type either:
Return a value (or throw) on all paths
Definitely don't return a value (e.g. if they contain an infinite loop).
It determines this by looking at the statements in your method to see if they "complete normally". This is a bit of a funny term, but it basically means that execution would move onto the next statement (or the method would finish executing if it is the last statement in the method).
In this case, it looks at the loop:
for (int i = 0; i < arrival.size(); i++) {
// ...
return counter;
}
And it finds that:
The for loop body completes abruptly (it always returns a value)
The for loop might be able to complete normally, because i < arrival.size() isn't a constant (*).
As such, it looks after the for loop to make sure that all following paths return a value (or throw). But this cannot be the case, because there are no statements after the for loop. As such, a compile-time error results.
The easiest way to satisfy the compiler is to put another return after the for loop:
for (int i = 0; i < arrival.size(); i++) {
// ...
return counter;
}
return /* some int */;
Or make the guard expression constant true (or omit it):
for (int i = 0; true; i++) {
// ...
return counter;
}
However, your loop body always returns if entered; so it is basically if (0 < arrival.size()) rather than a loop. And it would only ever return 0 or 1, because counter is incremented at most once.
This is presumably a logical error: the return shouldn't be inside the loop, allowing you to count the number of items in the list which meet the condition:
for (int i = 0; i < arrival.size(); i++) {
// ...
}
return counter;
(*) The compiler doesn't look any deeper than the fact it's not a constant equal to true. For example, i <= Integer.MAX_VALUE isn't constant, and thus is considered to allow normal completion, but it is clearly always true.

Cannot print out the right sum

I have assigned a letter grade to each student based on his/her grade. And I want to count the total number of students for each letter grade. But for some reasons, the result turns total wrong. Can anyone tell me what parts I did wrong? Thank you!
String letter ="A";
int letterA=0;
int letterB=0;
int letterC=0;
int letterD=0;
int letterF=0;
int a=0;
int b=0;
int c=0;
int d=0;
int f=0;
for (int row=0;row<100;row++){ //the outer loop, have 100 rows to go through
for ( int column=0;column<words.length;column++) {
if(words[column].equals(table[row][column])){ // compare two arrays
count++; }// add the score for each student if he/she is right
}
if (count >=18)
letter=("A");
if(count>=16 && count<18)
letter=("B");
if(count>=14 && count<16)
letter=("C");
if(count>=12 && count<14)
letter=("D");
if(count<12)
letter=("F");
System.out.println("Student Grade: "+letter+"\t");
count=0; // make sure the count will go back to 0, and run the loop again
if (letter.equals("A"))
letterA++;
a+=letterA;}
if (letter.equals("B"))
letterB++;
b+=letterB;
if (letter.equals("C"))
letterC++;
c+=letterC;
if (letter.equals("D"))
letterD++;
d+=letterD;
if (letter.equals("F"))
letterF++;
f+=letterF;
System.out.print("Question A "+a);
System.out.print("Question B "+b);
System.out.print("Question C "+c);
System.out.print("Question D "+d);
System.out.print("Question F "+f);
}
Always use braces, even for single statements:
if (letter.equals("A"))
letterA++;
a+=letterA;}
if (letter.equals("B"))
letterB++;
b+=letterB;
if (letter.equals("C"))
letterC++;
c+=letterC;
if (letter.equals("D"))
letterD++;
d+=letterD;
if (letter.equals("F"))
letterF++;
f+=letterF;
Should always be:
if ("A".equals(letter)) { letterA++; }
else if ("B".equals(letter)) { letterB++; }
else if ("C".equals(letter)) { letterC++; }
else if ("D".equals(letter)) { letterD++; }
else if ("F".equals(letter)) { letterF++; }
else { throw new RuntimeException("Invalid Letter " + letter); }
Use single line statements if you want them visually compact, but
still use the braces as they guarantee the intent of what is to be
done in a given block, they also act as documentation of that intent
for people in the future ( people includes you ) to know what is going
on.
I see no valid reason for the single letter variables they are never used and I do not understand why they are there?
General Critique:
Always use braces:
Leaving out braces means only the first statement after the if is executed when the if matches, the next line(s) are always executed.
if (letter.equals("A"))
letterA++;
a+=letterA;
is actually
if (letter.equals("A")) { letterA++; }
a+=letterA;
Which means that line outside the braces will always get executed no matter what the expression inside the if test evaluates to. The indention of the second line is conflating that statement as part of the if block and it is not.
There is absolutely nothing to gain by leaving out braces and
everything to lose.
Neat code is easy to read and maintain and shows you care:
Always format your code consistently and not so densely so you can tell what is going on and what was wrong with the braces missing version.
Look at the best advertising it has plenty of white space, clean formatted code should have plenty of consistent white space as well so that our brains can quickly pattern match and scan for relevant things like matching pairs of braces.
Clean formatted code is just a keystroke away in all IDEs worth using.
Clean code shows you care about what you are doing and makes your question more appealing, which means others will care about their answer just as much.
Clean code earns you respect from your peers that know what they are looking at and sets you apart from those that do not care or know what they are looking at.
Most Importantly Clean Code is easier to reason about and has less
bugs, no subtle bugs and is orders of magnitude easier to maintain.
Always cover all the conditions:
Always use if/else if/else with mutually exclusive tests.
If all the if clauses are mutually exclusive and you match the first one, all the rest are still evaluated for no reason with the if/if/if/if structure. if/else if/else if/else if/else only evaluates until something matches or nothing matches.
Without else you do not cover all possible cases that do not match, which is usually and error that will just occur silently without the else.
Do not just cover the happy path, cover the exceptional path, but do it in the least defensive manner possible.
Explicit is always better than Implicit!
Avoid == null checks; avoid null completely:
Always compare literals to variables with .equals() to avoid possible NullPointerExceptions.
Avoid using null references completely, it is possible in every case, even the cases that it seems like a legitimate reason.
If Tony Hoare, the inventor of them thinks it is a mistake
who is to argue.
Always Name your variables descriptively!
I am not sure what letterA is supposed to represent anymore than what a is supposed to represent. So no one can tell you if these are correct because no one knows for sure what they represent semantically.
No Unnamed Numerical Constants ( Magic Numbers ):
final int A_GRADE = 18;
final int B_GRADE = 16;
final int C_GRADE = 14;
final int D_GRADE = 12;
Given the way they are used the names arguably could be even better
like MINIMUM_A_GRADE, but that is opinion based, the lesson is avoid
magic numbers.
Do range checks in the same direction:
Do range checks in the same direction so that the variable is visually in the middle of the comparison.
This makes it harder to break the logic later on and is self documenting that it is a range check.
if (count >= A_GRADE) { /* omitted */ }
else if (B_GRADE <= count && count < A_GRADE) { /* omitted */ }
else if (C_GRADE <= count && count < B_GRADE) { /* omitted */ }
else if (D_GRADE <= count && count < C_GRADE) { /* omitted */ }
else /* isF */ { /* omitted */ }
Which one is easier to reason about and maintain?
Do not hesitate to have many small methods if they make the code more self documenting:
private static boolean isA(final int count) { return count >= A_GRADE; }
private static boolean isB(final int count) { return B_GRADE <= count && count < A_GRADE; }
private static boolean isC(final int count) { return C_GRADE <= count && count < B_GRADE; }
private static boolean isD(final int count) { return D_GRADE <= count && count < C_GRADE; }
then you will have the following:
if (isA(count)) { /* omitted */ }
else if (isB(count)) { /* omitted */ }
else if (isC(count)) { /* omitted */ }
else if (isD(count)) { /* omitted */ }
else /* isF */ { /* omitted */ }
Which one is more obvious and self documenting, thus more
maintainable?
DRY - Don't Repeat Yourself:
Logically if (count >= A_GRADE) { letter = "A";} is exactly the same as if ("A".equals(letter)) { /* do stuff */ } so this is duplicated logic.
Instead of assigning a letter than checking that again, just put the logic in the original check.
if (count >= A_GRADE) { /* do stuff */ }
else if (B_GRADE <= count && count < A_GRADE) { /* do stuff */ }
else if (C_GRADE <= count && count < B_GRADE) { /* do stuff */ }
else if (D_GRADE <= count && count < C_GRADE) { /* do stuff */ }
else { /* omitted */ }
I see no valid reason for the single letter variables they are never used and I do not understand why they are there?
Duplicate logic means multiple places to have errors and multiple
places to edit to fix bugs, save yourself time and effort and follow
the DRY principle.
Move large logic blocks to method calls:
When do stuff is more than a few lines, refactor it to a method call.
if (count >= A_GRADE) { recordMarkA(); }
else if (B_GRADE <= count && count < A_GRADE) { recordMarkB(); }
else if (C_GRADE <= count && count < B_GRADE) { recordMarkC(); }
else if (D_GRADE <= count && count < C_GRADE) { recordMarkD(); }
else { recordMarkF(); }
More small methods with descriptive names is always better than large
monolithic blocks of inline code.
This question shows substantial effort and a genuine desire to learn:
So I crafted up what I would want a complete solution ( provided the partial/incomplete code ) to look like.
Q34081279.java
public class Q34081279
{
final static int A_GRADE = 18;
final static int B_GRADE = 16;
final static int C_GRADE = 14;
final static int D_GRADE = 12;
public static void main(final String[] args)
{
final String[] words = new String[]{}; /* this is just a placeholer, not provided in question */
final String[][] table = new String[][]{}; /* this is just a placehoder, not provided in question */
int markA = 0;
int markB = 0;
int markC = 0;
int markD = 0;
int markF = 0;
for (int row = 0; row < 100; row++)
{
int count = 0;
for (int column = 0; column < words.length; column++)
{
if (words[column].equals(table[row][column])) { count++; }
}
if (count >= A_GRADE) { System.out.format("%d = A", count); }
else if (B_GRADE <= count && count < A_GRADE) { System.out.format("%d = B", count); }
else if (C_GRADE <= count && count < B_GRADE) { System.out.format("%d = C", count); }
else if (D_GRADE <= count && count < C_GRADE) { System.out.format("%d = D", count); }
else { System.out.format("%d = F", count); }
System.out.println();
}
System.out.println(String.format("Question A %d", markA));
System.out.println(String.format("Question B %d", markB));
System.out.println(String.format("Question C %d", markC));
System.out.println(String.format("Question D %d", markD));
System.out.println(String.format("Question F %d", markF));
}
}
#Buddy is on the right rack but it's more than that. All of the if statements with more than one line need to have braces.
Otherwise only the first line is read by the compiler. According to Oracle:
Deciding when to omit the braces is a matter of personal taste. Omitting them can make the code more brittle. If a second statement is later added to the "then" clause, a common mistake would be forgetting to add the newly required braces. The compiler cannot catch this sort of error; you'll just get the wrong results.
eg:
if (letter.equals("A")) {
letterA++;
a+=letterA;
}
if (letter.equals("B")) {
letterB++;
b+=letterB;
}

Bubble Sort with compare method not running

This is a follow-up to my previous question that I asked yesterday. I wrote a Bubble Sort method that analyzes an array of strings and returns the NUMBER of comparisons that the method has made when ordering the array into alphabetical order (the assignment is to write several types of sorting methods and graph the number of comparisons each one makes, to see which is most efficient).
This is my code:
public static void main(String[] args)
{
String[] test_array = {"bill", "phil", "adam"};
/*
System.out.println(compare("orange", "boogie"));
*/
System.out.println(bubbleSort(test_array));
}
public static int compare(String a, String b)
{
int len = Math.min (a.length(),b.length());
// looping through every character. If cha is less than chb, the method returns -1, and so on.
for (int i = 0; i<len; i++) {
char cha = a.charAt(i);
char chb = b.charAt(i);
if (cha < chb) {
return -1;
} else if (cha > chb) {
return 1;
}
}
// Now we account for the length of the word, since it could be the same word.
if (a.length() < b.length())
return -1;
else if (a.length() > b.length())
return 1;
// Seems to be the same String, so return 0.
else
return 0;
}
public static int bubbleSort(String[] test_array) {
boolean swapped = true;
// Variable to track number of comparisons.
int compNumber = 0;
while (swapped == true) {
swapped = false;
for (int i = 1; i < test_array.length; i++) {
// Tracking the number of comparisons
compNumber++;
if (compare(test_array[i-1], test_array[i]) > 0) {
//Switching the variables by use of a temp variable
String temp = test_array[i-1];
test_array[i-1] = test_array[i];
test_array[i] = temp;
swapped = true;
}
else {
swapped = true;
}
}
}
return compNumber;
}
So the compare method compares two strings (given by the array) and determines if they are in alphabetical order (returns -1) or not (returns 1), or is the same word (returns 0). Then, the bubble sort method calls upon the compare method to go through the array, and it then makes the switches, while my compNumber variable counts the number of times the loop (therefore the number of comparisons) runs.
It compiles fine, but it unfortunately doesn't stop running and doesn't return anything. I've waited 5 minutes so I've determined that something is wrong, probably with my loops. I can't seem to find an issue, having manipulated the parameters of the loops several times. Could anyone help me out? Thanks in advance.
"swapped" will always be true, hence the while will never end looping.
I think you meant to put swapped = false in the else statement
you need to set one of these two swapped = false... or else you will never exit the while loop because swapped = true always ... probably changing the second one makes sense !
if (compare(test_array[i-1], test_array[i]) > 0) {
//Switching the variables by use of a temp variable
String temp = test_array[i-1];
test_array[i-1] = test_array[i];
test_array[i] = temp;
swapped = true;
}
else {
swapped = true;
}

How do I return these using only one method?

public class newClass {
public static void main(String[] args)
{
int nullValue=0;
int nullValue2=1;
int nullValue3=0;
int nullValue4=0;
int [] sourceArray = {4,5,6,7};
int [] targetArray = new int [4];
for (int i=0; i<sourceArray.length; i++)
{
nullValue+=sourceArray[i];
}
targetArray[0]=nullValue;
// I added all sourceArray elements together and passed it to targetArray[0]
for (int i=0; i<sourceArray.length; i++)
{
nullValue2*=sourceArray[i];
}
targetArray[1]=nullValue2;
// I multiplied all sourceArray elements together and assigned the result to targetArray[1]
for (int i=0; i<sourceArray.length; i++)
{
nullValue3 += getResult(sourceArray[i]);
}
targetArray[2]=nullValue3;
// I tried to add all odd numbers in sourceArray together and assign it to targetArray[2]
for (int i=0; i<sourceArray.length; i++)
{
nullValue4 += getResult(sourceArray[i]);
}
targetArray[3]=nullValue4;
// Same as previous except I need to do that with even numbers.
}
public static int getResult (int x)
{
if (x%2 == 0)
{
return x;
}
else
{
return 0;
}
}
}
You can read my comments above. I realize I can create another method for the last part but I am supposed to use only one method to return odds and evens. I tried almost anything. I can't think of any other ways anymore. Obviously I can't return x in both cases(Yeah I was too desperate to try that).
Straight to the point. I need one method to return x if it's odd or if it's even(We can say it's impossible by the look of that sentence already). I guess that's impossible to do with only one method. I'm not good at java yet so I'm not sure. Maybe there are other ways to do that with only one method which may be so easy. I worked on it for like 6 hours so I'm asking you guys. Thanks.
Create a method to return a boolean if the number is even like so
public static boolean isEven(int x)
{
return (x%2 == 0)
}
Then in your loop for evens
for (int i=0; i<sourceArray.length; i++)
{
if(isEven(x))
nullValue3 += sourceArray[i];
}
For odds just change to if(!isEven(x))
But this is probably deviating from the requirements as you probably want a method that returns an int and you could just put the condition directly in the loop and not need a method
If I understand your question correctly, what you want is to be able to tell the getResult function whether to give you only odd numbers or only even numbers. Without getting complicated, this is what I would do:
public static int getResult(int x, boolean evens) {
if (x % 2 == 0) {
return evens ? x : 0; // shorthand for: if(evens) {return x;} else {return 0;}
} else {
return evens ? 0 : x;
}
}
Simply speaking, I pass a flag value (evens) to the getResult function. This flag tells me whether to filter for even numbers or for odd numbers.
I test whether x is even (x % 2 == 0). If it is, I return it if I'm looking for evens, and I return 0 if I'm looking for odds. If x wasn't even, then I do the opposite.
It would be a little cleaner to write a pair of helper functions, which you could then call from your getResult function.
private static int getIfEven(x) {
if (x % 2 == 0) {
return x;
}
return 0;
}
private static int getIfOdd(x) {
if (x % 2 == 0) {
return 0;
}
return x;
}
public static int getResult(int x, boolean evens) {
// shorthand for:
// if (evens) {
// return getIfEven(x);
// } else {
// return getIfOdd(x);
// }
return evens ? getIfEven(x) : getIfOdd(x);
}
Depending on how much you're allowed to deviate from the current setup (I assume this is homework), you could also just write an isEven(int x) function and call that at each step through the loop, only adding the number if it is/isn't even.

How to solve exception in thread "main", java.lang.ArithmeticException: / by zero? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I keep getting an exception in thread "main":
java.lang.ArithmeticException: / by zero
at PersonalityTest.percentage(PersonalityTest.java:85)
at PersonalityTest.main(PersonalityTest.java:19)
And I want to add the count every time the scanner reads A or B and get the percentage of B.
import java.io.*;
import java.util.*;
public class PersonalityTest {
public static final int dimen = 4;
public static void main(String [] args) throws FileNotFoundException {
Scanner input = new Scanner(new File("personality.txt"));
PrintStream out = new PrintStream(new File("output.txt"));
int[] a = new int[4];
int[] b = new int[4];
welcome();
while (input.hasNextLine()) {
String letter = letter(input, out);
countNum(a, b, out, letter);
int[] percentage = percentage(a, b, out);
type(out, percentage);
out.println("");
}
}
public static void welcome () {
System.out.println("The Keirsey Temperament Sorter is a test that measures four independent dimensions of your personality: ");
System.out.println("1. Extrovert versus Introvert (E vs. I): what energizes you");
System.out.println("2. Sensation versus iNtuition (S vs. N): what you focus on");
System.out.println("3. Thinking versus Feeling (T vs. F): how you interpret what you focus on");
System.out.println("4. Judging versus Perceiving (J vs. P): how you approach life");
System.out.println("");
}
public static String letter (Scanner input, PrintStream out) {
String name = input.nextLine();
out.println(name + ":");
String letter = input.nextLine();
return letter;
}
public static void countNum(int[] a, int[] b, PrintStream out, String letter) {
int[] countA = new int[7];
int[] countB = new int[7];
int n = 0;
out.print("answers: [");
for (int i = 0; i < letter.length(); i++) {
int type = i % 7;
if (letter.charAt(i) == 'A' || letter.charAt(i) == 'a') {
n = 1;
}
else if (letter.charAt(i) == 'B' || letter.charAt(i) == 'b') {
n = 1;
}
countA[type] += n;
countB[type] += n;
if (type == 2 || type == 4 || type == 6) {
a[type / 2] = countA[type - 1]+ countA[type];
b[type / 2] = countB[type - 1]+ countA[type];
} else if (type == 0) {
a[0] = countA[0];
b[0] = countB[0];
}
for (int j = 0; j < dimen; j++) {
out.print(a[j] + "A-" + b[j] + "B," + " ");
}
}
out.print("]");
}
public static int[] percentage (int[] a, int[] b, PrintStream out) {
int[] percentage = new int [4];
out.print("percent B: [");
double n = 0.0;
for (int i = 0; i < dimen; i++) {
n = b[i] * 100 / (a[i] + b[i]); // <--- This is where I get error
percentage [i] = (int) Math.round(n);
out.print(percentage[i]);
}
out.print("]");
return percentage;
}
public static void type (PrintStream out, int[] percentage) {
String[] type = new String [4];
out.print("type: ");
for (int i = 0; i <= dimen; i++) {
while (percentage[i] > 50) {
if (i == 0) {
type[1] = "I";
}
else if (i == 1) {
type[2] = "N";
}
else if (i == 2) {
type[3] = "F";
}
else {
type[4] = "P";
}
}
while (percentage[i] < 50) {
if (i == 0) {
type[1] = "E";
}
else if (i == 1) {
type[2] = "S";
}
else if (i == 2) {
type[3] = "T";
}
else {
type[4] = "J";
}
}
out.print(Arrays.toString(type));
}
}
}
Your logic is very difficult to follow with all the a, b, +1, -1, /2, etc. You should try to reduce it to the smallest amount of code that demonstrates your problem. Odds are that you'll find the problem while you're doing that. You might also provide some sample input. Without one or both of these, it's very difficult to help with your problem.
Update: I'm seeing a number of things that look like problems now that I see what you're trying to do. Unless I'm mistaken, your input file has a name on the first line followed by 70 lines, each with a single letter on them?
For one thing, when read a letter and send it into countNum(), you only have one variable called "n" that you increment whether you see an A or a B, and then you add "n" to both A and B. That's not adding one to either the number of A's or the number of B's. It will always add one to both of them.
Next, since you only send a single letter into countNum(), the outer for loop will only execute one time. That means you'll only ever put a value into a[0] and b[0]. Further, because of the "n" problem, both values will always be 1. Thus the one time you get to the inner for loop, it will always print "1A-1B, 0A-0B, 0A-0B, 0A-0B" for the first part of the answer.
After that, it should be obvious why your percentage() method doesn't work. All but the first position of the array have zeroes in them.
Additional stuff: You define a constant "dimen" equal to 4 but you sometimes use the constant and sometimes use a literal "4". Pick one and stick with it. I'd recommend the constant, and I'd recommend naming it something meaningful, like "NUMBER_OF_PERSONALITY_DIMENSIONS", if that's what it is. For that matter, give all of your variables better names, and it will make things easier for you and me both. Also, in your type() method, you say for ( int i = 0; i <= dimen; i++ ) { to iterate over an array which I think only has 4 elements. That's going to break. Finally, as you kind of mentioned elsewhere, don't pass arrays around, mutating them in multiple different methods. That's a good way to get lost. In general, make methods non-side-effecty. Instead of modifying the things you pass to them, return the important values from the method.
In general, I think you need to take a break and straighten out in your head what you're trying to do. The logic doesn't seem to make any sense.
I don't know if you've learned about this kind of thing yet, but you might consider splitting this into two classes: one to read in the data and one to tally it up. The tallying one might look something like:
class Tallier {
private int numberOfAs;
private int numberOfBs;
private int totalEntriesSoFar;
private int[] typeATotals;
private int[] typeBTotals;
public void gotNewA() {...}
public void gotNewB() {...}
}
You are dividing by zero, the problem is that. On the mentioned line, you have:
n = b[ i ] * 100 / ( a[ i ] + b[ i ] );
Sometimes, a[i]+b[i] is zero. Maybe the problem will be solved by a check like this:
for( int i = 0; i < dimen; i++ ) {
if (a[ i ] + b[ i ]!= 0)
n = b[ i ] * 100 / ( a[ i ] + b[ i ] );
else
//assign a number to n for this situation
percentage [ i ] = ( int ) Math.round( n );
out.print( percentage[ i ] );
}
But logically, you should not divide a number by zero. Then maybe you have to correct your algorithm.

Categories

Resources