meifungnano Posted June 15, 2004 Share Posted June 15, 2004 (edited) Anybody can help me with the programming problem here? I have problem in sorting the arraylist, and this is my work: problem: I use the infile consists of people's names, and have to sort them ascending order, and store them in the ouput file. using System;using System.IO; using System.Collections; namespace Lab_6 { class Class1 { static void Main(string[]args) { Console.Write("This program will read all names from the file, eliminate the duplicate names, "); Console.WriteLine("sort them in ascending orders, and save the result in another file."); Console.WriteLine(""); ArrayList names = new ArrayList(); string infile, filename; Console.Write("Enter the input file name:"); infile = Console.ReadLine(); if (!File.Exists(infile)) return; Console.WriteLine("File Exists."); StreamReader sr = File.OpenText(infile); Console.Write("Enter the output file:"); filename = Console.ReadLine(); if (File.Exists(filename)) Console.Write("Do you want to overwrite(Y/N)?"); string ans = (Console.ReadLine()); if (!ans.Equals("Y")) return; StreamWriter op = File.CreateText(filename); string name1; I'm having problem with the folowing segments, kep showing the araylist is 0 while ((name1 = sr.ReadLine())!=null) { for (int i=0;name1 != null;i++) { Console.WriteLine(name1); if (names.Count == 0) names.Add(name1); if (name1.CompareTo (names[i-1])<0) names.Insert(i,name1); if (name1.CompareTo (names[i-1]) > 0) names.Add(name1); } } Console.WriteLine(names.Count); StreamWriter op = File.CreateText(filename); for (int y=1;y<names.Count;y++) { op.WriteLine(names[y]); } op.Close(); } } } Edited June 15, 2004 by meifungnano Link to comment Share on other sites More sharing options...
0 azcodemonkey Posted June 15, 2004 Share Posted June 15, 2004 From what I can tell, unless you are doing something somewhere else, you are iterating through an empty arraylist, names. Look at your foreach statement. A suggestion: Create a class or struct that implements IComparable that represents a name. Read the name into a new instance of the struct or class. Add the instance to the ArrayList. Then, once you are finished reading the names into the ArrayList, use the ArrayList's Sort method to sort the names. Link to comment Share on other sites More sharing options...
0 meifungnano Posted June 15, 2004 Author Share Posted June 15, 2004 for best efficiency, my instructor told me to use insert rather than Sort. So the flow should be as follows: -Read the Line -Compare with all existing arraylist elements -Sort using Insert or Add into proper alphabetical place using CompareTo - And then output the contents of ArrayList into the output file. Basically, i'm stuck with CompareTo, Insert, and Add. Link to comment Share on other sites More sharing options...
0 azcodemonkey Posted June 15, 2004 Share Posted June 15, 2004 (edited) Your instructors idea is debatable. Nonetheless, I don't think you read the first part of my last message. You are trying to iterate through an empty arraylist, so you never add anything to it, hence the 0 count. You could also utilize the BinarySearch method of the arraylist to find your insertion index. The BinarySearch method returns the index of the next largest item if the search item isn't found. You can do away with the foreach statement altogether with this method. int insertIndex; ... insertIndex = names.BinarySearch( name1 ); names.Insert( ~insertIndex, name1 ); ... Edited June 15, 2004 by weenur Link to comment Share on other sites More sharing options...
0 meifungnano Posted June 15, 2004 Author Share Posted June 15, 2004 Unfortunately, can't use binary search, bubble sort, nor Linear search, we just use CompareTo. I'm making progress with the following code, but it's sorting only the first 2 elements and simply rewriting the rest. My input file just looks like Joe Schmoe Linda Schmoe Jerry Schmoe and so on... Can't use indexOf either :( while ((name1 = sr.ReadLine())!=null) { names.TrimToSize(); for (int i=0;name1 != null;i++) { if (names.Count == 0) { names.Add(name1); break; } if (name1.CompareTo (names) == 0) break; if (name1.CompareTo (names)<0) { names.Insert(i,name1); break; } if (name1.CompareTo (names) > 0) { names.Add(name1); break; } continue; } } Link to comment Share on other sites More sharing options...
0 kjordan2001 Posted June 15, 2004 Share Posted June 15, 2004 Why are you using name1 != null as your loop check? Why not use i < names.Count? And I was about to say, before you added the breaks, that that looked like an infinite loop. Link to comment Share on other sites More sharing options...
0 azcodemonkey Posted June 15, 2004 Share Posted June 15, 2004 Too bad you cant use the BinarySearch. It's 2 lines of code. :( I would think you would want to continue to loop if the CompareTo is > 0 and not add anything yet. You want to keep testing until the item is less than or equal to the current index, or until the loop is finished. Also, the last continue isn't necessary. Link to comment Share on other sites More sharing options...
0 azcodemonkey Posted June 15, 2004 Share Posted June 15, 2004 Why are you using name1 != null as your loop check? Why not use i < names.Count? And I was about to say, before you added the breaks, that that looked like an infinite loop. I didn't even notice that. Good catch. You should test for an empty arraylist first, then if it isn't empty enter a loop using the arraylist's count as the exit condition. Link to comment Share on other sites More sharing options...
0 meifungnano Posted June 15, 2004 Author Share Posted June 15, 2004 for (int i=0;name1 != null;i++) { if (names.Count == 0) // this line tests for the empty Array { names.Add(name1); break; } I can use name1 != null, because I want it to loop until it finds a break point, which i have provided for every condition of CompareTo Link to comment Share on other sites More sharing options...
0 meifungnano Posted June 15, 2004 Author Share Posted June 15, 2004 I really hate compareto :p Link to comment Share on other sites More sharing options...
0 azcodemonkey Posted June 15, 2004 Share Posted June 15, 2004 OK. Your code won't work because you really only test against the first element in the arraylist. It should insert the first 3 correctly, but afterward, you're hosed as you've seen. You need to continue looping if your name1 is greater than the current name in the list. You also need to test to see if the index is == the list count minus one and if the name1 is greater than the last item in the list. If it is, you need to add at that point. That should be the only time you add an item. Link to comment Share on other sites More sharing options...
0 kjordan2001 Posted June 15, 2004 Share Posted June 15, 2004 Try this: if ((name1=sr.ReadLine()) != null) { ?names.Add(name1); ?while ((name1 = sr.ReadLine())!=null) ?{ ? ? ?names.TrimToSize(); ? ?for (int i=0;i < names.Count;i++) ? ?{ ? ? ? ? ?if (i == (names.Count - 1)) { ? ? ? ?names.Add(name1); ? ? ? ?break; ? ? ?} ? ? ?if (name1.CompareTo (names[i]) == 0) ? ? ?break; ? ? ? ? ? ?if (name1.CompareTo (names[i])<0) ? ? ?{ ? ? ?names.Insert(i,name1); ? ? ?break; ? ? ?} ? ? ?if (name1.CompareTo (names[i]) > 0) ? ? ?{ ? ? ? ? ?names.Add(name1); ? ? ?break; ? ? ?} ? ? ?continue; ? ?} ?} ? } Link to comment Share on other sites More sharing options...
0 meifungnano Posted June 16, 2004 Author Share Posted June 16, 2004 Try this: if ((name1=sr.ReadLine()) != null) { names.Add(name1); while ((name1 = sr.ReadLine())!=null) { names.TrimToSize(); for (int i=0;i < names.Count;i++) { if (i == (names.Count - 1)) { names.Add(name1); break; } if (name1.CompareTo (names[i]) == 0) break; if (name1.CompareTo (names[i])<0) { names.Insert(i,name1); break; } if (name1.CompareTo (names[i]) > 0) { names.Add(name1); break; } continue; } } } This one sorted 2 elements, and the rest was not sorted. I'm back on the ball tonight, for as long as my brain continues to work, not much longer though, since I just had a 3 hr nap through the NBA finals (who won?...and who cares) and i'm still drained. if ((name1=sr.ReadLine()) != null) { names.Add(name1); while ((name1 = sr.ReadLine())!=null) { for (int i = 0, n = names.Count; i < n; i++) { if (name1.CompareTo(names) > 0) { if (i == names.Count - 1) { names.Add(name1); break; } continue; } if (name1.CompareTo(names) < 0) names.Insert(i, name1); if (name1.CompareTo(names) == 0) break; } I believe this one works, not so sure, i may have my alphabet backwards by now. Link to comment Share on other sites More sharing options...
0 meifungnano Posted June 16, 2004 Author Share Posted June 16, 2004 It didn't work, gets an infinite loop on 2/3 of my test files. I was really happy when it sorted the first of the three. :( Link to comment Share on other sites More sharing options...
0 kjordan2001 Posted June 16, 2004 Share Posted June 16, 2004 It didn't work, gets an infinite loop on 2/3 of my test files. I was really happy when it sorted the first of the three. :( It probably never breaks. if ((name1=sr.ReadLine()) != null) { names.Add(name1); while ((name1 = sr.ReadLine())!=null) { for (int i = 0, n = names.Count; i < n; i++) { if (i == names.Count - 1) { names.Add(name1); break; } if (name1.CompareTo(names[i]) > 0) { continue; } if (name1.CompareTo(names[i]) < 0) names.Insert(i, name1); if (name1.CompareTo(names[i]) == 0) break; } Link to comment Share on other sites More sharing options...
0 meifungnano Posted June 16, 2004 Author Share Posted June 16, 2004 Oh Man! hold up... Something else in her code is out of order, I think the Code is Elite now, at least what i've Done :) Give me a Sec, I think we'll have a final update Link to comment Share on other sites More sharing options...
0 kjordan2001 Posted June 16, 2004 Share Posted June 16, 2004 ? //if (File.Exists(filename)) ? ?//Console.Write("Do you want to overwrite(Y/N)?"); ? //string ans = (Console.ReadLine()); ? ? //if (!ans.Equals("Y")) ? ?//return; I commented this part out and it runs fine. And no wonder, it needs to look like: if (File.Exists(filename)) { ? ?Console.Write("Do you want to overwrite(Y/N)?"); ? ? string ans = (Console.ReadLine()); ? ? if (!ans.Equals("Y")) ? ?return; } Your infinite loop was no more than your console awaiting input. I kept wondering why when I hit enter it exited. Link to comment Share on other sites More sharing options...
0 meifungnano Posted June 16, 2004 Author Share Posted June 16, 2004 It's working Now! Here's the final picture! Give it a Try Copy & Paste into .Net, make sure you select C# Console Application (for any ppl just watchin the thread) then Ctrl + F5 it. using System; using System.IO; using System.Collections; namespace Lab_6 { class Class1 { static void Main(string[]args) { ArrayList names = new ArrayList(); string infile, outfile, name1, ans = "Y"; Console.Write("This program will read all names from the file, eliminate the duplicate names, "); Console.WriteLine("sort them in ascending orders, and save the result in another file."); Console.WriteLine(""); Console.Write("Enter the input file name:"); infile = Console.ReadLine(); if (!File.Exists(infile)) return; Console.WriteLine("File Exists."); Console.Write("Enter the output file:"); outfile = Console.ReadLine(); if (File.Exists(outfile)) //She forgot to nest the following { Console.Write("Do you want to overwrite(Y/N)?"); ans = (Console.ReadLine()); if (!ans.Equals("Y")) return; } StreamWriter sw = File.CreateText(outfile); StreamReader sr = File.OpenText(infile); if ((name1=sr.ReadLine()) != null) { names.Add(name1); } while ((name1 = sr.ReadLine())!=null) { for (int i = 0; i < names.Count; i++) { if (name1.CompareTo(names) < 0) names.Insert(i, name1); if (name1.CompareTo(names) > 0) { if (i == names.Count - 1) { names.Add(name1); break; } continue; } if (name1.CompareTo(names) == 0) break; } } for (int y=0; y<names.Count; y++) { sw.WriteLine(names[y]); } sw.Close(); } } } Sample input file, specify it's location on your HD when you run the program Dark RyuMichael Jordan Wail Matarbazi Michael Muresan meifungnano Cristopher Vogt John Madden George Bush Joe Montana Dark Ryu George Steinbeck Sgt. Pepper Sgt. Pepper George Bush John Madden John Adams Benjamin Franklin Thomas Jefferson Link to comment Share on other sites More sharing options...
0 +Fulcrum Subscriber¹ Posted June 16, 2004 Subscriber¹ Share Posted June 16, 2004 //if (File.Exists(filename)) //Console.Write("Do you want to overwrite(Y/N)?"); //string ans = (Console.ReadLine()); //if (!ans.Equals("Y")) //return; I commented this part out and it runs fine. And no wonder, it needs to look like: if (File.Exists(filename)) { Console.Write("Do you want to overwrite(Y/N)?"); string ans = (Console.ReadLine()); if (!ans.Equals("Y")) return; } Your infinite loop was no more than your console awaiting input. I kept wondering why when I hit enter it exited. =) Thanks Again! Btw, is there a way to clock this one vs. the one I completed last night? I want to see if one is actually more efficient in clock cycles as the instructor suggested. Link to comment Share on other sites More sharing options...
0 kjordan2001 Posted June 16, 2004 Share Posted June 16, 2004 Looks like we found the same thing :laugh: Link to comment Share on other sites More sharing options...
0 kjordan2001 Posted June 16, 2004 Share Posted June 16, 2004 Timing: using System; using System.Collections; using System.IO; namespace ConsoleApplication1 { /// <summary> /// Summary description for Class1. /// </summary> class Class1 { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main(string[] args) { TimeZone myTime = TimeZone.CurrentTimeZone; TimeSpan myTimeSpan = myTime.GetUtcOffset(new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day)); DateTime today = DateTime.UtcNow; //Localtime = UTC + UTC Offset today = today.Add(myTimeSpan); //Holds the current time components TimeSpan start = today.TimeOfDay; Console.Write("This program will read all names from the file, eliminate the duplicate names, "); Console.WriteLine("sort them in ascending orders, and save the result in another file."); Console.WriteLine(""); ArrayList names = new ArrayList(); string infile, filename; Console.Write("Enter the input file name:"); infile = Console.ReadLine(); if (!File.Exists(infile)) return; Console.WriteLine("File Exists."); StreamReader sr = File.OpenText(infile); Console.Write("Enter the output file:"); filename = Console.ReadLine(); if (File.Exists(filename)) { Console.Write("Do you want to overwrite(Y/N)?"); string ans = (Console.ReadLine()); if (!ans.Equals("Y")) return; } StreamWriter op = File.CreateText(filename); string name1 = sr.ReadLine(); Console.WriteLine(name1); if (name1 != null) { Console.WriteLine("Inserting "+name1); names.Add(name1); while ((name1 = sr.ReadLine())!=null) { for (int i = 0, n = names.Count; i < n; i++) { if (i == names.Count - 1) { names.Add(name1); break; } if (name1.CompareTo(names[i]) > 0) { continue; } if (name1.CompareTo(names[i]) < 0) names.Insert(i, name1); if (name1.CompareTo(names[i]) == 0) break; } } } Console.WriteLine(names.Count); for (int y=1;y<names.Count;y++) { op.WriteLine(names[y]); } op.Close(); myTimeSpan = myTime.GetUtcOffset(new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day)); today = DateTime.UtcNow; //Localtime = UTC + UTC Offset today = today.Add(myTimeSpan); TimeSpan end = today.TimeOfDay; Console.WriteLine("Total time: "+end.Subtract(start)); Console.ReadLine(); } } } Link to comment Share on other sites More sharing options...
0 +Fulcrum Subscriber¹ Posted June 16, 2004 Subscriber¹ Share Posted June 16, 2004 Who woulda guessed, this one is faster than the one I wrote last night! Total time: 00:00:00.2812500 vs. Total time: 00:00:00.6875000 (maybe because I used sort() ) It is quite a difference too, hmph. :sleep: I got full credit for what I did last night, unfortunately my friend the author of this thread, she wasn't so fortunate, I think the professor gave her partial credit! Anyway, i'm about to give the Linear, and Binary searches a try. And i've already been warned about the terribly slow bubbleSort, which is supposedly only most efficient when 99% of the elements are in the correct order, leaving only 1 to be sorted :) I thought that was funny when the prof told us so. Thank goodness I only have 1 more Final then i'm going for a vacation, I need one of those every year! Link to comment Share on other sites More sharing options...
0 pHuzi0n Posted June 16, 2004 Share Posted June 16, 2004 That code counts while the user inputs the filenames... And for accurate results you ought to use a large dataset; find a 1 MB txt file laying around your drive and sort that. Link to comment Share on other sites More sharing options...
0 +Fulcrum Subscriber¹ Posted June 16, 2004 Subscriber¹ Share Posted June 16, 2004 That code counts while the user inputs the filenames...And for accurate results you ought to use a large dataset; find a 1 MB txt file laying around your drive and sort that. I did implement it into the Sorting routine in my codes. I increased the infile size as well, but not to 1MB, i'll try that now. I was just discovering the new features in Yahoo Email, they upgraded all the Free Accounts, pretty cool stuff, I think AddressGuard is new, lets you create dummy emails that are disposable, such as for spam, etc... Link to comment Share on other sites More sharing options...
0 kjordan2001 Posted June 16, 2004 Share Posted June 16, 2004 That code counts while the user inputs the filenames...And for accurate results you ought to use a large dataset; find a 1 MB txt file laying around your drive and sort that. Whoops, copied and pasted part of that, didn't really pay attention to where I did either :p Link to comment Share on other sites More sharing options...
0 +Fulcrum Subscriber¹ Posted June 16, 2004 Subscriber¹ Share Posted June 16, 2004 New Results! I ran it consecutively a few times, to see if the scores would stabilize Total time: 00:00:19.3125000 (tonights') vs. Total time: 00:00:51.3281250 (last nights') My instructor was def right about efficiency, it's quite the difference here. BTW, I oops'd and created a 25MB txt file :laugh: and that's what these tests are a result of. Link to comment Share on other sites More sharing options...
Question
meifungnano
Anybody can help me with the programming problem here? I have problem in sorting the arraylist, and this is my work:
problem: I use the infile consists of people's names, and have to sort them ascending order, and store them in the ouput file.
Edited by meifungnanoLink to comment
Share on other sites
26 answers to this question
Recommended Posts