so I'm currently working on an assignment that I just can't seem to finish. Well I have everything finished but would like the extra credit. I've been looking around the web and can't really seem to find exactly what I'm looking for.
public class PascalTester
{
public static void main(String[] args)
{
Scanner kb = new Scanner(System.in);
System.out.println("Welcome to the Pascal's Triangle program!");
System.out.println("Please enter the size of the triangle you want");
int size = kb.nextInt();
int[][] myArray = new int[size][size];
myArray = fillArray(myArray);
//myArray = calculateArray(myArray);
printArray(myArray); //prints the array
}
private static int[][] fillArray(int[][] array)
{
array[0][1] = 1;
for (int i = 1; i < array.length; i++)
{
for (int j = 1; j < array[i].length; j++)
{
array[i][j] = array[i-1][j-1] + array[i-1][j];
}
}
return array;
}
private static void printArray(int[][] array)
{
for (int i = 0; i < array.length; i++)
{
for (int j = 0; j < array[i].length; j++)
{
if(array[i][j] != 0)
System.out.print(array[i][j] + " ");
}
System.out.println();
}
}
}
The only issue that I'm having now is to properly format the output to look like an actual triangle. Any suggestions would be very helpful at this point in time. Thanks in advance
One approach to this, is, assuming you have all numbers formatted to the same width, is to treat the problem as that of centering the lines.
Java Coding left as exercise to reader but essentially:
for lineText : triange lines
leadingSpacesCount = (80/2) - lineText.length();
print " " x leadingSpacesCount + lineText
Try to use the technique at http://www.kodejava.org/examples/16.html to make an array with array.length - i - 1 spaces (need to add the number spaces between numbers.. and 2 number of 2 digit numbers if any..).
Print this array at the start of the outer for loop.
The challenge here is that you want to start printing at the top of the triangle, but you don't know where to center each row until you get to the last (and widest) row of the triangle. The trick is to not print anything until you know how wide the last row is. One way to do this is to generate all the rows as String (or StringBuilder) objects and compute the maximum width. Then, from the top, center each line by first printing an appropriate number of spaces. The correct number of spaces will be
(maxLineLength - currentLine.length()) / 2
Alternatively, you can simply assume a maximum line length and center all lines in that width. If the longer lines exceed the maximum width, then the triangle will be distorted below a certain row. (Just be sure to not try printing a negative number of spaces!)
If anyone is looking for the actual code to do this take a look at my implementation in Java, it's similar to what Craig Taylor mentioned (numbers formatted to the same width) plus it uses an algorithm to compute the elements without memory (or factorials).
The code has comments explaining each step (calculation and printing):
/**
* This method will print the first # levels of the Pascal's triangle. It
* uses the method described in:
*
* https://en.wikipedia.org/wiki/Pascal%27s_triangle#Calculating_a_row_or_diagonal_by_itself
*
* It basically computes the Combinations of the current row and col
* multiplied by the previous one (which will always be 1 at the beginning
* of each pascal triangle row). It will print each tree element to the output
* stream, aligning the numbers with spaces to form a perfect triangle.
*
* #param num
* # of levels to print
*/
public static void printPascalTriangle(int num) {
// Create a pad (# of spaces) to display between numbers to keep things
// in order. This should be bigger than the # of digits of the highest
// expected number and it should be an odd number (to have the same
// number of spaces to the left and to the right between numbers)
int pad = 7;
// Calculate the # of spaces to the left of each number plus itself
// (this is the width of the steps of the triangle)
int stepsWidth = pad / 2 + 1;
// Now calculate the maximum # of spaces from the left side of the
// screen to the first triangle's level (we will have num-1 steps in the
// triangle)
int spaces = (num - 1) * stepsWidth;
for (int n = 0; n < num; n++) {
// Print the left spaces of the current level, deduct the size of a
// number in each row
if (spaces > 0) {
System.out.printf("%" + spaces + "s", "");
spaces -= stepsWidth;
}
// This will represent the previous combination C(n k-1)
int prevCombination = 1;
for (int k = 1; k <= n + 1; k++) {
System.out.print(prevCombination);
// Calculate how many digits this number has and deduct that to
// the pad between numbers to keep everything aligned
int digits = (int) Math.log10(prevCombination);
if (digits < pad) {
System.out.printf("%" + (pad - digits) + "s", "");
}
// Formula from Wikipedia (we can remove that "+1" if we start
// the row loop at n=1)
prevCombination = prevCombination * (n + 1 - k) / k;
}
// Row separator
System.out.println();
}
}
Hope it helps someone!
Related
So the question is:
Write a program that reads a sequence of input values and displays a bar chart of the values using asterisks. You may assume that all values are positive. First figure out the maximum value. That value’s bar should be drawn with 40 asterisks. Shorter bars should use proportionally fewer asterisks.
eg.
***********************
*********
****************************************
****
*******************
This is my code below:
int count = 0;
//Finds largest Value
int largestValue = numbersArray[0];
for (int i = 1; i < numbersArray.length; i++) {
if (numbersArray[i] > largestValue) {
largestValue = numbersArray[i];
count++;
}
}
//Prints number of asterisks
final int MAX = 40;
String asterisks = "****************************************";
for (int i = 0; i < count + 2; i++) {
System.out.print(numbersArray[i]);
if (numbersArray[i] == largestValue) {
System.out.print(asterisks);
} //if (numbersArray[i] != largestValue) {
else {
for (int j = 0; j < (40 * numbersArray[i] / largestValue); j++) {
System.out.print("*");
}
}
System.out.println();
}
This code doesn't seem to run properly.
If I enter values in the order: 5 8 6 4 7, it will just print the stars for 5 and 8, and not the rest. Basically it prints stars for values till the largest number.
I can't find what's wrong with my code. Any help would be greatly appreciated!
Thanks for reading <3
First of all, you don't need to count variable - it does nothing helpful to you and you for some reason limit yourself (you increment everytime you find a larger element so you only increment once since there's nothing larger than 8).
What you should be doing is finding the largest value, as you did, and then running over the entire array and displaying each element proportional to that value, as you did (but without the special case for the actual largest value - that is atrocious).
Also, you should note that division of two integers would result in an integer, which is not what you want, so you'll have to cast one of them to float or double.
//finds largest Value
int largestValue = numbersArray[0];
for (int i = 1; i < numbersArray.length; i++) {
if (numbersArray[i] > largestValue) {
largestValue = numbersArray[i];
}
}
//Prints number of asterisks
final int MAX = 40;
for (int i = 0; i < numbersArray.length; i++) {
int portion = (int)(MAX * (numbersArray[i] / (float)largestValue));
for (int j = 0; j < portion; j++) {
System.out.print("*");
}
System.out.println();
}
So you'll find the largest value is 8.
Then for 5, you'll do 5/8 which is 0.625 and times MAX (40) that would be 25, so you'll print 25 *.
Then for 8 - 8/8 = 1.0 * MAX = 40 so you'll print the whole 40 *.
For 6 - 6/8 = 0.75 * MAX = 30 so you'll print 30 * and so on.
Note that if you want to fine-tune it, you could use Math.round instead of simply casting the portion to int (which simply truncates the floating point).
I'm a java beginner and only learned about the scanner class, JOptionPane, loops, and if statements.
I have to create a java program that prints an hour glass shape based on the number the user inputs. The user will also give a character symbol which is what the hourglass shape will consist of. For example if the user enters "4" for shape and "7" for character then it will look this:
8 number "7" on first now. 6 number "7" on second row. 4 number "7" on third row. 2 number "7" on fourth row. 4 number "7" on fifth row. 6 number "7" on seventh row. 8 number "7" on eight row.
Below is a visual representation of this.
77777777
777777
7777
77
7777
777777
77777777
The only instructions I was given was:
To read a character use the following code where scanner is Scanner object:
char symbol = scanner.next().charAt(0);
I would appreciate it if someone could point in the general direction of what code to use.
Here is my solution using your specification and relating the comments to your example.
import java.util.Scanner;
class Hourglass
{
public static void main(String[] args)
{
// construct scanner
Scanner scanner = new Scanner(System.in);
// get the values for the character and the size of the hourglass from the user
System.out.print("Enter a symbol: ");
char symbol = scanner.next().charAt(0);
System.out.print("Enter the size: ");
int size = scanner.nextInt();
// call method to output the hourglass with the user's input
hourGlass(symbol, size);
}
static void hourGlass(char symbol, int size)
{
for (int i = 0; i < size; i++) // loops size times to get the first half + the middle
{
// needs to loop 8,6,4,and 2 times; decreases by 2, hence the 2* and -i from outer loop;
// I used 0 for the outer loop so 2*(size - 0) = 2 * size to start the top line;
for (int j = 1; j <= 2 * (size - i); j++)
{
System.out.print(symbol);
}
System.out.println();
}
for (int i = 0; i < size - 1; i++) // loops 1 less than size times to get the bottom
{
// loop for 4,6,and 8 times; increases by 2 so 2 * i will control this; starts at size so size + (2 * i) = size + (2 * 0) = size
for (int j = 1; j <= size + (2 * i); j++)
{
System.out.print(symbol);
}
System.out.println();
}
}
}
I'm a student in a Java Programming class. My problem deals with an interpretation of the Monte Carlo Simulation. I'm supposed to find the probability that three quarters or three pennies will be picked out of a purse that has 3 quarters and 3 pennies. Once a coin is picked it is not replaced. The probability should be 0.1XXXXXXX. I keep getting 0 or 1 for my answer. This is what i have so far.
public class CoinPurse {
public static void main(String[] args) {
System.out.print("Probability of Drawing 3 coins of the Same Type - ");
System.out.println(coinPurseSimulation(100));
}
/**
Runs numTrials trials of a Monte Carlo simulation of drawing
3 coins out of a purse containing 3 pennies and 3 quarters.
Coins are not replaced once drawn.
#param numTrials - the number of times the method will attempt to draw 3 coins
#returns a double - the fraction of times 3 coins of the same type were drawn.
*/
public static double coinPurseSimulation(int numTrials) {
final int P = 1;
final int Q = 2;
int [] purse = {Q, Q, Q, P, P, P};
int [] drawCoins = new int[3];
for (int draw = 0; draw < 3; draw ++) {
int index = (int)(Math.random() * purse.length);
drawCoins[draw] = purse[index];
int [] newPurse = new int[purse.length-1];
int j = 0;
for (int i =0; i < purse.length; i++) {
if (i == index) {
continue;
}
newPurse[j] = purse[i];
j++;
}
purse = newPurse;
}
double number = 0.0;
double result = 0.0;
for (int i = 0; i < numTrials; i++) {
result++;
for (int j = 0; j < numTrials;j++) {
if(drawCoins[0] == drawCoins [1] && drawCoins[1] == drawCoins[2]) {
number++;
}
}
}
return number/result;
}
}
The reason you only ever get 0 or 1 is that you only draw (or pick) coins from the purse once, but you then test that draw numTrials * numTrials times. You have two loops (with indices i and j) iterating numTrials time - your logic is a little messed up there.
You can put the first loop (for drawing coins) within a second loop (for running trials) and your code will work. I've put a minimal refactor below (using your code as closely as possible), with two comments afterwards that might help you some more.
public class CoinPurse
{
public static void main(String[] args)
{
System.out.print("Probability of Drawing 3 coins of the Same Type - ");
System.out.println(coinPurseSimulation(100));
}
/**
* Runs numTrials trials of a Monte Carlo simulation of drawing 3 coins out
* of a purse containing 3 pennies and 3 quarters. Coins are not replaced
* once drawn.
*
* #param numTrials
* - the number of times the method will attempt to draw 3 coins
* #returns a double - the fraction of times 3 coins of the same type were
* drawn.
*/
public static double coinPurseSimulation(int numTrials)
{
final int P = 1;
final int Q = 2;
double number = 0.0;
double result = 0.0;
// Changed your loop index to t to avoid conflict with i in your draw
// loop
for (int t = 0; t < numTrials; t++)
{
result++;
// Moved your draw without replacement code here
int[] purse =
{ Q, Q, Q, P, P, P };
int[] drawCoins = new int[3];
for (int draw = 0; draw < 3; draw++)
{
int index = (int) (Math.random() * purse.length);
drawCoins[draw] = purse[index];
int[] newPurse = new int[purse.length - 1];
int j = 0;
for (int i = 0; i < purse.length; i++)
{
if (i == index)
{
continue;
}
newPurse[j] = purse[i];
j++;
}
purse = newPurse;
}
// Deleted the loop with index j - you don't need to test the same
// combination numTrials times...
if (drawCoins[0] == drawCoins[1] && drawCoins[1] == drawCoins[2])
{
number++;
}
}
return number / result;
}
}
Picking coins code
I have some comments on your routing for drawing coins:
It works correctly
It is rather cumbersome
It would have been easier for you to spot the problem if you had broken this bit of code into a separate method.
I'm going to address 3 and then 2.
Break the drawing code out into a method
private static int[] pickCoins(int[] purse, int numPicks)
{
//A little error check
if (numPicks > purse.length)
{
System.err.println("Can't pick " + numPicks +
" coins from a purse with only " + purse.length + " coins!");
}
int[] samples = new int[numPicks];
// Your sampling code here
return samples;
}
You can now simply call from within your second loop i.e.
drawCoins = pickCoins(purse, 3);
Sampling algorithm
#pjs's answer recommends using Collections.shuffle() and then taking the first 3 coins in your collection (e.g. an ArrayList). This is a good suggestion, but I'm guessing you haven't been introduced to Collections yet, and may not be 'allowed' to use them. If you are - do use them. If not (as I assume), you might want to think about better ways to randomly draw n items from an r length array without replacement.
One (well accepted) way is the Fisher-Yates shuffle and its derivatives. In effect it involves picking randomly from the unpicked subset of an array.
In Java - an working example could be as follows - it works by moving picked coins to the "end" of the purse and picking only from the first maxInd unpicked coins.
private static int[] pickCoins(int[] purse, int numCoins)
{
int[] samples = new int[numCoins];
int maxInd = purse.length - 1;
for (int i = 0; i < numCoins; i++)
{
int index = (int) (Math.random() * maxInd);
int draw = purse[index];
samples[i] = draw;
// swap the already drawn sample with the one at maxInd and decrement maxInd
purse[index] = purse[maxInd];
purse[maxInd] = draw;
maxInd -= 1;
}
return samples;
}
Expected results
You say your expected result is 0.1XXXXXXX. As you're learning Monte Carlo simulation - you might need to think about that a little more. The expected result depends on how many trials you do.
First, in this simple example, you can consider the analytic (or in some sense exact) result. Consider the procedure:
You draw your first coin - it doesn't matter which one it is
Whichever coin it was, there are 2 left in the bag that are the same - the probability of picking one of those is 2 / 5
If you picked one of the matching coins in step 2, there is now 1 matching coin left in the bag. The probability of picking that is 1 / 4
So, the probability of getting 3 matching coins (of either denomination) is 2 / 5 * 1 / 4 == 2 / 20 == 0.1
Your Monte Carlo programme is trying to estimate that probability. You would expect it to converge on 0.1 given sufficient estimates (i.e. with numTrials high enough). It won't always give a value equal to, or even starting with, 0.1. With sufficient number of trials, it's likely to give something starting 0.09 or 0.1. However, if numTrials == 1, it will give either 0 or 1, because it will draw once and the draw will either match or not. If numTrials == 2, the results can only be 0, 0.5 or 1 and so on.
One of the lessons of doing Monte Carlo simulation to estimate probabilities is to have a sufficiently high sample count to get a good estimate. That in turn depends on the accuracy you want - you can use your code to investigate this once it's working.
You need to move the loop where you generate draws down into the numTrials loop. The way you've written it you're making a single draw, and then checking that one result numTrials times.
I haven't checked the logic for your draw carefully, but that's because I'd recommend a different (and much simpler) approach. Use Collections.shuffle() on your set of quarters and pennies, and check the first three elements after each shuffle.
If done correctly, the answer should be 2 * (3/6) * (2/5) * (1/4), which is 0.1.
I have create a program that takes a random array which is created by starting from 0 and adding Math.random() (double between 0 and 0.999) n times, and calculates the weighted average of each position within a certain radius. I currently have a program that does this but i was wondering how to create one using a torus. The basic principle is the last element is now equal to the first element and when the first element updates its position it takes into account the difference between the other elements including some of the last elements in the array.
Any help on the matter would be much appreciated. Its not help with the coding but with the principle behind it, I cant work out how this would be possible for multiple iterations.
heres the code so far that works for one iteration. After one the code is incorrect and calculates the wrong values.
import java.text.DecimalFormat;
import java.util.Scanner;
/**
* Created by jameshales on 12/03/2014.
*/
public class Torus {
public static void main(String[] args) {
DecimalFormat df = new DecimalFormat("#.###"); // this sets all decimals to a max of 3 decimal places.
System.out.println("how many numbers of agents on the real line?"); // This asks the question "how many numbers on the real line?" to the user.
Scanner input = new Scanner(System.in);
int n = 0;
n=Integer.parseInt(input.nextLine()); // the scanner reads the input and assigns it to the variable n
double[] agentPosition = new double[n]; // create an array with decimal places allowed called agentPosition
double[] newAgentPosition = new double[n]; // create an array with decimal places allowed called newAgentPosition
double[] originalAgentPosition = new double[n]; // create an array with decimal places allowed called originalAgentPosition
System.out.println("Please select your desired radius? select 1 normally"); // This asks the question "Please select your desired radius?
double r = 0;
r = input.nextDouble(); // the scanner reads the next input and assigns it to the variable r
int t = 0; // sets t to 0
double epsilon = 0.001; // this allows us to sets epsilon to 0.
// start the array from position 0 with its value set to 0
for (int i = 0; i <= n - 1; i++) { // starting from position 1 it creates a random number between 0 and 0.999 and adds it to the previous agentPosition to fill the array in a random increasing way.
if (i > 0)
agentPosition[i] = agentPosition[i - 1] + Math.random(); // this equation creates the random array
else agentPosition[i] =0.0;
}
System.arraycopy(agentPosition,0,originalAgentPosition,0,n);
// This takes the first randomly created array(agentPosition), copyies each element starting from 0 to n and calls it originalAgentPosition.
while(true) { // This is the start of the while loop, this will keep running until false
for (int i = 0; i <= n - 1; i++) {
// this will go through the array 1 position at a time in an increasing order from position 0 to n-1
double total1 = agentPosition[i]; // sets the initial value of total1 to 0
double total2 = 0; // sets the initial value of total2 to 0
int numposition = 1; // this starts at 1 so it includes the position in the array when dividing.(also stops dividing by 1)
for (int j = i - 1; j >= 0; j--) { // this will work from the initial value of the array to the one before the one selected.
if ((agentPosition[i] - agentPosition[j]) <= r) { // this calculates the absolute value of the difference between 2 positions on the array. (from i working downwards)
numposition++; // this sums the number of positions within the radius of the chosen position.
total1 += agentPosition[j]; // this sums up all the values within the radius below to the total1.
} else break; // stops the program once it has passed a position of a distance of 1
}
for (int k = i + 1; k <= n - 1 ; k++) { // this will go from the one after the position selected to the last position in the array to test if the distance is greater than 1, stops otherwise..
if (Math.abs(agentPosition[k] - agentPosition[i]) <= r) { // this calculates the absolute value of the difference between 2 positions on the array(i and positions greater).
numposition++; // this sums the number of positions within the radius of the chosen position.
total2 += agentPosition[k]; // this sums up all the values within the radius above to the total1.
} else break; // stops the program once it has passed a position of a distance of 1
}
for (int j = n - 2; j >= 1; j--) { // this will work from the initial value of the array to the one before the one selected.
if (((agentPosition[n-1] + agentPosition[i]) - agentPosition[j]) <= r) { // this calculates the absolute value of the difference between 2 positions on the array. (from i working downwards)
numposition++;
total1 += (agentPosition[j] - agentPosition[n - 1]); // this sums up all the values within the radius below to the total1.
} else break;// stops the program once it has passed a position of a distance of 1
}
for (int k = 1; k <= n - 2 ; k++) { // this will go from the one after the position selected to the last position in the array to test if the distance is greater than 1, stops otherwise..
if (Math.abs((agentPosition[i] - agentPosition[n - 1]) - agentPosition[k]) <= r) { // this calculates the absolute value of the difference between 2 positions on the array(i and positions greater).
numposition++; // this sums the number of positions within the radius of the chosen position.
total2 += (agentPosition[n - 1] + agentPosition[k]); // this sums up all the values within the radius above to the total1.
} else break;// stops the program once it has passed a position of a distance of 1
}
newAgentPosition[i] = (total1 + total2) / numposition; // this calculates the new weighted average. ( sum of assigned random variable/ sum of position)
}
for (int i = 0; i <= n - 1; i++){
if (newAgentPosition[i] > originalAgentPosition[n - 1]){
newAgentPosition[i] = newAgentPosition[i] - originalAgentPosition[n - 1];
}
if(newAgentPosition[i] < 0) { // This checks if the agentPosition is smaller than 0 and then adds the largest agent to make all the elements within the range.
newAgentPosition[i] = newAgentPosition[i] + originalAgentPosition[n - 1];
}
}
t++; // This sums up how many iterations it will take.
double largestDiff = 0.0; // This assigns largestDiff to 0
for (int i = 0; i <= n-1; i++) {
double diff = Math.abs(agentPosition[i] - newAgentPosition[i]); // This calculates the difference between the previous and current array at position i.
if(diff > largestDiff) // If the difference between the agents is bigger than 0, assign it to the variable largestDiff.
largestDiff = diff;
}
if(largestDiff <= epsilon){ // This checks if the difference is bigger than the set epsilon,
break; // This stops the program if the difference is smaller than epsilon
}
agentPosition = new double[n];
System.arraycopy(newAgentPosition, 0, agentPosition, 0, n); // This takes the newly generated array(newAgentPosition), copyies each element starting from 0 to n and assigns it back to agentPosition. (this stops the problem j and with taking the newly created elements.)
}
for (int i = 0 ; i <= n - 1; i++) { // starting from position 1 it creates a random number between 0 and 0.999 and adds it to the previous agentPosition to fill the array in a random increasing way.
System.out.println(i + ": " + df.format(originalAgentPosition[i]) + "\t->\t" + df.format(agentPosition[i]));
}
int sumdofclusters = 1; // This sets the sum of clusters to 1
System.out.println("The different clusters are:\n" + df.format(agentPosition[0])); // This prints out the first cluster only.
for (int i = 1; i <= n - 1 ; i++) {
if(Math.abs(agentPosition[i] - agentPosition[i - 1]) >= epsilon) { // This checks if the element after the element at hand is different by a set epsilon.(how to work out different clusters)
sumdofclusters++; // This sums the number of clusters.
System.out.println(df.format(agentPosition[i])); // This prints out the different clusters other than the first 1.
}
}
System.out.println("Number of clusters is:" + sumdofclusters); // This prints out the number of clusters.
System.out.println("Number of iterations:" + t); // This prints out the number of iterations.
}
}
You can create a circular list using an array with modulus division.
getElementAt(double[] arr, int index)
{
index = index % arr.length;
index = index + arr.length; // If index is negative, modulus division gives us negative result, so this makes it positive.
index = index % arr.length; // In case the previous step made index >= n
return arr[index]
}
If n is arr.length then
0 <= index < n will be like normal.
n <= index will wrap around the list (e.g. arr[n] == arr[0], arr[n+1] == arr[1], etc.)
index < 0 will wrap around the list in the other direction (e.g. arr[-1] == arr[n-1], arr[-2] == arr[n-2], etc.)
Okay so I changed my code around and deleted a lot of the unnecessary garbage in it. It works for some numbers but not for others, for example, when I put in 100 rolls/8 sides/3 die it gives me an out of bounds error despite the limits I've set for it. Obviously I've looked over some detail, I'm just not sure what detail it is.
public class Ass11f {
public static void main(String[] args) {
EasyReader console = new EasyReader();
System.out.print("Enter how many times you want to roll the die: ");
int numRolls = console.readInt();
System.out.print("Enter the amount of sides: ");
int numSides = console.readInt();
System.out.print("Enter the amount of die: ");
int numDie = console.readInt();
int[] rollSum = new int[numDie*numSides];
for (int i = 0; i<numRolls; ++i)
{
int rollCounter=0;
for (int l = 0; l<numDie; ++l){
rollCounter += ((int)(Math.random()*numSides)+1);
}
rollSum[rollCounter]++;
}
for (int m = 2;m<=rollSum.length;++m) System.out.println(m+"'s: "+rollSum[m]+" times, "+((((double)rollSum[m])/numRolls)*100)+"%");
}
}
There are two base problems:
When adding roll totals, you're trying to add the maximum roll in an index one past the end of the array. The easy fix is to simply add 1 to the length of your array.
When printing, you cannot access an array using an index equal to the array's length, which is what m<=rollSum.length will eventually do. Replace that with m < rollSum.length so it stops before the final value.
Also, here's some ways to make your array creation a bit clearer:
// The minimum value is always numDie.
// The maximum is always numDie * numSides
// There are maximum - minimum + 1 possible values (ie 6 on a d6)
int maximum = numDie * numSides;
int minimum = numDie;
// Remember, index zero is now the minimum roll.
// The final index is the maximum roll. So the count at an index is really
// the count for any roll with value index + minimum
int[] rollSum = new int[maximum - minimum + 1];
I also recommend splitting up that print statement. It's a bit easier to read and debug. Also, you can start at numDie instead of 2 to account for when you have more or less die than 3:
for (int i = numDie; i < rollSum.length; ++i) {
// Print the first bit, ie "2's: ".
System.out.print(i + "'s: ");
// How many times was that value rolled?
System.out.print(rollSum[i] + " times, ");
// What percentage is that?
double percentage = ((double)rollSum[i]) / numRolls * 100;
System.out.println(percentage + "%");
}