In my Undead class I have a method written which allows an undead character to sacrifice itself and split its remaining health between the two remaining team mates (the total number of players in the array of chars is always 3).
My function for this is
public void sacrifice(Character other1, Character other2){
int healthgiven = health/2;
health -= health;
other1.health += healthgiven;
other2.health += healthgiven;
System.out.println(name + " has sacrified himself for the team.
His health has been distributed among the two remaining allies. ");
}
This works as far as I know, but it becomes a problem when I have to use it in the main. I somehow have to figure out which elements of the list are the two other characters (who can be Undead as well). Basically when I end up calling undeadchar.sacrifice(other1, other2), I need to find the two characters that are not undeadchar. Sorry if it's confusing I will rewrite this if necessary.
I think you should place a check before calling the method sacrifice.
Assuming that you have getHealth() function in your Player and once the player sacrifices health the health of player is 0 then,
List<Player> PlayersList = new ArrayList<Player>();
Player sacrificingPlayer = ... //Your logic to find sacrificing player
List<Player> healthyPlayers = GetHealthyPlayer(PlayersList );
sacrificingPlayer.sacrifice(healthyPlayers.get(0), healthyPlayers.get(1));
and function GetHealthyPlayer();
public List<Player> GetHealthyPlayer(List<Player> PlayersList )
{
List<Player> Players = new ArrayList<Player>();
int PlayerCount = 0;
for (Player pl: PlayersList )
{
if(pl.getHealth() > 0)
{
Players.add(pl);
PlayerCount++;
if(PlayerCount == 2) //Since we need only two healthy player
break;
}
}
if(PlayerCount != 2)
throw Exception("Two healthy players not found "); //Or you Can return null and check
return Players;
}
Assuming you have something like:
ArrayList<Character> chars = ...; // all of them
Character sacrificingChar = ...; // the one that will sacrifice himself
Then you can do:
List<Character> others = new ArrayList<>(chars);
others.remove(sacrificingChar);
sacrificingChar.sacrifice(others.get(0), others.get(1));
Using Java 8:
List<Character> charList = ...
Character sacrificeChar = ...
List<Character> notSacrificeList = charList.stream()
.filter(x -> !x.equals(sacrificeChar))
.map(Character::new)
.collect(Collectors.toList());
Related
I'm trying to do an application which set a game plan for a tournament.
I have a method:
public List<Match> creerMatchsTousContreTous(List<Equipe> lEquipe) {
List<Match> lMatch = new ArrayList<>();
for (int i = 0; i < lEquipe.size(); i++) {
for (int j = i + 1; j < lEquipe.size(); j++) {
Match match = new Match();
match.setEquA(lEquipe.get(i));
match.setEquB(lEquipe.get(j));
lMatch.add(match);
}
}
return lMatch;
}
This method receid a list of Teams. Each one must to play which each others. This return a list of plays (Match).
I want now to random the plays. I need that a Team A who plays the first Play not play the next one. And so more.
I use:
Collections.shuffle(lMatch);
But that ramdom the list of plays and it is possible that a tema play two successive plays.
How can I achieve that?
Thanks
Best Regards
EDIT:
EXAMPLE:
The method return a list of games:
TEAM 1 : TEAM 2
TEAM 2 : TEAM 3
TEAM 1 : TEAM 3
TEAM 4 : TEAM 3
TEAM 2 : TEAM 4
TEAM 4 : TEAM 3
creerMatchsTousContreTous() return in this example a list with 6 values. But here for example, in the first game, TEAM 2 is playing, in the second game he is also playing, and this mustn't be.
I would suggest adding a boolean variable, such as justPlayed or hasPlayed, to the Team class. This variable would track if a particular team has just played in a game.
Collections.shuffle(lMatch); // get two random teams using shuffle
while(Match.Team1.getHasPlayed() == True or Match.Team2.getHasPlayed() == True){
Collections.shuffle(lMatch); // try to find different teams
}
lMatch.play(); // you've found two teams, so now you can call your play method
for(Team t:lEquipe){ // go through the list of teams and
t.setHasPlayed(false); // reset the rest each team's boolean
}
Match.Team1.setHasPlayed(true);
Match.Team2.setHasPlayed(true); // set the boolean to true at the end of the turn
//
This is obviously pseudocode, since I don't know your implementation of Match and Team. Still, consider using the boolean instance field and checking if it has been modified in the previous turn.
The one below is a recursive approach. I think it can provide solution in a faster way than one suggested by #Sonedring, as constraint is applied after every randomization.
It is also safer for a corner case where you have less than 4 teams. In the corner case you will not find a solution and you don't to run an endless loop.
Hope this helps.
public static void randomize(List<Match> matches) {
List<Match> randomizedList = new ArrayList<>();
int numberOfAttempts = 256;
// tmpSubList is a temporary list that contains all matches
// (excluding unwanted) after n-th iteration (randomization).
List<Match> tmpSubList = new ArrayList<Match>(matches);
while (matches.size() > 0) {
// if tmpSubList contains - it means there is no match that can be added.
// Need to restart randomization algorithm.
if (tmpSubList.size() == 0) {
System.out.println("Restarting algorithm.");
if (--numberOfAttempts == 0) {
throw new ArithmeticException("Could not find solution.");
}
// Need to restart:
matches.addAll(randomizedList);
tmpSubList.addAll(randomizedList);
randomizedList.clear();
}
int randomIndex = (int) (tmpSubList.size() * Math.random());
Match match = tmpSubList.remove(randomIndex);
matches.remove(match); // remove also from the main list;
randomizedList.add(match);
Equipe lastTeam1 = match.getEquA();
Equipe lastTeam2 = match.getEquB();
tmpSubList.clear();
matches.stream()
.filter( x -> !x.getEquA().equals(lastTeam1) && !x.getEquB().equals(lastTeam1) )
.filter( x -> !x.getEquA().equals(lastTeam2) && !x.getEquB().equals(lastTeam2) )
.forEach( x -> tmpSubList.add(x));
}
matches.addAll(randomizedList);
}
Before asking my question I want to make some things clear. First, I am new to Java and programming in general. Second, This is my first post so please go easy on me if I did something wrong. Finally, I DO NOT want any specific solutions to my assignment in any responses to this post. Those issues are for me to figure out. What I do want is an explanation as to why my test code wont compile/run. To better understand the issue I will paste the assignment information, then the Driver class that is given, then my class code that is accessed by the Driver class. The compiler error I have is shown in the title, but since it is fairly vague, here is a screenshot of the exact errors I'm getting.
The following is the assignment:
You are to design a class “LostPuppy.java” which represents a puppy lost in a multi-floor building that
contains the same number of rooms on each floor. During instantiation (or creation) of an object of this class,
each room on each floor will be initialized as empty (you will actually use the space ‘ ‘ character for this
purpose) and a random room will be chosen where the puppy is lost. For this purpose, the character “P” will
be placed in this random location. Further details on the constructor is listed below.
An object of this class is used as a game for two players to take turns searching for the puppy, one room at a
time until the unfortunate little canine is found. The instantiation of this object and the search will be performed
by a “driver” program which has been provided to you allowing you to only have to concentrate on developing
the class (the driver program is in the file “PuppyPlay.java”)
Fields (of course, all fields are private):
A character (char) array named myHidingPlaces. This represents the building where the rows are floors
and the columns are rooms on each floor (this building has an unusual numbering system; the floors and
rooms both start at zero).
Two integers that will hold the floor and room where the puppy is lost, named myFloorLocation and
myRoomLocation.
A char named myWinner which will be assigned the player’s character when a player finds the puppy
(the driver program uses digits ‘1’ and ‘2’ to more clearly distinguish the players from the puppy).
A boolean named myFound which is set to true when the puppy is found.
Constructor:
Receives two integer parameters as the user’s input for the number of floors and rooms of the building
in which the puppy is lost.
The constructor instantiates the 2D array “myHidingPlaces” as a character array with the first parameter
for the rows (theFloors) and the second parameter as the columns (theRooms).
Initialize myHidingPlaces’ cells, each to contain a space ‘ ‘ (done with single quotes)
Set myFloorLocation (floor puppy is on) randomly based using the first parameter
Set myRoomLocation (room puppy is in) randomly based using the second parameter
Set myHidingPlaces[myFloorLocation][myRoomLocation] to the char ‘P’
Set myWinner to a single space
Set myFound to false
Methods:
roomSearchedAlready receives the floor and room to be searched and returns true if the room has
already been searched, false otherwise.
puppyLocation receives the floor and room to be searched and returns true if the floor and room are
where the puppy is lost, false otherwise. This method should NOT change any of the fields.
indicesOK receives the floor and room to be searched and returns true if the floor and room values are
within the array indices range, false otherwise (used to check that these indices will not cause an error
when applied to the array).
numberOfFloors returns how many floors are in the building (the first floor starts at zero).
numberOfRooms returns how many rooms are on each floor of the building (the first room starts at
zero and all floors have the same number of rooms).
searchRoom receives the floor and room to be searched and also the current player (as a char type)
and returns true if the puppy is found, false otherwise. If the puppy is NOT found searchRoom also
sets the myHidingPlaces array at the received floor and room location to the received player value (a ‘1’
or a ‘2’) OR, when found, sets the myWinner field to the current player AND sets myFound to true.
toString displays the current hidingPlaces array and it’s contents EXCEPT the location of the puppy
which remains hidden until he/she is found at which point toString will be called (by the driver) and both
the player who found the puppy and a ‘P’ will be displayed in the same cell….
NOW, and perhaps the awkward portion of the toString output. Normally, when displaying a 2D array,
the [0][0] cell is displayed in the upper left corner as with matrices. However, because the puppy
decided to get lost in a building and not a matrix, it would make more visual sense to have the first floor
(row 0) displayed on the bottom, second floor above it… and finally the top floor, well… on top! To
save words, look closely at the sample run provided on the next page. Your output should look the
same as what is seen on the next page in the sample run.
Here is the Driver program:
import java.util.Random;
import java.util.Scanner;
/**
* This program is used as a driver program to play the game from the
* class LostPuppy. Not to be used for grading!
*
* A puppy is lost in a multi-floor building represented in the class
* LostPuppy.class. Two players will take turns searching the building
* by selecting a floor and a room where the puppy might be.
*
* #author David Schuessler
* #version Spring 2015
*/
public class PuppyPlay
{
/**
* Driver program to play LostPuppy.
*
* #param theArgs may contain file names in an array of type String
*/
public static void main(String[] theArgs)
{
Scanner s = new Scanner(System.in);
LostPuppy game;
int totalFloors;
int totalRooms;
int floor;
int room;
char[] players = {'1', '2'};
int playerIndex;
boolean found = false;
Random rand = new Random();
do
{
System.out.print("To find the puppy, we need to know:\n"
+ "\tHow many floors are in the building\n"
+ "\tHow many rooms are on the floors\n\n"
+ " Please enter the number of floors: ");
totalFloors = s.nextInt();
System.out.print("Please enter the number of rooms on the floors: ");
totalRooms = s.nextInt();
s.nextLine(); // Consume previous newline character
// Start the game: Create a LostPuppy object:
game = new LostPuppy(totalFloors, totalRooms);
// Pick starting player
playerIndex = rand.nextInt(2);
System.out.println("\nFloor and room numbers start at zero '0'");
do
{
do
{
System.out.println("\nPlayer " + players[playerIndex]
+ ", enter floor and room to search separated by a space: ");
floor = s.nextInt();
room = s.nextInt();
//for testing, use random generation of floor and room
//floor = rand.nextInt(totalFloors);
//room = rand.nextInt(totalRooms);
} while (!game.indicesOK(floor, room)
|| game.roomSearchedAlready(floor, room));
found = game.searchRoom(floor, room, players[playerIndex]);
playerIndex = (playerIndex + 1) % 2;
System.out.println("\n[" + floor + "], [" + room + "]");
System.out.println(game.toString());
s.nextLine();
} while (!found);
playerIndex = (playerIndex + 1) % 2;
System.out.println("Great job player " + players[playerIndex] +"!");
System.out.println("Would you like to find another puppy [Y/N]? ");
}
while (s.nextLine().equalsIgnoreCase("Y"));
}
}
Finally, here is my test code:
import java.util.Random;
import java.util.Scanner;
public class LostPuppy
{
char[][] myHidingPlaces;
int myFloorLocation;
int myRoomLocation;
char myWinner;
boolean myFound;
Random random = new Random();
public void LostPuppy(int theFloors, int theRooms)
{// this ^ void is the issue and is now removed from my code(answered 7/14/2015 on stack overflow)
char[][] myHidingPlaces = new char[theFloors][theRooms];
for (int i = 0; i < theFloors; i++)
{
for (int j = 0; j < theRooms; j++)
{
myHidingPlaces[i][j] = ' ';
}
}
myFloorLocation = random.nextInt(theFloors);
myRoomLocation = random.nextInt(theRooms);
myHidingPlaces[myFloorLocation][myRoomLocation] = 'P';
myWinner = ' ';
myFound = false;
}
public boolean roomSearchedAlready(int floor, int room)
{
if (myHidingPlaces[floor][room] == '1' ||
myHidingPlaces[floor][room] == '2')
{
return true;
}
else
{
return false;
}
}
public boolean puppyLocation(int floor, int room)
{
if (myHidingPlaces[floor][room] == 'P')
{
return true;
}
else
{
return false;
}
}
public boolean indicesOK(int floor, int room)
{
if (floor <= myHidingPlaces.length || room <= myHidingPlaces[0].length)
{
return true;
}
else
{
return false;
}
}
public int numberOfFloors()
{
return myHidingPlaces.length - 1;
}
public int numberOfRooms()
{
return myHidingPlaces[0].length - 1;
}
public boolean searchRoom(int floor, int room, char player)
{
if (myFound = true)
{
myWinner = player;
myFound = true;
return true;
}
else
{
myHidingPlaces[floor][room] = player;
return false;
}
}
public String toString()
{
return "this is a test";
}
}
I DO NOT want any specific solutions to my assignment in any responses
to this post. Those issues are for me to figure out. What I do want is
an explanation as to why my test code wont compile/run.
This line
game = new LostPuppy(totalFloors, totalRooms);
Won't compile because you haven't defined any constructor that expect two int as arguments (totalFloors and totalRooms).
In order to fix this, declare in your class LostPuppy a constructor such as
public LostPuppy(int totalFloors, int totalRooms)
{
//Do something here with paremeters..
}
This line
while (!game.indicesOK(floor, room)
Won't compile because you haven't defined any indicesOk method in your LostPuppy class.
Create a method such as
public boolean indicesOK(int floot, int room)
{
//return some conditions
}
I think your building method should be constructor:
public LostPuppy(int theFloors, int theRooms)
{
myHidingPlaces = new char[theFloors][theRooms]; //this line
for (int i = 0; i < theFloors; i++)
{
for (int j = 0; j < theRooms; j++)
{
myHidingPlaces[i][j] = ' ';
}
}
myFloorLocation = random.nextInt(theFloors);
myRoomLocation = random.nextInt(theRooms);
myHidingPlaces[myFloorLocation][myRoomLocation] = 'P';
myWinner = ' ';
myFound = false;
}
Note: look at the marked line, do not define type, if you define type, it becomes local variable instead of instance variable.
QUESTION:
How can I read the string "d6+2-d4" so that each d# will randomly generate a number within the parameter of the dice roll?
CLARIFIER:
I want to read a string and have it so when a d# appears, it will randomly generate a number such as to simulate a dice roll. Then, add up all the rolls and numbers to get a total. Much like how Roll20 does with their /roll command for an example. If !clarifying {lstThen.add("look at the Roll20 and play with the /roll command to understand it")} else if !understandStill {lstThen.add("I do not know what to say, someone else could try explaining it better...")}
Info:
I was making a Java program for Dungeons and Dragons, only to find that I have come across a problem in figuring out how to calculate the user input: I do not know how to evaluate a string such as this.
I theorize that I may need Java's eval at the end. I do know what I want to happen/have a theory on how to execute (this is more so PseudoCode than Java):
Random rand = new Random();
int i = 0;
String toEval;
String char;
String roll = txtField.getText();
while (i<roll.length) {
check if character at i position is a d, then highlight the numbers
after d until it comes to a special character/!aNumber
// so if d was found before 100, it will then highlight 100 and stop
// if the character is a symbol or the end of the string
if d appears {
char = rand.nextInt(#);
i + #'s of places;
// so when i++ occurs, it will move past whatever d# was in case
// d# was something like d100, d12, or d5291
} else {
char = roll.length[i];
}
toEval = toEval + char;
i++;
}
perform evaluation method on toEval to get a resulting number
list.add(roll + " = " + evaluated toEval);
EDIT:
With weston's help, I have honed in on what is likely needed, using a splitter with an array, it can detect certain symbols and add it into a list. However, it is my fault for not clarifying on what else was needed. The pseudocode above doesn't helpfully so this is what else I need to figure out.
roll.split("(+-/*^)");
As this part is what is also tripping me up. Should I make splits where there are numbers too? So an equation like:
String[] numbers = roll.split("(+-/*^)");
String[] symbols = roll.split("1234567890d")
// Rough idea for long way
loop statement {
loop to check for parentheses {
set operation to be done first
}
if symbol {
loop for symbol check {
perform operations
}}} // ending this since it looks like a bad way to do it...
// Better idea, originally thought up today (5/11/15)
int val[];
int re = 1;
loop {
if (list[i].containsIgnoreCase(d)) {
val[]=list[i].splitIgnoreCase("d");
list[i] = 0;
while (re <= val[0]) {
list[i] = list[i] + (rand.nextInt(val[1]) + 1);
re++;
}
}
}
// then create a string out of list[]/numbers[] and put together with
// symbols[] and use Java's evaluator for the String
wenton had it, it just seemed like it wasn't doing it for me (until I realised I wasn't specific on what I wanted) so basically to update, the string I want evaluated is (I know it's a little unorthodox, but it's to make a point; I also hope this clarifies even further of what is needed to make it work):
(3d12^d2-2)+d4(2*d4/d2)
From reading this, you may see the spots that I do not know how to perform very well... But that is why I am asking all you lovely, smart programmers out there! I hope I asked this clearly enough and thank you for your time :3
The trick with any programming problem is to break it up and write a method for each part, so below I have a method for rolling one dice, which is called by the one for rolling many.
private Random rand = new Random();
/**
* #param roll can be a multipart roll which is run and added up. e.g. d6+2-d4
*/
public int multiPartRoll(String roll) {
String[] parts = roll.split("(?=[+-])"); //split by +-, keeping them
int total = 0;
for (String partOfRoll : parts) { //roll each dice specified
total += singleRoll(partOfRoll);
}
return total;
}
/**
* #param roll can be fixed value, examples -1, +2, 15 or a dice to roll
* d6, +d20 -d100
*/
public int singleRoll(String roll) {
int di = roll.indexOf('d');
if (di == -1) //case where has no 'd'
return Integer.parseInt(roll);
int diceSize = Integer.parseInt(roll.substring(di + 1)); //value of string after 'd'
int result = rand.nextInt(diceSize) + 1; //roll the dice
if (roll.startsWith("-")) //negate if nessasary
result = -result;
return result;
}
So, this is in a game environment. I have 2 ArrayLists, one is a party of 3 characters you own, and the other is an ArrayList of 3 enemy characters.
I have a method called combat which puts character "a" from your party and "b" from the enemy party in combat. I have this working without any problems, but when one of the characters dies in either ArrayList, the targets have to switch.
For example:
1)Characters a, b, c Vs. Character d, e, f
2)I use my combat method so that a fights d, b fights e, and c fights f. All is well so far.
3)Character a loses and dies, now I have to make character b fight d and e, while c keeps fighting f.
Any ideas on how I could go about doing this?
I would just remove the dead character at the end of combat() method and then run the combat() again recursively until one of the lists is empty.
Pseudocode:
protected void combat(List<Character> heroes, List<Character> enemies) {
if (heroes.isEmpty() || enemies.isEmpty()) {
//one of the parties wins
return;
}
List<Pair<Character, Character>> vs = new LinkedList<>();
int i = 0;
while ( i< heroes.length() && i< enemies.length()) {
vs.add(heroes.get(i), enemies.get(i));
++i;
}
for (Pair<Character, Character> fight : vs) {
//figure out the loser
Character loser = fight(vs.getFirst(), vs.getSecond();
if (loser.isEnemy()) {
enemies.remove(loser);
} else {
heroes.remove(loser);
}
}
combat(heroes, enemies);
}
List friends = new ArrayList();
List enemies = new ArrayList();
// populate the lists.
// map the opponents to each other.
//if elementA in friend dies while fighting elementX
friends.remove("elementA");
//during fighting
if(friends.size()>0){
//new enemy of element X is
friends.get(1);
}
else{
//enemies has won over friends.
}
Note: The source codes include multiple classes, so for the sake of your time, I will not post it, but will give you context. Please forgive if I can't explain well. I have been working on this a lot and my explanation makes sense to me but may not make sense to others.
I have a task to determine what category user input belongs into. For example, if a user inputs: I love dogs and cats.
The program will output that the top 2 categories:
dogs,
cats
If the user only inputs: "I love dogs", the program will output the top 2 categories as "dogs, no other category found"
"no category" is the default response if there is only one category found or none at all.
I have created arrays lists for the following categories: dogs, cats, birds. These arraylists contain keywords that will trigger the program to recognize what category the user input will be in.
I basically need to get the highest likelihood and second highest likelihood (if applicable) and 'link' them to a string that will output what the category is.
This is my code, which attempts to take the top 2 highest likelihoods and get them to output on the console. my issue is getting the categories to link to their respective string to ensure the categories with highest likelihood are outputted.
//Create prioritization
int topDouble = 0;
String topString = "no category"; //default response
int secondDouble = 0;
String secondString = "no category"; // default response
ArrayList<Double> likelyDouble = new ArrayList<Double>();
likelyDouble.add(cats);
likelyDouble.add(dogs);
likelyDouble.add(birds);
ArrayList<String> likelyString = new ArrayList<String>();
likelyString.add("you talked about cats");
//to parallel likelyDouble cats category
likelyString.add("you talked about dogs");
//to parallel likelyDouble dogs category
likelyString.add("you talked about birds");
//to parallel likelyDouble cats category
int count = 0;
for (double d : likelyDouble){
if((d>0) && (d > topDouble)){
topDouble = (int) d;
topString = likelyString.get(count);
}
else if((d>0) && (d > secondDouble)){
secondDouble = (int) d;
secondString = likelyString.get(count);
}
}
System.out.print(topString + "\n");
System.out.print(secondString);
The output I get defaults to:
User input:
I like dogs and cats.
Dogs
no category
FYI The program determines what the likelihood that the user is talking about a certain category based on position in the sentence and number of times that category is referenced. The likelihood is a value that is calculated. so if the category is not mentioned at all, the likelihood is 0.
Thanks for all of your help!
I don't clearly understand what you are after, but I suspect it has something to do with your cast:
topDouble = (int) d;
You always set topDouble to 0 - assuming likelyhood is in the range [0,1].
Same goes to secondDouble.
Probably you wanted to declare topDouble and secondDouble as double, and remove the cast to an int - to get a double of the max/second value.
In addition - I cannot see you increase count, so you always get() the first element in the ArrayList.
Just a design thaught for a better approach [in my opinion]:
Create a new class: LikelyhoodStringDouble with 2 fields, one is a String and the other is a double. Make it implement Comparable [based on the double's value.
All you will have to do now is use Collections.sort() to sort the list, and get the top k elements you want [in your case k=2]
If I get you right, you can give a try to use a Map to store the likelyhood of your categories for every input any user can enter.
Sample given:
List<String> categories = new ArrayList<String>();
categories.add("dogs");
categories.add("cats");
categories.add("birds");
Map<String, Double> counterMap = new HashMap<String, Double>
for(String s : categories) {
counterMap.put(s, 0);
}
List<String> inputString = new ArrayList<String>();
inputString.add("you talked about cats");
inputString.add("you talked about dogs");
inputString.add("you talked about birds");
for(String s : inputString) {
for(String s2 : categories) {
//get the likelyhood of the category in the sentence
Double d = getLikelyhood(s2, s);
//add the likelyhood in your map
map.put(s2, map.get(s2) + d);
}
}
//after setting the likelyhood of the categories with the user input
//you just need to get the 2 major values in the map
//I'll let you a small algorithm for this
int x = 0;
String[] arrS = new String[m.size()];
for(Object o : m.keySet().toArray()) {
arrS[x++] = (String)o;
}
x = 0;
Double[] arrI = new Double[m.size()];
for(Object o : m.values().toArray()) {
arrI[x++] = (Double)o;
}
int max1, max2, posMax1, posMax2;
max1 = arrI[0];
max2 = arrI[0];
posMax1 = 0;
posMax2 = 0;
for(int i=1; i < arrI.length; i++) {
if (arrI[i] >= max1) {
max2 = max1;
max1 = arrI[i];
posMax2 = posMax1;
posMax1 = i;
} else if (arrI[i] > max2) {
max2 = arrI[i];
posMax2 = i;
}
}
System.out.println("Max category: " + arrS[posMax1]);
System.out.println("Second Max category: " + arrS[posMax2]);
Hope this helps you.