struggling
struggling

Reputation: 535

How to sort based on second parameter

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

Answers (5)

devmohd
devmohd

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

Arjun Vachhani
Arjun Vachhani

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

struggling
struggling

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

Tomer W
Tomer W

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

Michael Mairegger
Michael Mairegger

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

Related Questions