Reputation: 535
I have to write an algorithm to sort the names according to the second parameter, I am not able to get the logic how to do , the input file will contain data like this :
Jervie, 12, M , Jaimy ,11, F, Tony , 23, M ,Janey , 11, F
And the output has to be like this:
Jaimy, 11, F , Janey, 11, F, Jervie ,12, M, Tony , 23, M
They are sorted on the basis of second parameter, I have read this file and stored the data in struct array:
struct element
{
public string name;
public int numComp;
public string sex;
} ;
Now i am thinking of doing sorting numComp
, But how to process for algo , that's what i am not able to understand , Could some one help me please ?, If you know any other optimal solution then please do not hesitate to give, Thanks
My full code for what i done yet is :
class Program
{
struct element
{
public string name;
public string sex;
public int numComp;
} ;
static void Main(string[] args)
{
string appRootDir = new DirectoryInfo(Environment.CurrentDirectory).Parent.Parent.FullName;
string text = System.IO.File.ReadAllText(appRootDir+"\\File.txt");
string[] words = text.Split(new Char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
int counter = 0 ,pos=0;
element[] storage = new element[words.Count()/3];
foreach(string str in words)
{
if(counter==0)
{
storage[pos].name = str;
counter++;
}
else if (counter == 1)
{
storage[pos].numComp = Int32.Parse(str);
counter++;
}
else if(counter==2)
{
storage[pos].sex = str;
counter = 0; pos++;
}
}
//Now how to sort on the basis of numComp and print the output as desired ?
Console.ReadKey();
}
}
Now how to sort on the basis of numComp and print the output as desired ?
Upvotes: 1
Views: 727
Reputation: 1
You can sort as below -
String [] input = {"Jervie,12,M" , "Jaimy,11,F", "Tony,23,M" ,"Janey,11,F"};
List<String> al= Arrays.asList(input);
Collections.sort(al, (o1, o2) -> Integer.parseInt(o1.split(",")[1]) - Integer.parseInt(o2.split(",")[1]));
OR
private String [] sort (String [] input) {
PriorityQueue<String> pq = new PriorityQueue<>((o1, o2) -> Integer.parseInt(o1.split(",")[1]) - Integer.parseInt(o2.split(",")[1]));
for (String s : input) {
pq.add(s);
}
String [] res = new String[input.length];
int i=0;
while(!pq.isEmpty()){
res [i++] = pq.poll();
}
return res;
}
Upvotes: 0
Reputation: 1958
Hey you could do it like this,
I have created a linq Extension method which creates chunks from IEnumerable(see this post for more detail about creating chunk from IEnumerable input Split List into Sublists with LINQ)
Check this fiddle for output https://dotnetfiddle.net/VlkRot
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
public class Program
{
struct element
{
public string name;
public string sex;
public int numComp;
} ;
public static void Main()
{
string input = "Jervie, 12, M , Jaimy ,11, F, Tony , 23, M ,Janey , 11, F";
var elements = input.Split(',').Where(x => !string.IsNullOrWhiteSpace(x))
.Select(x => x.Trim()).Chunk(3)
.Select(x =>
{
var i = x.ToList();
return new element
{
name = i[0],
numComp = int.Parse( i[1]),
sex = i[2],
};
});
var sorted = elements.OrderBy(x => x.numComp).ToList();
var temp = sorted.Select(x => x.name + ", " + x.numComp+", " + x.sex );
var output = string.Join(", ",temp);
Console.WriteLine(output);
}
}
public static class LinqExtension
{
public static IEnumerable<IEnumerable<T>> Chunk<T>(this IEnumerable<T> source, int chunksize)
{
while (source.Any())
{
yield return source.Take(chunksize);
source = source.Skip(chunksize);
}
}
}
Upvotes: 1
Reputation: 535
I have done it and this is the solution
class Program
{
struct element
{
public string name;
public string sex;
public int numComp;
public bool flag;
} ;
static void Main(string[] args)
{
int[] arr = { 5, 1, 6, 3, 4, 5, 8, 3, 9, 2, 6, 7 };
string appRootDir = new DirectoryInfo(Environment.CurrentDirectory).Parent.Parent.FullName;
string text = System.IO.File.ReadAllText(appRootDir + "\\File.txt");
string[] words = text.Split(new Char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
int counter = 0, pos = 0; int[] storeNum = new int[words.Count() / 3];
element[] storage = new element[words.Count() / 3];
element[] storage2 = new element[words.Count() / 3];
foreach (string str in words)
{
if (counter == 0)
{
storage[pos].flag = false;
storage[pos].name = str;
counter++;
}
else if (counter == 1)
{
storeNum[pos] = storage[pos].numComp = Int32.Parse(str);
counter++;
}
else if (counter == 2)
{
storage[pos].sex = str;
counter = 0; pos++;
}
}
int[] mergeSorted = mergeSort(storeNum); //How to proceed here ?
int posit = 0, counterr = 0;
foreach (int num in mergeSorted)
{
for (int i = 0; i < 4; i++)
{
if (storage[i].numComp == num && storage[i].flag==false)
{
storage[i].flag = true;
storage2[posit++] = storage[i];
break;
}
counterr++;
}
}
Console.ReadKey();
}
private static int[] mergeSort(int[] arr)
{
if (arr.Count() <= 1)
{
return arr;
}
int mid = arr.Count() / 2;
int[] left = new int[mid];
int[] right = new int[arr.Count() - mid];
for (int i = 0; i < mid; i++)
{
left[i] = arr[i];
}
int k = 0;
for (int i = mid; i < arr.Count(); i++)
{
right[k++] = arr[i];
}
int[] leftVal = mergeSort(left);
int[] rightVal = mergeSort(right);
int[] merged = mergesort(leftVal, rightVal);
return merged;
}
private static int[] mergesort(int[] leftVal, int[] rightVal)
{
List<int> finalArr = new List<int>(leftVal.Count() + rightVal.Count());
List<int> left = new List<int>(leftVal);
List<int> right = new List<int>(rightVal);
while (left.Count != 0 && right.Count() != 0)
{
if (left[0] < right[0])
{
finalArr.Add(left[0]);
left.RemoveAt(0);
}
else
{
finalArr.Add(right[0]);
right.RemoveAt(0);
}
}
while (left.Count != 0)
{
finalArr.Add(left[0]);
left.RemoveAt(0);
}
while (right.Count != 0)
{
finalArr.Add(right[0]);
right.RemoveAt(0);
}
return finalArr.ToArray();
}
}
Upvotes: 0
Reputation: 3433
Take Any Sorting Algorithm (You can find some sorting algorithms explained + code at This Link),
Implement it, and replace the comparison function to
int myElementCmpFunc(element a, element b){
return Int32.Compare(a.numCorp, b.numCorp);
}
and pass this function to your sorting algorithm.
Note in the link, there is no Compare Function, but implied to replace
code like if (x <= pivot)
with if(myElementCmpFunc(x,pivot) <= 0)
Note2 if comparing by numCorp is the general Compare function, you can override the default compare function with your function, and make it so a <= b
will be valid by comparing numCorp.
Upvotes: 4
Reputation: 7301
I assume you mean as second Parameter that the result should be ordered by numCorp
, so why don't you use LINQ-Queries
:
var orderedList = storage.OrderBy(i => i.numCorp);
Upvotes: 4