|
||
|
|
#1 (permalink) |
|
Forum Expert
|
I have a problem with an array, and it seems like an easy solution that i have seen before..but cannot find where...
I have a array filled with...animals, lots of different types. I want the array to count how many of each animal there are in the array(done that)..without counting the same animal again later on... Code:
private void CountTypes()
{
foreach (string s in m_types)
{
int count = 0;
for (int i = 0; i < m_types.Count; i++)
{
if (s == m_types[i].ToString())
{
if (count == 0)
m_filetypes.Add(m_types[i].ToString());
count++;
}
}
m_filecount.Add(count);
}
for (int i = 0; i < m_filetypes.Count; i++)
{
SetText4(""+m_filetypes[i]+" "+m_filecount[i]);
}
}
I cannot remove the 'animal' for it would change the size of the array, and replacing the animal did nothing... ('animals' are an example) |
|
|
|
|
|
#2 (permalink) |
|
Forum Expert
|
create a hash (or hash style array).
use the animal type as the index. loop through the original array. foreach animaltype in the array, increment the integer at the animaltype's index. you only have to go through the array one time this way. i use the same technique to calculate an image's precise histogram, and it works super quick. (you'll have to pardon me on this one, i'm a ruby programmer much more than c#, so i'm not sure exactly what datatype you'd use) |
|
|
|
|
|
#3 (permalink) |
|
Forum Expert
Join Date: Nov 2003
Location: Illinois, USA
Age: 21
Posts: 2,911
|
Ok, I think this is what you want, but Im not sure
Code:
public static Dictionary<string,int> CountTypes(string[] array)
{
Dictionary<string, int> types = new Dictionary<string, int>();
foreach (string s in array)
{
if (!types.ContainsKey(s))
{
types.Add(s, 1);
}
else
{
types[s] += 1;
}
}
return types;
}
This was my example to test it Code:
static void Main(string[] args)
{
string[] m_types = new string[] { "Dog", "Cat", "Donkey", "Dog", "Lizard","Cat","Zebra", "Horse", "Horse","Dog" };
Dictionary<string, int> types = CountTypes(m_types);
foreach (string s in types.Keys)
{
Console.WriteLine("{0} - {1}",s,types[s]);
}
Console.WriteLine();
Console.WriteLine("Total types - {0}",types.Count);
Console.ReadLine();
}
|
|
|
|
|
|
#4 (permalink) |
|
Forum Expert
|
Thats what i thought would happen.. the main problem behind this is that i do not know what strings are going to be put into these array lists. The top part of the code(which i diddnt provide, i will later) goes and looks for that info. So, something like dictionaries would not be possible.
But, thanks for that sample.. @Nochte: sounds interesting, ill check it out! (wont let me + ya, Nochte) |
|
|
|
|
|
#5 (permalink) |
|
ConnectUO Creator
Join Date: Jan 2004
Location: In your mom
Age: 27
Posts: 4,760
|
if they are animals, and these animals are different objects, cant u do
Dictionary<Type, int>
__________________
Jeff Boulanger ConnectUO - Core Developer Want to help make ConnectUO better? Click here to submit your ideas/requests Use your talent to compete against other community members in RunUO hosted coding competitions If you know XNA (even if its just a little) or are a good artist(2d or 3d) and are interested in making games for a hobby send me a pm or drop by #xna in irc.runuo.com. I'm looking to put together a small game development team. Please do not pm me for support. If you are having issues please post in the appropriate forum. Thanks for your continued support of both ConnectUO and RunUO |
|
|
|
|
|
#6 (permalink) | |
|
Forum Expert
|
Quote:
There are basically two ways to do this, record the animals that have been processed already (which can be done with a hash table, as has been demonstrated already), or sort the array of animals first, then only do the actual processing each time the animal changes and keep a local count of the current animal like you do now. Of course each has its own benefits and drawbacks. Also, you don't need to know which animals there are in the array beforehand to use a Dictionary, mordero just used one in his example, likely to make it simpler than it would have been had he not. Rather than calling Add the first time you encounter it, you could just use the index operator that the Dictionary has that adds the key with a given value if it is not in the table and sets the key's value to a given value if it already exists. Then you could just check to see if the value is equal to one and if so do the processing on it since it's the first time the animal has been encountered. Of course, this is essentially what Nochte was advocating as well, I was just more long winded about it. Since I'm bored, a more concrete example could be Code:
private void CountTypes ()
{
Dictionary<String, Int32> animals = new Dictionary<String, Int32>();
foreach ( string s in m_types )
{
++animals[s];
}
foreach ( KeyValuePair<String, Int32> keyVal in animals )
{
m_filetypes.Add( keyVal.Key );
m_filecount.Add( keyVal.Value );
}
for ( int i = 0; i < m_filetypes.Count; i++ )
{
SetText4( "" + m_filetypes[i] + " " + m_filecount[i] );
}
}
Last edited by Sep102; 12-28-2006 at 02:04 AM. |
|
|
|
|
|
|
#7 (permalink) | |
|
Forum Expert
Join Date: Nov 2003
Location: Illinois, USA
Age: 21
Posts: 2,911
|
Quote:
If you wanted it outputted in the same format as your example of Code:
SetText4(""+m_filetypes[i]+" "+m_filecount[i]);
Code:
Dictionary<string, int> blah = CountTypes(m_types);
foreach (string filetype in blah.Keys)
{
SetText4(filetype + " " + blah[filetype]);//you dont need that first ""+
}
|
|
|
|
|
|
|
#8 (permalink) |
|
Forum Expert
|
Ok see a lot of new code..so if you all dont mind..im going to ask a few question on what these snippets do?
Code:
public static Dictionary<string,int> CountTypes(string[] array)
{
Dictionary<string, int> types = new Dictionary<string, int>();
foreach (string s in array)
{
if (!types.ContainsKey(s))
{
types.Add(s, 1);
}
else
{
types[s] += 1;
}
}
return types;
}
------------------------------------- Code:
private void CountTypes ()
{
Dictionary<String, Int32> animals = new Dictionary<String, Int32>();
foreach ( string s in m_types )
{
++animals[s];
}
foreach ( KeyValuePair<String, Int32> keyVal in animals )
{
m_filetypes.Add( keyVal.Key );
m_filecount.Add( keyVal.Value );
}
for ( int i = 0; i < m_filetypes.Count; i++ )
{
SetText4( "" + m_filetypes[i] + " " + m_filecount[i] );
}
}
![]() ------------------- The program i am making goes through a destination on your hard drive, and will 'take inventory' of all the file types in that destination..it will say "144 files - 44 were .ppt 100 were .isd " - like that.. Last edited by BeneathTheStars; 12-28-2006 at 02:21 AM. |
|
|
|
|
|
#9 (permalink) |
|
Forum Expert
|
The code:
Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Collections;
using System.Threading;
using System.Security;
using System.Diagnostics;
namespace DiskAnalyzer
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public int counter = 0;
public string location,location2 = "";
public bool active = false;
private ArrayList m_types = new ArrayList();
private ArrayList m_filetypes = new ArrayList();
private ArrayList m_filecount = new ArrayList();
delegate void SetTextCallback(string text);
delegate void SetActiveCallback(bool on);
private void button1_Click(object sender, EventArgs e)
{
Status(counter, location, active);
Thread th = new Thread(new ThreadStart(startproc));
th.Start();
}
private void Status(int counter, string location, bool active)
{
SetText(location);
SetText2(counter.ToString());
SetText3(active.ToString());
}
private void SetText(string text)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true. -msdn
if (this.label5.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else
{
this.label5.Text = text;
}
}
private void SetText2(string text)
{
if (this.label6.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText2);
this.Invoke(d, new object[] { text });
}
else
label6.Text = text;
}
private void SetText3(string text)
{
if (this.label7.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText3);
this.Invoke(d, new object[] { text });
}
else
{
this.label7.Text = text;
}
}
private void SetText4(string text)
{
if (this.textBox1.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText4);
this.Invoke(d, new object[] { text });
}
else
{
this.textBox1.Text += text;
}
}
private void SetOn(bool enable)
{
if (this.button1.InvokeRequired)
{
SetActiveCallback d = new SetActiveCallback(SetOn);
this.Invoke(d, new object[] { enable });
}
else
{
this.button1.Enabled = enable;
}
}
public void startproc()
{
location2 = textBox2.Text;
DirectoryInfo di = new DirectoryInfo(@location2);
active = true;
SetOn(false);
Status(counter, location,active);
CountFiles(di);
CountTypes();
Reset();
}
private void Reset()
{
active = false;
Status(counter, location, active);
counter = 0;
MessageBox.Show("Done!");
SetOn(true);
}
private void CountFiles(DirectoryInfo dri)
{
try {
FileInfo[] gfiles = dri.GetFiles();
foreach (FileInfo fl in gfiles)
{
counter += 1;
m_types.Add(fl.Extension.ToString().ToLower());
}
DirectoryInfo[] dri2 = dri.GetDirectories();
foreach (DirectoryInfo drx in dri2)
CountFiles(drx);
}
catch { }
location = dri.FullName.ToString();
Status(counter, location, active);
}
private void CountTypes()
{
foreach (string s in m_types)
{
int count = 0;
for (int i = 0; i < m_types.Count; i++)
{
if (s == m_types[i].ToString())
{
if (count == 0)
m_filetypes.Add(m_types[i].ToString());
count++;
}
}
m_filecount.Add(count);
}
for (int i = 0; i < m_filetypes.Count; i++)
{
SetText4(""+m_filetypes[i]+" "+m_filecount[i]);
}
}
}
}
|
|
|
|
|
|
#10 (permalink) | |
|
Forum Expert
Join Date: Nov 2003
Location: Illinois, USA
Age: 21
Posts: 2,911
|
Quote:
|
|
|
|
|
|
|
#11 (permalink) |
|
Forum Expert
|
Got it to do as i want.. thanks very much mordero, Sep102, Jeff, and Nochte!
Here it is: Code:
private void CountTypes()
{
Dictionary<string, int> types = new Dictionary<string, int>();
foreach (string s in m_types)
{
if (!types.ContainsKey(s))
types.Add(s, 1);
else
types[s] += 1;
}
foreach (string filetype in types.Keys)
{
if (types[filetype] == 1)
continue;
SetText4(filetype + " " + types[filetype] + "\r\n");
}
}
Once i get the whole thing done, i will post it! |
|
|
|
|
|
#13 (permalink) | |
|
Forum Expert
|
Quote:
|
|
|
|
|
|
|
#14 (permalink) | |
|
Forum Expert
|
Quote:
Last edited by Sep102; 12-28-2006 at 03:24 AM. |
|
|
|
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|