可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
my program records the number of bottles four rooms has collected in a bottle drive. When the user types in quit, the number of bottle each room has collected is shown as well as it prints out the room that has the most bottles. I have used an array to keep track of room number. How can change a method of instead of using an array, I would like to initiate room1, room2, room3, room4. Will i be able to use my looped array calls to write lines if i dont use an array? There are the lines i mean.
int room = int.Parse(quit); Console.Write("Bottles collected in room {0}: ", room); // This line adds the count of bottles and records it so you can continuously count the bottles collected. rooms[room - 1] += int.Parse(Console.ReadLine());
And this line:
}//Writes the bottles collected by the different rooms Console.WriteLine("Bottles collected in room {0} = {1}", i + 1, rooms[i]);
Here is my code:
namespace BottleDrive { class Program { static void Main(string[] args) {//Initialize array of rooms to 4 int[] rooms = new int[4]; //Start of while loop to ask what room your adding into. while (true) { Console.Write("Enter the room you're in: "); //If user enters quit at anytime, the code will jump out of while statement and enter for loop below string quit = Console.ReadLine(); if (quit == "quit") //Break statement allows quit to jump out of loop break; //Variable room holds the number of bottles collect by each room. int room = int.Parse(quit); Console.Write("Bottles collected in room {0}: ", room); // This line adds the count of bottles and records it so you can continuously count the bottles collected. rooms[room - 1] += int.Parse(Console.ReadLine()); } int maxValue = 0;//initiates the winner, contructor starts at 0 int maxRoomNumber = 0;//initiates the room number that wins for (int i = 0; i < rooms.Length; ++i)//This loop goes through the array of rooms (4) { if (rooms[i] > maxValue)//Makes sure that the maxValue is picked in the array {//Looking for room number for the maxValue = rooms[i]; maxRoomNumber = i + 1; }//Writes the bottles collected by the different rooms Console.WriteLine("Bottles collected in room {0} = {1}", i + 1, rooms[i]); } //Outputs winner Console.WriteLine("And the Winner is room " + maxRoomNumber + "!!!"); } } }
And thank you, I appreciate how much this community has helped me learn c sharp.
回答1:
You can not replace an array easily with individual variables. If you have a declaration like
int room1 = 0, room2 = 0, room3 = 0, room4 = 0;
and want to access room number i then you have to write
switch (i) { case 1: Console.WriteLine(room1); break; case 2: Console.WriteLine(room2); break; case 3: Console.WriteLine(room3); break; case 4: Console.WriteLine(room4); break; }
With an array you can simply write
Console.WriteLine(rooms[i]);
If you really want to go this array-less way, I suggest you to use helper methods:
private void SetRoom(int room, int value) { switch (room) { case 1: room1 = value; break; case 2: room2 = value; break; case 3: room3 = value; break; case 4: room4 = value; break; } } public int GetRoom(int room) { switch (room) { case 1: return room1; case 2: return room2; case 3: return room3; case 4: return room4; default: return 0; } }
You must declare variables room1 to room4 as class members to make this work.
Now you can write:
Console.WriteLine(GetRoom(i));
Or instead of rooms[i] += n;
SetRoom(i, GetRoom(i) + n);
回答2:
You could do that, but that would be a step back from good programming and towards writing bad code.
First it would bloat your code, since you always had to do something like this:
// this is the code you have now (3 lines for 4 rooms): int room = int.Parse(quit); Console.Write("Bottles collected in room {0}: ", room); rooms[room - 1] += int.Parse(Console.ReadLine()); // and this is the code you'll have when you refrain from using arrays // (17 lines for 2 rooms, ignoring empty lines and ones with only brackets): int room = int.Parse(quit); Console.Write("Bottles collected in room {0}: ", room); switch(room) { case 1: Console.WriteLine(room1); break; case 2: Console.WriteLine(room2); break; // other cases... } int count = int.Parse(Console.ReadLine()); switch(room) { case 1: room1 += count; break; case 2: room2 += count; break; // other cases... }
And second (and far more important):
The code is totally not extensible. If you want to add a fifth room to collect bottles in, you have to go through the whole program and adjust each and every switch statement, which is not only time consuming but also extremely prone to error.
回答3:
Here's an example that uses a Class to hold the information for each room. The reason for using a class is so that if your program needs to change in the future to collect more information, you won't have to track yet another array, you can just add properties to the class.
The individual rooms are now held in a list instead of an array just to show a different construct.
Here is the new Room class:
public class Room { public int Number { get; set; } public int BottleCount { get; set; } public Room(int wNumber) { Number = wNumber; } }
And here is the new version of the program. Note that additional checking of the values entered by the end user has been added in order to prevent exceptions when trying to get the current room or parse to an int the value entered by the user:
static void Main(string[] args) { const int MAX_ROOMS = 4; var cRooms = new System.Collections.Generic.List<Room>(); for (int nI = 0; nI < MAX_ROOMS; nI++) { // The room number is 1 to 4 cRooms.Add(new Room(nI + 1)); } // Initializes the room that wins //Start of while loop to ask what room your adding into. while (true) { Console.Write("Enter the room you're in: "); //If user enters quit at anytime, the code will jump out of while statement and enter for loop below string roomNumber = Console.ReadLine(); if (roomNumber == "quit") { //Break statement allows quit to jump out of loop break; } int room = 0; if (int.TryParse(roomNumber, out room) && (room < MAX_ROOMS) && (room >= 0)) { Room currentRoom; currentRoom = cRooms[room]; Console.Write("Bottles collected in room {0}: ", currentRoom.Number); int wBottleCount = 0; if (int.TryParse(Console.ReadLine(), out wBottleCount) && (wBottleCount >= 0)) { // This line adds the count of bottles and records it so you can continuously count the bottles collected. currentRoom.BottleCount += wBottleCount; } else { Console.WriteLine("Invalid bottle count; value must be greater than 0"); } } else { Console.WriteLine("Invalid room number; value must be between 1 and " + MAX_ROOMS.ToString()); } } Room maxRoom = null; foreach (Room currentRoom in cRooms) //This loop goes through the array of rooms (4) { // This assumes that the bottle count can never be decreased in a room if ((maxRoom == null) || (maxRoom.BottleCount < currentRoom.BottleCount)) { maxRoom = currentRoom; } Console.WriteLine("Bottles collected in room {0} = {1}", currentRoom.Number, currentRoom.BottleCount); } //Outputs winner Console.WriteLine("And the Winner is room " + maxRoom.Number + "!!!"); }
回答4:
I think your logic is sound (ie using a variable for the max value and max room and comparing each time). Were there any restriction as to not using arrays? It would seem that using 4 variables would require more lines of code.
I like the answer using a class. But you could very well do this with standard c with an array.
What is the requirement? encapsulation? robustness?