0

I need your help with using one array to track 3 pieces of data. I have o use one array because it is school assignment and I am required to do so. The array has to track Province ID, Region ID and the population for each region. There is 13 province and in each province there is 48 regions. Since the array is fixed size, I used a 624 by 3 multi dimensional array. The first column is for the provinceID, the second is for the regionID, and the third one is for the population.. I set the rows to 624 because there is 13 province and 48 regions in each province so 13*48 = 624.

I was able to insert my data and display them like this

ProvinceID # 1 RegionID # 1: 125000

Instead I would like to display the regions and population by province.

Something like this:

ProvinceID #1

RegionID # 1: 12000
RegionID # 2: 30000

ProvinceID #2

RegionID #1: 14000
RegionID #: 145000

Here is what I did I declare a global array int[,] census;

I initialize it on form initialize census = new int[624,3];

Here is my insert

try
{
    // declare variables
    int prov, region, population;

    prov = Convert.ToInt32(txtProvinceID.Text);
    region = Convert.ToInt32(txtRegionID.Text);
    population = Convert.ToInt32(txtPopulation.Text);


    census[counter, 0] = prov;
    census[counter, 1] = region;
    census[counter, 2] = population;

    counter++;

    MessageBox.Show("Population " + txtPopulation.Text.ToString() + " saved for Province #" + txtProvinceID.Text.ToString()
        + " , Region #" + txtRegionID.Text.ToString(), "Success!");

    txtRegionID.Clear();
    txtProvinceID.Clear();
    txtPopulation.Clear();
    txtProvinceID.Focus();
}
catch (Exception ex)
{
    if (ex.Message == "Input string was not in a correct format.")
    {
        MessageBox.Show("Please enter a numeric value", "Error");
    }
    else
    {
        MessageBox.Show(ex.Message, "Error");
    }
}

This is the code to retrieve the data and save them to a file

string output = "";

try
{
    for (int rows = 0; rows < census.GetLength(0); rows++)
    {

        for (int columns = 0; columns < census.GetLength(1); columns++)
        {
            if (census[rows, columns] != 0)
            {
                if (columns == 0)
                {
                    output += "Province ID #" + census[rows, columns];
                }
                else if (columns == 1)
                {
                    output += "Region ID #" + census[rows, columns] + ": ";
                }
                else if (columns == 2)
                {
                    output += census[rows, columns] + "\n";
                }

            }// END if census[rows, coloumns]!=0

        }// END for coloumns

    }//END for(int row =0

    // save the data to a text file

    SaveFileDialog sfd = new SaveFileDialog();
    sfd.FileName = "untitled";
    sfd.Filter = "Text (*.txt)|*.txt|Word Doc (*.doc)|*.doc";
    sfd.DefaultExt = "txt";
    sfd.AddExtension = true;
    sfd.ShowDialog();

    FileStream sf = new FileStream(sfd.FileName, FileMode.Create);

    StreamWriter sw = new StreamWriter(sf);

    sw.Write(output);

    sw.Close();
}
catch (Exception)
{

}
4

4 回答 4

2

想象一个表格,其中行是省,列是地区。每个表格单元格中都是该省/地区的人口。它看起来像这样

            Region 1    Region 2    Region 3
Province 1   12000       13000       14000
Province 2   11320        9876        1234
Province 3   19723       32767        5038
Province 4     263        1284        1961

这正好对应一个二维数组:

int[,] census = new int[4,3];

数组中的值将是,例如:

census[0,0] = 12000;  // Province 1, Region 1
census[0,1] = 13000;  // Province 1, Region 2
census[2,2] = 5038;   // Province 3, Region 3

修改您的代码,您将创建人口普查数组:

int[,] census = new int[13, 48];

并填充它:

prov = Convert.ToInt32(txtProvinceID.Text);
region = Convert.ToInt32(txtRegionID.Text);
population = Convert.ToInt32(txtPopulation.Text);
census[prov-1, region-1] = population;

现在,如果要按省和地区输出:

StringBuilder output = new StringBuilder();
for (int prov = 0; prov < census.GetLength(0); prov++)
{
    output.AppendLine("Province ID " + prov+1);
    for (int region = 0; region < census.GetLength(1); ++region)
    {
        output.AppendLine("  Region #" + region+1 + " " +
            census[prov, region]);
    }
}

然后输出它,你打开你显示的文件和Write(output.ToString()).

我曾经StringBuilder构造输出而不是附加到string. 附加字符串非常昂贵。

此外,您可以使用File.WriteAllText简化您的文件编写,如下所示:

// Show the Save File dialog box. And then,
File.WriteAllText(sfd.Filename, output.ToString());

无需打开 aFileStream然后 a StreamWriterFile.WriteAllText为您处理所有这些。

更新

要跳过没有数据的省份,您写入一个临时StringBuilder文件,然后仅在有数据时将其附加到最终输出。例如:

StringBuilder output = new StringBuilder();
for (int prov = 0; prov < census.GetLength(0); prov++)
{
    StringBuilder sbTemp = new StringBuilder();
    for (int region = 0; region < census.GetLength(1); ++region)
    {
        if (census[prov, region] != 0)
        {
            sbTemp.AppendLine("  Region #" + region+1 + " " +
                census[prov, region]);
        }
    }
    if (sbTemp.Length > 0)
    {
        // At least one region had population, so add that
        // and the province to the output.
        output.AppendLine("Province ID " + prov+1);
        output.Append(sbTemp);
    }
}
于 2013-09-15T02:59:21.793 回答
2

该数组必须跟踪省 ID、地区 ID 和每个地区的人口。

这表明您应该创建一个class来保存这三个数据。这样,使用数组会容易得多。就像是:

class Region
{
    public int ProvinceId { get; set; }
    public int RegionId { get; set; }
    public long Population { get; set; }
}

请注意,我为人口选择了不同的类型,你不能用一个简单的数组来做到这一点,而且你肯定迟早会需要这样的东西。

当你拥有它时,你可以使用 LINQ 创建来自同一省份的区域组:

Region[] regions = …; // or maybe List<Region>

var regionGroups = regions.GroupBy(r => r.ProvinceId);

var result = new StringBuilder();

foreach (regionGroup in regionGroups)
{
    result.AppendFormat("Province ID #{0}\n\n", regionGroup.Key);

    foreach (var region in regionGroup)
    {
        result.AppendFormat(
            "Region ID #{0}: {1}\n", region.RegionId, region.Population);
    }
}

return result.ToString();

此外,你永远不应该这样做:

catch (Exception)
{
}

如果您需要处理一些特定的异常,请处理那些,但只处理那些.

于 2013-09-14T15:54:53.363 回答
0

如果您真的特别不使用对象或数据库表来存储值并且也不想使用 LINQ,那么以下解决方案可能会对您有所帮助

        void Select(string key)
        {
            for(int i=0;i<624;i++)
            {
                if(census[i][0]==key)
                {
                    Console.Write(census[i][1]);
                    Console.Write(census[i][2]);
                    Console.WriteLine();

                }

            }
        }

为了消除重复数据,我们使用 List 来检查之前是否检查过该 Province Id

            string done = "";
            for (int i = 0; i < 624; i++)
            {
                if (!done.Contains(census[i][0]))
                {
                    Console.WriteLine(census[i][0]);
                    Select(census[i][0]);
                }
                done=done+census[i][0];
            }

我希望这段代码对你有帮助,但这真的不是一个好的编程方式。

于 2013-09-14T17:23:34.567 回答
0

我觉得你现在的程序设计真的很难做到这一点

我建议您使用锯齿状数组来存储值,因为LINQ 不能用于 2D 数组

锯齿状数组是“数组数组”

string[][] census=new string[624][];

for(int i=0;i<624;i++)
{
census[i]=new string[3];
}

现在您可以使用 LINQ 从数组中获取所需的数据

var match=from c in census 
          where c[0]=="Province ID Text"
          from details in c
          where details!="Province ID Text"
          select details;

并按如下方式打印值

foreach(var i in match)
Console.WriteLine(i);
于 2013-09-14T15:43:54.127 回答