【发布时间】:2016-06-09 10:26:50
【问题描述】:
我正在做一个学校项目,我花了 5 个小时试图了解如何使用包含四个维度的对象对数组进行排序。我打算按productCode 或drinkName 对它们进行排序。当我阅读各种线程时,人们告诉 OP 使用 LINQ。我不应该使用它,而且我越来越困惑使用什么方法。老师告诉我,要使用冒泡排序(我知道算法不好),我在包含一维的数组上做得很好。我尝试了Array.Sort,但后来我得到了System.InvalidOperationException。
我要疯了,即使我阅读了有关该主题的多个主题,我也被困住了。我可能以错误的方式使用ToString。任何轻推将不胜感激。
class soda
{
string drinkName;
string drinkType;
int drinkPrice;
int productCode;
//Construct for the beverage
public soda(string _drinkName, string _drinkType, int _drinkPrice, int _productCode)
{
drinkName = _drinkName;
drinkType = _drinkType;
drinkPrice = _drinkPrice;
productCode = _productCode;
}
//Property for the drink name e.g. Coca Cola, Ramlösa or Pripps lättöl
public string Drink_name()
{
return drinkName;
//set { drinkName = value; }
}
//Property for the drink type e.g. Soda, fizzy water or beer
public string Drink_type()
{
return drinkType;
//set { drinkType = value; }
}
//Property for the drink price in SEK
public int Drink_price()
{
return drinkPrice;
//set { drinkPrice = value; }
}
//Property for the product code e.g. 1, 2 or ...
public int Product_code()
{
return productCode;
//set { productCode = value; }
}
//Property for the product code e.g. 1, 2 or ...
public int _Product_code
{
get { return productCode; }
set { productCode = value; }
}
public override string ToString()
{
return string.Format(drinkName + " " + drinkType + " " + drinkPrice + " " + productCode);
//return string.Format("The beverage {0} is of the type {1} and costs {2} SEK.", drinkName, drinkType, drinkPrice, productCode);
}
}
class Sodacrate
{
private soda[] bottles; //Crate the array bottles from the class soda.
private int antal_flaskor = 0; //Keeps tracks on the amount of bottles. 25 is the maximum allowed.
//Construct
public Sodacrate()
{
bottles = new soda[25];
}
public void sort_sodas()
{
string drinkName = "";
int drinkPrice = 0;
int productCode = 0;
Array.Sort(bottles, delegate (soda bottle1, soda bottle2) { return bottle1._Product_code.CompareTo(bottle2._Product_code); });
foreach (var beverage in bottles)
{
if (beverage != null)
{
drinkName = beverage.Drink_name(); drinkPrice = beverage.Drink_price(); productCode = beverage.Product_code();
Console.Write(drinkName + " " + drinkPrice + " " + productCode);
}
}
}
}
----------编辑--------------- 感谢您的帮助,我离解决方案越来越近了,我不得不在星期四吃午饭来解决我的问题。
我的排序还是有问题;
//Exception error When I try to have .Product_Name the compiler protests. Invalid token
public void sort_Sodas()
{
int max = bottles.Length;
//Outer loop for complete [bottles]
for (int i = 1; i < max; i++)
{
//Inner loop for row by row
int nrLeft = max - i;
for (int j = 0; j < (max - i); j++)
{
if (bottles[j].Product_code > bottles[j + 1].Product_code)
{
int temp = bottles[j].Product_code;
bottles[j] = bottles[j + 1];
bottles[j + 1].Product_code = temp;
}
}
}
}
当我想要所有那些对产品组真实的值时,我的线性搜索也只返回一个值。为了更快的实验,我在 Run() 中尝试了一些不同的东西。我将追加当前代码。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Sodacrate
{
//Soda - contains the properties for the bottles that go in to the crate
class Soda : IComparable<Soda>
{
string drinkName;
string drinkType;
int drinkPrice;
int productCode;
//Construct for the beverage
public Soda(string _drinkName, string _drinkType, int _drinkPrice, int _productCode)
{
drinkName = _drinkName;
drinkType = _drinkType;
drinkPrice = _drinkPrice;
productCode = _productCode;
}
//Property for the drink name e.g. Coca Cola, Ramlösa or Pripps lättöl
public string Drink_name
{
get { return drinkName; }
set { drinkName = value; }
}
//Property for the drink type e.g. Soda, fizzy water or beer
public string Drink_type
{
get { return drinkType; }
set { drinkType = value; }
}
//Property for the drink price in SEK
public int Drink_price
{
get { return drinkPrice; }
set { drinkPrice = value; }
}
//Property for the product code e.g. 1, 2 or ...
public int Product_code
{
get { return productCode; }
set { productCode = value; }
}
//Override for ToString to get text instead of info about the object
public override string ToString()
{
return string.Format("{0,0} Type {1,-16} Price {2,-10} Code {3, -5} ", drinkName, drinkType, drinkPrice, productCode);
}
//Compare to solve my issues with sorting
public int CompareTo(Soda other)
{
if (ReferenceEquals(other, null))
return 1;
return drinkName.CompareTo(other.drinkName);
}
}
static class Screen
{
// Screen - Generic methods for handling in- and output ======================================= >
// Methods for screen handling in this object are:
//
// cls() Clear screen
// cup(row, col) Positions the curser to a position on the console
// inKey() Reads one pressed key (Returned value is : ConsoleKeyInfo)
// inStr() Handles String
// inInt() Handles Int
// inFloat() Handles Float(Singel)
// meny() Menu system , first invariable is Rubrik and 2 to 6 meny choises
// addSodaMenu() The options for adding bottles
// Clear Screen ------------------------------------------
static public void cls()
{
Console.Clear();
}
// Set Curser Position ----------------------------------
static public void cup(int column, int rad)
{
Console.SetCursorPosition(column, rad);
}
// Key Input --------------------------------------------
static public ConsoleKeyInfo inKey()
{
ConsoleKeyInfo in_key; in_key = Console.ReadKey(); return in_key;
}
// String Input -----------------------------------------
static public string inStr()
{
string in_string; in_string = Console.ReadLine(); return in_string;
}
// Int Input -------------------------------------------
static public int inInt()
{
int int_in; try { int_in = Int32.Parse(Console.ReadLine()); }
catch (FormatException) { Console.WriteLine("Input Error \b"); int_in = 0; }
catch (OverflowException) { Console.WriteLine("Input Owerflow\b"); int_in = 0; }
return int_in;
}
// Float Input -------------------------------------------
static public float inFloat()
{
float float_in; try { float_in = Convert.ToSingle(Console.ReadLine()); }
catch (FormatException) { Console.WriteLine("Input Error \b"); float_in = 0; }
catch (OverflowException) { Console.WriteLine("Input Owerflow\b"); float_in = 0; }
return float_in;
}
// Menu ------------------------------------------------
static public int meny(string rubrik, string m_val1, string m_val2)
{ // Meny med 2 val ---------------------
int menSvar; menyRubrik(rubrik); menyRad(m_val1); menyRad(m_val2); menSvar = menyInm();
return menSvar;
}
static public int meny(string rubrik, string m_val1, string m_val2, string m_val3)
{ // Meny med 3 val ---------------------
int menSvar; menyRubrik(rubrik); menyRad(m_val1); menyRad(m_val2); menyRad(m_val3); menSvar = menyInm();
return menSvar;
}
static public int meny(string rubrik, string m_val1, string m_val2, string m_val3, string m_val4)
{ // Meny med 4 val ---------------------
int menSvar; menyRubrik(rubrik); menyRad(m_val1); menyRad(m_val2); menyRad(m_val3); menyRad(m_val4); menSvar = menyInm();
return menSvar;
}
static public int meny(string rubrik, string m_val1, string m_val2, string m_val3, string m_val4, string m_val5)
{ // Meny med 5 val ---------------------
int menSvar; menyRubrik(rubrik); menyRad(m_val1); menyRad(m_val2); menyRad(m_val3); menyRad(m_val4); menyRad(m_val5); menSvar = menyInm();
return menSvar;
}
static public int meny(string rubrik, string m_val1, string m_val2, string m_val3, string m_val4, string m_val5, string m_val6)
{ // Meny med 6 val ---------------------
int menSvar; menyRubrik(rubrik); menyRad(m_val1); menyRad(m_val2); menyRad(m_val3); menyRad(m_val4); menyRad(m_val5); ; menyRad(m_val6); menSvar = menyInm();
return menSvar;
}
static void menyRubrik(string rubrik)
{ // Meny rubrik --------
cls(); Console.WriteLine("\n\t {0}\n----------------------------------------------------\n", rubrik);
}
static void menyRad(string menyVal)
{ // Meny rad --------
Console.WriteLine("\t {0}", menyVal);
}
static int menyInm()
{ // Meny inmating ------
int mVal; Console.Write("\n\t Menyval : "); mVal = inInt(); return mVal;
}
// Menu for adding bottles --------------------------------
static public void addSodaMenu()
{
cls();
Console.WriteLine("\tChoose a beverage please.");
Console.WriteLine("\t1. Coca Cola");
Console.WriteLine("\t2. Champis");
Console.WriteLine("\t3. Grappo");
Console.WriteLine("\t4. Pripps Blå lättöl");
Console.WriteLine("\t5. Spendrups lättöl");
Console.WriteLine("\t6. Ramlösa citron");
Console.WriteLine("\t7. Vichy Nouveu");
Console.WriteLine("\t9. Exit to main menu");
Console.WriteLine("\t--------------------\n");
}
// Screen - Slut <========================================
} // screen <----
class Sodacrate
{
// Sodacrate - Methods for handling arrays and lists of Soda-objects ======================================= >
// Methods for Soda handling in this object are:
//
// cls() Clear screen
//
//
private Soda[] bottles; //Create they array where we store the up to 25 bottles
private int antal_flaskor = 0; //Keep track of the number of bottles in the crate
//Inte Klart saknar flera träffar samt exception
public int find_Soda(string drinkname)
{
//Betyg C
//Beskrivs i läroboken på sidan 147 och framåt (kodexempel på sidan 149)
//Man ska kunna söka efter ett namn
//Man kan använda string-metoderna ToLower() eller ToUpper()
for (int i = 0; i < bottles.Length; i++)
{
if (bottles[i].Drink_name == drinkname)
return i;
}
return -1;
}
//Exception error
public void sort_Sodas()
{
int max = bottles.Length;
//Outer loop for complete [bottles]
for (int i = 1; i < max; i++)
{
//Inner loop for row by row
int nrLeft = max - i;
for (int j = 0; j < (max - i); j++)
{
if (bottles[j].Product_code > bottles[j + 1].Product_code)
{
int temp = bottles[j].Product_code;
bottles[j] = bottles[j + 1];
bottles[j + 1].Product_code = temp;
}
}
}
}
/*
//Exception error
public void sort_Sodas_name()
{
int max = bottles.Length;
//Outer loop for complete [bottles]
for (int i = 1; i < max; i++)
{
//Inner loop for row by row
int nrLeft = max - i;
for (int j = 0; j < (max - i); j++)
{
if (bottles[j].Drink_name > bottles[j + 1].Drink_name)
{
int temp = bottles[j].Drink_name;
bottles[j] = bottles[j + 1];
bottles[j + 1].Drink_name = temp;
}
}
}
}
*/
//Search for Product code
public int LinearSearch(int key)
{
for (int i = 0; i < bottles.Length; i++)
{
if (bottles[i].Product_code == key)
return i;
}
return -1;
}
//Contains the menu to choose from the crates methods
public void Run()
{
bottles[0] = new Soda("Coca Cola", "Soda", 5, 1);
bottles[1] = new Soda("Champis", "Soda", 6, 1);
bottles[2] = new Soda("Grappo", "Soda", 4, 1);
bottles[3] = new Soda("Pripps Blå", "beer", 6, 2);
bottles[4] = new Soda("Spendrups", "beer", 6, 2);
bottles[5] = new Soda("Ramlösa", "water", 4, 3);
bottles[6] = new Soda("Loka", "water", 4, 3);
bottles[7] = new Soda("Coca Cola", "Soda", 5, 1);
foreach (var beverage in bottles)
{
if (beverage != null)
Console.WriteLine(beverage);
}
Console.WriteLine("\n\tYou have {0} bottles in your crate:\n\n", bottleCount());
Console.WriteLine("\nTotal value of the crate\n");
int total = 0;
for (int i = 0; i < bottleCount(); i++)
{
total = total + (bottles[i].Drink_price);
}
/* int price = 0; //Causes exception error
foreach(var bottle in bottles)
{
price = price + bottle.Drink_price;
}
*/
Console.WriteLine("\tThe total value of the crate is {0} SEK.", total);
// Console.WriteLine("\tThe total value of the crate is {0} SEK.", price);
Screen.inKey();
Screen.cls();
int test = 0;
test = bottles[3].Product_code;
Console.WriteLine("Product code {0} is in slot {1}", test, 3);
Screen.inKey();
Console.WriteLine("Type 1, 2 or 3");
int prodcode = Screen.inInt();
Console.WriteLine(LinearSearch(prodcode));
Console.WriteLine("Product code {0} is in slot {1}", prodcode, (LinearSearch(prodcode)));
Console.WriteLine(bottles[(LinearSearch(prodcode))]);
Screen.inKey();
// sort_Sodas(); //Causes Exception error I want it to sort on either product code or product name
foreach (var beverage in bottles)
{
if (beverage != null)
Console.WriteLine(beverage);
}
}
//Print the content of the crate to the console
public void print_crate()
{
foreach (var beverage in bottles)
{
if (beverage != null)
Console.WriteLine(beverage);
//else
//Console.WriteLine("Empty slot");
}
Console.WriteLine("\n\tYou have {0} bottles in your crate:", bottleCount());
}
//Construct, sets the Sodacrate to hold 25 bottles
public Sodacrate()
{
bottles = new Soda[25];
}
// Count the ammounts of bottles in crate
public int bottleCount()
{
int cnt = antal_flaskor;
// Loop though array to get not empty element
foreach (var beverages in bottles)
{
if (beverages != null)
{
cnt++;
}
}
return cnt;
}
//Calculates the total value of the bottles in the crate
public int calc_total()
{
int temp = 0;
for (int i = 0; i < bottleCount(); i++)
{
temp = temp + (bottles[i].Drink_price);
}
return temp;
}
//Adds bottles in the crate.
public void add_Soda()
{
/*Metod för att lägga till en läskflaska
Om ni har information om både pris, läsktyp och namn
kan det vara läge att presentera en meny här där man kan
välja på förutbestämda läskflaskor. Då kan man också rätt enkelt
göra ett val för att fylla läskbacken med slumpade flaskor
*/
//I start of with adding 7 bottles to avoid having to add so many bottles testing functions. Remove block before release
bottles[0] = new Soda("Coca Cola", "Soda", 5, 1);
bottles[1] = new Soda("Champis", "Soda", 6, 1);
bottles[2] = new Soda("Grappo", "Soda", 4, 1);
bottles[3] = new Soda("Pripps Blå", "lättöl", 6, 2);
bottles[4] = new Soda("Spendrups", "lättöl", 6, 2);
bottles[5] = new Soda("Ramlösa citron", "mineralvatten", 4, 3);
bottles[6] = new Soda("Vichy Nouveu", "mineralvatten", 4, 3);
//<======================================================================================================= End block
int beverageIn = 0; //Creates the menu choice-variable
while (beverageIn != 9) //Exit this menu by typing 9 - This value should be different if we add more bottle types to add.
{
Screen.addSodaMenu(); //Calls the menu in the Screen-class
Console.WriteLine("You have {0} bottles in the crate.\n\nChoose :", bottleCount());
Screen.cup(8, 13);
int i = bottleCount(); //Keeps track of how many bottles we have in the crate. If the crate is full we get expelled out of this method
if (i == 25)
{ beverageIn = 9; }
else beverageIn = Screen.inInt(); //end
switch (beverageIn) //Loop for adding bottles to the crate exit by pressing 9
{
case 1:
i = bottleCount();
bottles[i] = new Soda("Coca Cola", "Soda", 5, 1);
i++;
break;
case 2:
i = bottleCount();
bottles[i] = new Soda("Champis", "Soda", 6, 1);
i++;
break;
case 3:
i = bottleCount();
bottles[i] = new Soda("Grappo", "Soda", 4, 1);
i++;
break;
case 4:
i = bottleCount();
bottles[i] = new Soda("Pripps Blå lättöl", "lättöl", 6, 2);
i++;
break;
case 5:
i = bottleCount();
bottles[i] = new Soda("Spendrups lättöl", "lättöl", 6, 2);
i++;
break;
case 6:
i = bottleCount();
bottles[i] = new Soda("Ramlösa citron", "mineralvatten", 4, 3);
i++;
break;
case 7:
i = bottleCount();
bottles[i] = new Soda("Vichy Nouveu", "mineralvatten", 4, 3);
i++;
break;
case 9:
i = bottleCount();
if (i == 25)
{
Console.WriteLine("\tThe crate is full\n\tGoing back to main menu. Press a key: ");
}
Console.WriteLine("Going back to main menu. Press a key: ");
break;
default: //Default will never kick in as I have error handling in Screen.inInt()
Console.WriteLine("Error, pick a number between 1 and 7 or 9 to end.");
break;
}
}
}
// Sodacrate - End <========================================
class Program
{
public static void Main(string[] args)
{
//Skapar ett objekt av klassen Sodacrate som heter Sodacrate
var Sodacrate = new Sodacrate();
Sodacrate.Run();
Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);
}
}
}
}
【问题讨论】:
-
为了对某些东西进行排序,您必须以某种方式定义顺序。使用单个数字很明显,但是对于对象,您必须说明这些部分如何组合在一起来定义顺序。你定义过这样的函数吗?
-
你的老师要你写冒泡排序,所以你无论如何都不能使用
Array.Sort -
“我在一个包含一维的数组上做 [冒泡排序] 都很好”所以让我们看看。
-
@MaciejLos:不,它没有。它可以实现
IEquatable,这不是一回事,或者不同的类可以实现IEqualityComparer...或者OP可以传入一个比较委托,就像他们实际做的那样。 .. -
@MaciejLos:(实际上,我错过了你会使用
IComparer和IComparable,而不是IEqualityComparer/IEquatable来进行排序......)