struggling
struggling

Reputation: 535

Removing string from string array at particular index

I am trying to write an algorithm to delete a name from list of names at particular index. Initially i will read a file line by line. The file would be like this :

amelie barbon cat dog thomas | 3
raty  pertw ituy |5

Now for example we see the first line where we have three(3) at last, so here we have to to read the number at last for each line , this number is blackNumber, so called because after reading this number we have to delete the each string at this index one by one until we have 1 string left in the string array. And that only left string is our answer.

For example: Cat will be deleted in first iteration, and the list will become

amelie barbon dog thomas

Now dog will be deleted and then thomas,after these two similar deletion the list will be:

 amelie barbon

Up to here my code is working fine, But now we have to delete at index 3 and the but there are 2 elements only in the list, so the next deletion counter has to start like this :

amelie(index:1)-> barbon(index:2)->amelie(index:3) 

And the string amelie must be deleted, which will remain barbon in the list, and that's the answer is. (This last step when total number of list elements are less then blackNumber, then i am not able to get the logic that how to do).

What i have tried is below:(which will run infinitely when list count is smaller than blackNumber)

 class Program
    {
        static void Main(string[] args)
        {
            using (StreamReader reader = File.OpenText("C:\\Users\\Mohit\\Desktop\\PolmStudio Tasks\\anmeDelete\\anmeDelete\\file.txt"))

                while (!reader.EndOfStream)
                {
                    List<string> list = null;
                    string line = reader.ReadLine(); ;
                    if (null != line)
                    {
                        list = new List<string>();

                        string[] digits = line.Split(new char[] { ' ', '\n', '|' }, StringSplitOptions.RemoveEmptyEntries);
                        for (int i = 0; i < digits.Count() - 1; i++)
                        {
                            list.Add(digits[i]);
                        }
                        int blacknumber = Convert.ToInt32(digits[digits.Count() - 1]) - 1;
                        do
                        {
                            for (int i = 0; i < list.Count(); i++)
                            {
                                if (i == blacknumber)
                                {
                                    list.RemoveAt(i);
                                }
                            }
                        } while (list.Count > 1);

                    }
                    foreach (string str in list)
                    {
                        Console.WriteLine(str);
                    }

                    Console.WriteLine("");
                }
            Console.ReadKey();
        }
    }

Upvotes: 1

Views: 3023

Answers (6)

M.kazem Akhgary
M.kazem Akhgary

Reputation: 19149

Its a simple math. assume your list length is 3. and you want to remove 5th element.

5 % (3 - 1) = 1. so you must remove item at index 1 i.e 2nd element.

If the index of element that you are trying to remove is less than count of list then you just normally remove it.

List<string> list = new List<string>{"amelie", "barbon", "cat", "dog", "thomas"};

int blacknumber = 3;
blacknumber--; // because indexes are 0 based

do
{
    list.RemoveAt(blacknumber < list.Count ? blacknumber : blacknumber % list.Count);
} while (list.Count > 1);


Console.WriteLine(list[0]); // prints barbon

Side note:

Do not use Count() because it calls Enumerable.Count from linq. its not optimum. you can directly use the property of list. with list.Count (without parenthesis.)

Upvotes: 1

struggling
struggling

Reputation: 535

Thanks for the given suggestion and solution your suggestion gave me idea that i cannot change the list items position which are to be deleted, but i can change the blackNumber using % operator, so many friends gave me idea about how to do thanks to them but every one's algo is missing some condition. Below is the working solution which implements all necessary conditions :

 string line = reader.ReadLine();
                    if (null != line)
                    {
                        list = new List<string>();

                        string[] digits = line.Split(new char[] { ' ', '\n', '|' }, StringSplitOptions.RemoveEmptyEntries);
                        for (int i = 0; i < digits.Count() - 1; i++)
                        {
                            list.Add(digits[i]);
                        }
                        int blacknumber = Convert.ToInt32(digits[digits.Count() - 1]);
                        int saveBlackNum = blacknumber;
                        do
                        {
                            for (int i = 0; i < list.Count(); i++)
                            {
                                if ((list.Count < (blacknumber)))
                                {
                                    if(blacknumber % list.Count==0 )
                                    {
                                        blacknumber = list.Count();
                                    }
                                    else
                                    {
                                        blacknumber = ((blacknumber) % list.Count());
                                    }                                  
                                    break;
                                }
                                if ((list.Count >= (blacknumber)))
                                {
                                    if (i == blacknumber - 1)
                                    {
                                        list.RemoveAt(blacknumber - 1);
                                        blacknumber = saveBlackNum;
                                        break;
                                    }
                                }
                            }
                        } while (list.Count > 1);

                    }
                    foreach (string str in list)
                    {
                        Console.WriteLine(str);
                    }
                    Console.WriteLine("");

May be helpful to some one else in future.

Upvotes: 1

5Qe
5Qe

Reputation: 44

Just change the inner loop to the following and you will get your required answer:

do
{
    int i =0;

    if (blacknumber >= list.Count()) i = blacknumber % list.Count();
    else i = blacknumber;

    list.RemoveAt(i);
} while (list.Count > 1);

Upvotes: 1

SILENT
SILENT

Reputation: 4268

I have a simpler solution. The only case I don't know based on your question is what happens if the blackNumber is 1. Will the answer be amelia or thomas?

Heres my code

            var arr = new List<string>() { "amelie", "barbon", "cat", "dog", "thomas" };
            var goal = blackline - 2;
            if (goal > -1)
            {
                if (arr.Count > goal)
                {
                    Console.WriteLine(arr[goal]);
                }
                else
                {
                    Console.WriteLine(arr[arr.Count - 1]);
                }
            }
            else
            {                    
                Console.WriteLine(arr[0]); //if blackline is 1 and answer is suppose to be amelia
                //Console.WriteLine(arr[arr.Count - 1]); //If blackline is 1 and answer is suppose to be thomas
            }

Upvotes: 1

I think, what you're looking for is using modulo % of element n by length

Since you're doing it with a List, you could do something:
int listIndex = i % list.Count;

I believe it shall do as you need. The modulo will return the remaining part of the division, hence the index you are looking for.

Upvotes: 2

Peavey2787
Peavey2787

Reputation: 138

I'm having trouble understanding what you want, is this what you want? To stop removing items if there are less items in that line than the blacknumber? 'if (i == blacknumber && list.Count >= blacknumber)'

Upvotes: -1

Related Questions