Hello my program fails to run with ArrayIndexOutofBoundsExeption. I get this error when I run it:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -35
at RoulleteChecker.main(RoulleteChecker.java:134)
Here is my code:
import javax.swing.JOptionPane;
import javax.swing.JTextArea;
public class RoulleteChecker {
public static void main( String args[] )
{
int a[] = new int[37];
for ( long roll = 1; roll <=99999999; roll++ ) {
a[0] = 1 + ( int ) ( Math.random() * 34);
switch ( a[0] ) {
case 0:
++a[1];
break;
case 1:
++a[2];
break;
case 2:
++a[3];
break;
case 3:
++a[4];
break;
case 4:
++a[5];
break;
case 5:
++a[6];
break;
case 6:
++a[7];
break;
case 7:
++a[8];
break;
case 8:
++a[9];
break;
case 9:
++a[10];
break;
case 10:
++a[11];
break;
case 11:
++a[12];
break;
case 12:
++a[13];
break;
case 13:
++a[14];
break;
case 14:
++a[15];
break;
case 15:
++a[16];
break;
case 16:
++a[17];
break;
case 17:
++a[18];
break;
case 18:
++a[19];
break;
case 19:
++a[20];
break;
case 20:
++a[21];
break;
case 21:
++a[22];
break;
case 22:
++a[23];
break;
case 23:
++a[24];
break;
case 24:
++a[25];
break;
case 25:
++a[26];
break;
case 26:
++a[27];
break;
case 27:
++a[28];
break;
case 28:
++a[29];
break;
case 29:
++a[30];
break;
case 30:
++a[31];
break;
case 31:
++a[32];
break;
case 32:
++a[33];
break;
case 33:
++a[34];
break;
case 34:
++a[35];
break;
}
}
JTextArea outputArea = new JTextArea();
outputArea.setText( "Lets see: " + a[0-35] );
JOptionPane.showMessageDialog( null, outputArea,
"Searching for the frequency: 99999999 times", JOptionPane.INFORMATION_MESSAGE );
System.exit( 1 );
}
}
Please my head is going to blow with this. I think that my error is on the a variable.
The error is from this line:
outputArea.setText( "Lets see: " + a[0-35] );
The - sign is the arithmetic minus operator. So, 0 - 35 is -35, which is, of course, not a valid index. I'm guessing you wanted to print the range of 0 to 35, which could be done with Arrays.toString:
outputArea.setText( "Lets see: " + Arrays.toString(a));
First, all that gigantic switch could be replaced by this:
++a[a[0] + 1];
Then, as other people already pointed out, a[0 - 35] do not means what you want, it will not magically grab the positions 0 to 35 of the array. It is just the math result of 0 subtracted to 35, which is -35. There is no position -35 on an array.
To represent the array as a String, we can use Java 8 Streams:
IntStream.of(a).limit(36).boxed().collect(Collectors.toList()).toString().replace(", ", "\n")
What this does:
This will convert the int[] to a IntStream (the IntStream.of(a) part).
Lets limit to get only the first 36 elements (since you wanted the elements from 0 to 35). This is what the .limit(36) does.
Then the IntStream will be converted to a Stream<Integer> (the .boxed()) part.
Then it will be converted to a List<Integer> (the .collect(Collectors.toList())) part.
Then it will be converted to a String (the .toString() part).
Since that String will be too long to be presented on a single line, it is a good idea to add some line breaks, this is what the .replace(", ", "\n") does.
Finally, you don't need the System.exit(1);, it has no purpose here.
With that, this is your resulting code:
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import javax.swing.JOptionPane;
import javax.swing.JTextArea;
public class RoulleteChecker {
public static void main(String args[]) {
int a[] = new int[37];
for (long roll = 1; roll <= 99999999; roll++) {
a[0] = 1 + (int) (Math.random() * 34);
++a[a[0] + 1];
}
JTextArea outputArea = new JTextArea();
outputArea.setText("Lets see: " + IntStream.of(a).limit(36).boxed().collect(Collectors.toList()).toString().replace(", ", "\n"));
JOptionPane.showMessageDialog(null, outputArea,
"Searching for the frequency: 99999999 times", JOptionPane.INFORMATION_MESSAGE);
}
}
New improved answer:
To show line numbers, I think that the Streams approach will not work or it would be overly complex. So lets use an specialized method instead:
import javax.swing.JOptionPane;
import javax.swing.JTextArea;
public class RoulleteChecker {
private static final int TIMES = 99999999;
public static void main(String args[]) {
int a[] = new int[36];
for (long roll = 1; roll <= TIMES; roll++) {
int r = (int) (Math.random() * a.length);
++a[r];
}
JTextArea outputArea = new JTextArea();
outputArea.setText("Lets see:\n" + asString(a));
JOptionPane.showMessageDialog(null, outputArea,
"Searching for the frequency: " + TIMES + " times", JOptionPane.INFORMATION_MESSAGE);
}
private static String asString(int[] s) {
StringBuilder sb = new StringBuilder(8 * s.length);
for (int i = 0; i < s.length; i++) {
sb.append(i + 1).append(": ").append(s[i]).append("\n");
}
return sb.toString();
}
}
There is a few more differences here:
Since the 0th position of the array is just to temporarily hold the newly generated number, lets get it out of the array entirely. This is what the r variable is. And since I removed the 0th position of the array, so I removed the + 1 on the ++a[a[0] + 1] which became simply ++a[r].
I moved the number of times (99999999) to a constant. This makes it easier to make it changeable if needed.
Again, since I removed the 0th position of the array, I also removed the 1 + from the line that calculated a random number. Further, I made it grab the size of the array dynamically, so you don't need to track the array size both when creating it and when randomly accessing one of its positions.
The asString method should be pretty easy straightforward. The only gotcha is the i + 1, where the + 1 has the purpose to show the indexes starting at 1 instead of 0.
The parameter on the StringBuilder's constructor in the asString method is just a total String size estimative for performance, it is not an important thing.
This is Java:
a[0-35]
actually means:
a[-35]
What makes you think -35 is a valid index? You see --- all the information that you need to fix the bug is there - you just have to read the exception message carefully. It tells you the position of the error, and it tells you the invalid index!
And btw: consider your switch statement.
Do you really think you need to write down a switch that more or less does
case i:
i++;
?
Related
I'm trying to convert binary to decimal, how do I change my code to be able to do that? Where did I mess up?
i tried looking at other examples, looking at java api and watching videos but i still can't figure out what mistake i have made.
package Calculator;
import java.util.Scanner;
public class Calculator {
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
System.out.println("(2) Convert binary to decimal");
System.out.println("\n\n Please enter your choice: ");
int choice = scan.nextInt();
if(choice == 2){
scan.nextLine();
//prompt for user input
System.out.println("Please enter a binary number: ");
String binary = scan.nextLine();
char[] binaryArray = binary.toCharArray();
int i=1;
int integer=0;
//potential problem somewhere around here?
while(i<8){
if(binaryArray[i]==0) {
++i;
}else if(binaryArray[i]==1) {
switch(i) {
case 1:
integer+=128;
++i;
break;
case 2:
integer+=64;
++i;
break;
case 3:
integer+=32;
++i;
break;
case 4:
integer+=16;
++i;
break;
case 5:
integer+=8;
++i;
break;
case 6:
integer+=4;
++i;
break;
case 7:
integer+=2;
++i;
break;
case 8:
integer+=1;
++i;
break;
}
}
}
System.out.println("The decimal value of the binary number is: "+ integer);
scan.close();
}
}
}
The input is always 0. I've tried 11010110, 11111111,and 01010111. Always 0. I know the problem lies somewhere with my integer value not changing but I can't figure out what it specifically is.
This is happening because you are reading the input, and converting into an array of char.
Anywhere where you are making your comparisons to an int, you should instead be doing a comparison to a char, by wrapping your values in single quotations.
while(i<8){
if(binaryArray[i]=='0') {
++i;
}else if(binaryArray[i]=='1') {
switch(i) {
case 1:
integer+=128;
++i;
break;
case 2:
integer+=64;
++i;
break;
case 3:
integer+=32;
++i;
break;
case 4:
integer+=16;
++i;
break;
case 5:
integer+=8;
++i;
break;
case 6:
integer+=4;
++i;
break;
case 7:
integer+=2;
++i;
break;
case 8:
integer+=1;
++i;
break;
}
}
Others have already pointed out that you have got confused between 0 and 1, and '0' and'1'`.
Other problems:
Your i starts at 1, so you miss the most significant bit;
You will never actually hit case 8: in the switch because of the while (i < 8) loop guard.
This doesn't work unless you enter exactly 8 bits.
You can write the entire while loop in a much more concise way:
for (int i = 0; i < binaryArray.length; i++) {
integer *= 2; // shift the digits along by 1 place
if (binaryArray[i] == '1') {
integer += 1; // set the least significant bit.
}
}
You should get away from all those switch statements.
Say you have "10101101" as input.
set val = 0;
Then either multiply by val by 2 or shift left 1 bit. They're the same. It is important
you do this before adding the next bit.
Start from the left and if it's a '1', add a 1 to val. Otherwise, add 0.
Then repeat starting at multiply until you've gone thru the string.
val should then have the decimal version when you print it.
I programmed a game.
I used switch case to implement a state machine.
The problem is that in case ZIEHEN_SP the break statement doesn't work.
When I debug it, the compiler just step over the break statement and goes to the next case ZIEHEN_BA.
I commented the part where the compiler ignores the break statement.
Why?
import java.util.*;
import java.util.Scanner;
import java.io.*;
class BlackJack2 {
static int chips = 100;
static int einsatz = 0;
enum State { INIT, EINSATZ,ZIEHEN_SP, ZIEHEN_BA}
static State state = State.INIT;
static ArrayList<Integer> bankKarten = new ArrayList<Integer>();
static ArrayList<Integer> spielerKarten = new ArrayList<Integer>();
static Scanner scanner = new Scanner(System.in);
static String s = "";
static int eingabe = 0;
static void init(){
System.out.println("\nEin neues Spiel beginnt: ");
bankKarten.clear();
spielerKarten.clear();
bankKarten.add(giveCard());
spielerKarten.add(giveCard());
}
static void chipsSetzen(){
einsatz = 0;
if(chips == 0){
System.out.print("\nSie haben " + chips + " Chips!");
System.exit(1);
}
do{
System.out.print("\nSie haben " + chips + " Chips");
System.out.print("\nWie viel moechten Sie setzen? ");
try{
einsatz = Integer.parseInt(scanner.next());
} catch(Exception e){
}
} while(einsatz <= 0 || einsatz > chips);
chips -= einsatz;
}
static int sumSpielerKarten(){
int sum=0;
for(int i=0; i<spielerKarten.size(); i++){
sum +=spielerKarten.get(i);
}
return sum;
}
static int sumBankKarten(){
int sum=0;
for(int i=0; i<bankKarten.size(); i++){
sum +=bankKarten.get(i);
}
return sum;
}
static int giveCard(){
return (int)(Math.random()*11+1);
}
static boolean oneMoreCard(){
int ss = sumSpielerKarten();
if(ss >= 21){
return false;
} else {
do{
System.out.print("\nMoechten sie eine witere Karte ziehen? (y/n): ");
s = scanner.next();
if(s.equals("y")){
return true;
} else if(s.equals("n")){
return false;
}
} while(!s.equals("y") || !s.equals("n"));
}
return false;
}
static String evaluateWinner(int s, int b){
String ret = "";
if(b > 21 || (s > b && s<=21) || s == 21 && b != 21){
ret = "Player";
} else if(s > 21 || b > s || b == 21 && s != 21){
ret = "Bank";
} else if(b == s){
ret = "Both";
}
return ret;
}
static int updateMoney(int s, int b){
String winner = evaluateWinner(s, b);
int newChips = 0;
if(winner == "Player"){
newChips = einsatz*2 + chips;
} else if(winner == "Both"){
newChips = einsatz + chips;
} else if(winner == "Bank"){
newChips = chips;
}
System.out.println("Winner: "+ winner);
return newChips;
}
static void showCards(){
System.out.print("\nBank:\t");
for(int i=0; i<bankKarten.size(); i++){
System.out.print( "[" + bankKarten.get(i) + "]");
}
System.out.println("\t= " + sumBankKarten());
System.out.print("Player:\t");
for(int i=0; i<spielerKarten.size(); i++){
System.out.print( "[" + spielerKarten.get(i) + "]");
}
System.out.println("\t= " + sumSpielerKarten());
}
static void banksTurn(){
int sb = sumBankKarten();
int ss = sumSpielerKarten();
if(sb != 21 && ss != 21 && ss < 21){
while(sb < 17 || (ss > sb && sb < 17)){
bankKarten.add(giveCard());
}
}
updateMoney(ss, sb);
}
public static void main(String args[]){
while(true){
switch(state){
case INIT:
init();
state = State.EINSATZ;
break;
case EINSATZ:
chipsSetzen();
state = State.ZIEHEN_SP;
break;
case ZIEHEN_SP:
showCards();
while(oneMoreCard()){
spielerKarten.add(giveCard());
showCards();
}
state = State.ZIEHEN_BA;
break; // << Compiler ignores this statement and goes directly to case ZIEHEN_BA
case ZIEHEN_BA:
banksTurn();
state = State.INIT;
break;
}
}
}
}
Because you change state to a value that matches with State.ZIEHEN_BA condition :
state = State.ZIEHEN_BA;
So here :
while(true){
...
state = State.ZIEHEN_BA;
break;
case ZIEHEN_BA:
banksTurn();
state = State.INIT;
break;
...
}
the case ZIEHEN_BA is executed at the next iteration of the loop.
What Eclipse shows may be an optimization of the JVM performed at runtime or by the compiler. You could disassemble the class to have more information.
EDIT
I have done the test and i don't think it is a compiler optimization.
Look at this minimal example where I don't set the state in the case :
public class TestSwitch {
public enum MyEnum {
A, B
};
public static void main(String[] args) {
MyEnum state = MyEnum.A;
while (true) {
switch (state) {
case A:
break;
case B:
break;
}
}
}
}
Here is the disassembled code of the main() method :
public static void main(java.lang.String[]);
Code:
0: getstatic #18 // Field a/TestSwitch$MyEnum.A:La/TestSwitch$MyEnum;
3: astore_1
4: invokestatic #24 // Method $SWITCH_TABLE$a$TestSwitch$MyEnum:()[I
7: aload_1
8: invokevirtual #27 // Method a/TestSwitch$MyEnum.ordinal:()I
11: iaload
12: tableswitch { // 1 to 2
1: 36
2: 39
default: 39
}
36: goto 4
39: goto 4
And look at the version where I set the state in case A to enter in case B :
public class TestSwitch {
public enum MyEnum {
A, B
};
public static void main(String[] args) {
MyEnum state = MyEnum.A;
while (true) {
switch (state) {
case A:
state = MyEnum.B;
break;
case B:
break;
}
}
}
}
Here is the disassembled code of the main() method :
public static void main(java.lang.String[]);
Code:
0: getstatic #18 // Field a/TestSwitch$MyEnum.A:La/TestSwitch$MyEnum;
3: astore_1
4: invokestatic #24 // Method $SWITCH_TABLE$a$TestSwitch$MyEnum:()[I
7: aload_1
8: invokevirtual #27 // Method a/TestSwitch$MyEnum.ordinal:()I
11: iaload
12: tableswitch { // 1 to 2
1: 36
2: 43
default: 43
}
36: getstatic #31 // Field a/TestSwitch$MyEnum.B:La/TestSwitch$MyEnum;
39: astore_1
40: goto 4
43: goto 4
There is not optimization in this compiled code.
After case A execution :
36: getstatic #31 // Field a/TestSwitch$MyEnum.B:La/TestSwitch$MyEnum;
39: astore_1
the next instruction is a goto to the loop :
40: goto 4
So the optimization is probably performed at runtime by the JVM or the Eclipse debugger.
The compiler optimized your code :-)
As you set the switch variable to State.ZIEHEN_BA and there's nothing to be executed in between (while (true) and reentering the switch) that's exactly the next lines to be executed.
I'm not sure if it's supposed to behave that way (changing variable switched on inside switch will cause following cases to be checked) but in your case I totally agree with the compiler.
As you can see in this example, this behaviour is not always the case:
public static void main(String[] args) {
int i = 3;
switch(i) {
case 1:
System.out.println("1:");
break;
case 2:
System.out.println("2:");
break;
case 3:
System.out.println("3:");
i = 5;
break;
case 4:
System.out.println("4:");
break;
case 5:
System.out.println("5:");
i = 5;
break;
case 6:
System.out.println("6:");
break;
case 7:
System.out.println("7:");
break;
default:
break;
}
System.out.println("I = " + i);
}
Results in
3:
I = 5
This is an optimization. When you set the state to ZIEHEN_BA, the compiler knows it will get there as a next step. Without optimization, there would just be some aditional steps, but it will get there anyway:
Set the state; do the break; goto the while(true), now do the switch and...it gets to ZIEHEN_BA. So that is equivalent to going there directly.
Actually , compiler is not ignoring the break.
As you set state = State.ZIEHEN_BA in the existing case statement
So after invoking break it's going straight to ZIEHEN_BA in the next iteration of while(ture) loop .... :)
It may seems that it's directly going to ZIEHEN_BA by ignoring break but it's entering there in the following iteration.
The main program which you wrote is an unbreakable loop. Once if we see the code properly, you were assigning the state to the other case whenever some case was hit. And moreover you never ended the loop. The while loop doesn't know where to stop. Not exactly sure what you want to do.
FYI, the break is not skipped but it worked only break the switch loop. And I guess you expectation is to break the while loop...
If you want the code stop at a particular point, place a break for while loop. Again placing break; inside switch doesn't work as it breaks the switch loop. Instead try to set a Boolean variable before while and change the variable value to false where ever you want the loop to break.
This question already has answers here:
How do I generate random integers within a specific range in Java?
(72 answers)
Closed 5 years ago.
I am required to implement an interface as part of my final school assignment for my Java class. The overridden interface is supposed to print a short message describing how a football player celebrates being drafted in the NFL, something like this:
System.out.println("name dances to celebrate his draft");
However my interface is not printing the message when I put it into the methods which allow the user to add a player to their roster. Here is the overridden interface in the program:
//Overridden celebrate method
#Override
public void celebrate(int i, int place){
int randomInteger;
if (place == 0) //Player is offensive
{
randomInteger = random1Thru6();
//players() is a method that contains all the players in the team
//'place' refers to the players location in the array of players on the team
switch (randomInteger)
{
case 1: System.out.println(players(i).get(place) + " dances to celebrate his draft!");
break;
case 2: System.out.println(players(i).get(place) + " cartwheels to celebrate his draft!");
break;
case 3: System.out.println(players(i).get(place) + " throws a party to celebrate his draft!");
break;
case 4: System.out.println(players(i).get(place) + " sings to celebrate his draft!");
break;
case 5: System.out.println(players(i).get(place) + " gets root beer for everyone to celebrate his draft!");
break;
case 6: System.out.println(players(i).get(place) + " gets donuts to celebrate his draft!");
}
}
else if (place == 1) //Player is defensive
{
randomInteger = random1Thru6();
switch (randomInteger)
{
case 1: System.out.println(players(i).get(place) + " dances to celebrate his draft!");
break;
case 2: System.out.println(players(i).get(place) + " cartwheels to celebrate his draft!");
break;
case 3: System.out.println(players(i).get(place) + " throws a party to celebrate his draft!");
break;
case 4: System.out.println(players(i).get(place) + " sings to celebrate his draft!");
break;
case 5: System.out.println(players(i).get(place) + " gets root beer for everyone to celebrate his draft!");
break;
case 6: System.out.println(players(i).get(place) + " gets pizza to celebrate his draft!");
}
}
}
I am supposed to have one different celebratory response for offensive and defensive positions as is shown in the code above.
Here is the referenced random1Thru6() method:
public int random1Thru6() { //used to get a random number from 1 to 6
int randomInteger = (int)Math.random() * 10;
//this is supposed to call the method over and over again until it gives a number from 1-6 but it has been printing 7-9 as well
if (randomInteger > 6)
random1Thru6();
return randomInteger;
}
And here is the players() method:
//holds and prints all the players
public ArrayList<String> players(int i) {
ArrayList<String> returnedList = new ArrayList<>();
// Christian McCaffrey is a Running Back, Corn Elder is a Corner Back for the Carolina Panthers
ArrayList<String> Players1 = new ArrayList<String>();
Players1.add("Christian McCaffrey");
Players1.add("Corn Elder");
//Jake Butt is a Tight End, Brendan Langley is a Corner Back for the Denver Broncos
ArrayList<String> Players2 = new ArrayList<String>();
Players2.add("Jake Butt");
Players2.add("Brendan Langley");
//Ryan Switzer is a Wide Receiver, Taco Charlton is a Defensive End for the Dallas Cowboys
ArrayList<String> Players3 = new ArrayList<String>();
Players3.add("Ryan Switzer");
Players3.add("Taco Charlton");
//Dalvin Cook is a Running Back, Ifeadi Odenigbo is a Defensive Line for the Minnesota Vikings
ArrayList<String> Players4 = new ArrayList<String>();
Players4.add("Dalvin Cook");
Players4.add("Ifeadi Odenigbo");
switch (i)
{
case 1: returnedList.addAll(Players1);
break;
case 2: returnedList.addAll(Players2);
break;
case 3: returnedList.addAll(Players3);
break;
case 4: returnedList.addAll(Players4);
break;
}
return returnedList;
}
Here is how the celebrate() method is called:
for (int l = 0; l < players(i).size(); l++)
{
if (choosePlayer.equalsIgnoreCase(players(i).get(l)))
{
addPlayer(players(i).get(l));
celebrate(i, l);
enterRoster();
}
}
And:
addPlayer(players(i).get(place));
celebrate(i, place);
enterRoster();
addPlayer(int i, int place) is a method that adds the player for team 'i' in the position of 'place' in the team's player array into the ArrayList of the user's roster.
NOTE: I checked what number was being called by random1Thru6() as suggested in a comment and now I understand why it wasn't printing the celebrate message, since I had (int)Math.random() * 10 it was always returning 0 so I changed it to:
double randomDouble = Math.random() * 10;
int randomInteger = (int)randomDouble;
Now it prints the celebrate messages but random1Thru6() is now returning all numbers 1-9, please explain how I can make this method call itself recursively until it will return a number 1-6.
Thank you delephin for your comment!
NOTE: I have accepted delephin's answer shown below, thank you all for the help!
Add to your main class:
static Random r = new Random();
static {
r.setSeed(System.currentTimeMillis());
}
and change your randomizer method to something like this:
public int random1Thru6() {
return r.nextInt(6) + 1;
}
From a quick test, your previous randomizer was returning zeros.
So I am making a program in Java on a BlueJ environment that computes Binary expansion. However, I can't seem to figure out how to add powers more than 9 in the output.
If I have an input power of anything more than 9 the program goes haywire, presumably because there are no cases after 9.
Also, I personally feel my program in general is extremely inefficient but I just did it this morning and this was the first approach I saw, so if you see a way to make it more efficient than using switch case, that'd be great too.
This is my code so far. It's not all mine, but I'm not sure if intellectual property and stuff applies on here, so just putting it out there.
import java.util.*;
class Binomial_Theorem_Expansion
{
public static void main(String args[])
{
Scanner s=new Scanner(System.in);
System.out.println("Enter the value of x in (x+a)^n");
int x=s.nextInt();
System.out.println("Enter the value of a in (x+a)^n");
int a=s.nextInt();
System.out.println("Enter the value of n in (x+a)^n");
int n=s.nextInt();
System.out.println ("The expanded answer is");
int r=0;
int powx=n;
while (r<=n)
{
long nCr=calculatenCr(n,r);
if(nCr!=-1)
{
double y=Math.pow((double)x,(double)n-r);
double z=Math.pow((double)a,(double)r);
switch (powx)
{
case 0: System.out.print ("("+nCr*y*z);
break;
case 1: System.out.print ("("+nCr*y*z+"x");
break;
case 2: System.out.print ("("+nCr*y*z+"x\u00B2");
break;
case 3: System.out.print ("("+nCr*y*z+"x\u00B3");
break;
case 4: System.out.print ("("+nCr*y*z+"x\u2074");
break;
case 5: System.out.print ("("+nCr*y*z+"x\u2075");
break;
case 6: System.out.print ("("+nCr*y*z+"x\u2076");
break;
case 7: System.out.print ("("+nCr*y*z+"x\u2077");
break;
case 8: System.out.print ("("+nCr*y*z+"x\u2078");
break;
case 9: System.out.print ("("+nCr*y*z+"x\u2079");
break;
case 10: System.out.print ("("+nCr*y*z+"x\u2071\u00B2");
break;
}
switch (r) {
case 0: System.out.print (")");
break;
case 1: System.out.print ("y"+")");
break;
case 2: System.out.print ("y\u00B2"+")");
break;
case 3: System.out.print ("y\u00B3"+")");
break;
case 4: System.out.print ("y\u2074"+")");
break;
case 5: System.out.print ("y\u2075"+")");
break;
case 6: System.out.print ("y\u2076"+")");
break;
case 7: System.out.print ("y\u2077"+")");
break;
case 8: System.out.print ("y\u2078"+")");
break;
case 9: System.out.print ("y\u2079"+")");
break;
}
r++;
if (r<=n)
{
System.out.print ("+");
}
powx--;
}
}
}
public static long calculatenCr(int n,int r)
{
long res=1;
if(n>=r)
{
res=getFact(n)/(getFact(n-r)*getFact(r));
return res;
}
else return -1;
}
public static long getFact(int n)
{
long f=1;
for(int i=n;i>=1;i--)
{
f*=i;
}
return f;
}
}
Thanks for any constructive input. :)
presumably because there are no cases after 9.
Your code is using UNICODE superscript characters, and the cases that you have cover only numbers zero through ten for x and zero through nine for y.
You can fix this by defining a method that produces a superscript UNICODE conversion of a multidigit number, and calling it from both places where you need to produce such representation:
switch (powx) {
case 0: System.out.print ("("+nCr*y*z);
break;
case 1: System.out.print ("("+nCr*y*z+"x");
break;
default: System.out.print ("("+nCr*y*z+"x"+toSuperscript(powx));
break;
}
The other switch (i.e. switch (r)) should be converted in a similar way.
You can implement String toSuperscript(int n) by producing a decimal representation of n, and then replacing '0' with '\u2070', '1' with '\u00B9', and so on.
I am trying to get practice on loops and switch statements and trying to figure out the following issue.
The output depends on the integer day value.
For example if the user enters 8 then it will print the first 8 lines as follows:
On the 8th day of holidays, I did Eight jumping jacks,
....
...
On the 3rd day of holidays, I did Three pull downs,
...
..
On the 1st day of holidays, I did One downhill sprint.
So to solve this problem, I have used a switch statement in a for loop and then wanted to use another switch statement to put the appropriate suffix for the day number. Eg: 1st, 2nd etc
I have done the following but I am stuck badly and would really appreciate if they can help me out.
int day = in.nextInt();
for (int i = 0; i < day; i++) {
switch (day) {
// Also, do I add another switch statement here for suffix?
}
}
Loop is not required, you can do it as follows:
int day = in.nextInt();
switch(day){
case 10:
System.out.println("statement 10");
case 9:
System.out.println("statement 9");
case 8:
System.out.println("statement 8");
case 7:
System.out.println("statement 7");
case 6:
System.out.println("statement 6");
case 5:
System.out.println("statement 5");
case 4:
System.out.println("statement 4");
case 3:
System.out.println("statement 3");
case 2:
System.out.println("statement 2");
case 1:
System.out.println("statement 1");
}
So, when the input is 8, it will print your all statements starting from 8 to 1 as you require.
Use methods for each operation. Each method will have its own switch:
private String getDaySuffix(int day) {
switch(day) {
case 1: return "st";
// ...
}
}
private String getActivity(int day) {
switch(day) {
case 1: return "One downhill sprint";
// ...
}
}
for (int i = 0; i < day; i++) {
String s = "On the " + day + getDaySuffix(day) +
" day of holidays, I did " + getActivity(day);
}
That way, you improve cohesion: each method does what it is supposed to do, and nothing else.
Assume day has value entered by user.. then..
for(int i=day;i<=day && i!=0;i--)
{
switch(i)
{
case 8 :
On the 8th day of holidays, I did Eight jumping jacks,
break;
.
.
.
case 3 :
On the 3rd day of holidays, I did Three pull downs,
break;
.
.
case 1 :
On the 1st day of holidays, I did One downhill sprint.
break;
default :
break;
}
}
To get the right suffix you could use a switch:
private static String getSuffix(final int number) {
switch (number) {
case 0: throw new IllegalArgumentException();
case 1: return "st";
case 2: return "nd";
case 3: return "rd";
default:return "th";
}
}
To geht the word form of a number you could use an array:
final static String[] numbers = new String[] {
"zero", "one", "two", "three", "four",
"five", "six", "seven", "eight", "nine", "ten"
};
To use this, just append numbers[yourInt] to your string.
numbers[5] e.g. will be "five".
Putting everything together might look like this (It also appends an s to the activity if needed):
public class Main {
final static String[] numbers = new String[] {
"zero", "one", "two", "three", "four",
"five", "six", "seven", "eight", "nine", "ten"
};
final static String pattern = "On the %d%s day of holidays, I did %s %s%s\n";
final static Scanner in = new Scanner(System.in);
public static void main(String[] args) {
final int day = in.nextInt();
final String activity;
switch (day) {
case 1 : activity = "downhill sprint"; break;
// ...
case 3 : activity = "pull down"; break;
//...
case 8 : activity = "jumping jack"; break;
default : activity = "";
}
if (!activity.equals(""))
System.out.printf(pattern, day, getSuffix(day), numbers[day], activity, day > 1 ? "s" : "");
}
private static String getSuffix(final int number) {
switch (number) {
case 0: throw new IllegalArgumentException();
case 1: return "st";
case 2: return "nd";
case 3: return "rd";
default:return "th";
}
}
}
Converting the number to a word can be done with a switch statement, in the case where you are having a limited (and small) number. For example, only numbers one to 10.
It would be as follows:
String numberWord;
switch (day)
{
case 1:
suffix = "one";
break;
case 2:
suffix = "two";
break;
case 3:
suffix = "three";
break;
//ETC
default: break;
}
However, if you wish for a much larger range of numbers, I recommend you check out the following page:
http://www.rgagnon.com/javadetails/java-0426.html
It contains a method which converts a number to a word. It converts into the billions.
Regarding the suffix, a similar solution to that of above can be used. Watch out for 11, 12 and 13 though, because they have their unique suffixes.
String GetSuffix (int number)
{
int lastTwoDigits = number % 100;
if (lastTwoDigits == 11 || lastTwoDigits == 12 || lastTwoDigits == 13)
{
return "th";
}
switch (number % 10)
{
case 1:
suffix = "st";
break;
case 2:
suffix = "nd";
break;
case 3:
suffix = "rd";
break;
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 0:
suffix = "th";
break;
default: break;
}
//This shouldn't happen
return "";
}
Here's an example of how to use this:
String result = "On the " + Integer.toString(day) + GetSuffix(day) + " day of holidays, I did " + EnglishNumberToWords(day) + " jumping jacks";