Loop to Check if Index Has Repeated in C# - c#

I would like to create a for loop to check if an index value has repeated, and if it has to remove it from the original and display an updated list with no repeated index values.
I have and Array (called Original) with multiple values being repeated, and then I created a Temporary Array (called TempArray) with the same exact values.
I want to check the Original and TempArray values against each other to see if there are duplicates.
I want my code to be similar to a previous one I did where I deleted an index from the middle of my array, as follows
for (int i = 0; i < Original.Length; i++)
{
TempArray[i] = Original[i];
}
Original = new int[Original.Length - 1];
//Set index to delete
int DeleteIndex = 3;
//modify size of Orignial array and copy in array without deleted element index
for (int i = 0; i < TempArray.Length; i++)
{
if (i < DeleteIndex)
{
Original[i] = TempArray[i];
}
else if (i > DeleteIndex)
{
Original[i - 1] = TempArray[i];
}
}
P.S. Original[] is an array from a text file. Sorry if my explanation is hard to understand as I am new to computer programming.
Also is there any way to do this code without LINQ, I have to create using arrays only as its all thats been taught at school?

It took some time to understand what you want :)
to check if an index value has repeated, and if it has to remove it from the original and display an updated list with no repeated index values
It is shortly called distinct values. There is a LINQ method .Distinct():
Original = Original.Distinct().ToArray();
It will remove all repeated values.
where I deleted an index from the middle of my array
You can do this easier by converting to List, applying RemoveAt and back:
var list = new List<int>(Original);
list.RemoveAt(DeleteIndex);
Original = list.ToArray();
P.S. Assuming that you say "index" about the values in your array, it is pretty confusing. Array does not store indices - index is usually understood as a key of an array.

May be this will do the trick for you. I am assuming that you need to remove duplicate from your array
Original = Original.Distinct().ToArray();
Will Returns distinct elements from a sequence by using the default equality comparer to compare values.

Related

How do I sort a cloned temp list in a while loop without also sorting the original list(C#)?

I copied an int list into a temporary list in a while loop so I could sort it without sorting the original. For some reason both get sorted when I do this and I don't understand why.
public static int sortedSum(List<int> a)
{
int ans = 0;
while (a.Count > 0)
{
var temp = a;
temp.Sort();
for (int i = 0; i < a.Count; i++)
{
ans += temp[i] * (i + 1);
}
a.RemoveAt(a.Count - 1);
}
return ans;
}
The Problem I was trying to solve requires me to keep removing the last index spot and then sorting the list. I thought cloning the list would allow me to manipulate the list without messing with the index spots of the original but when I sort the Temp list the original gets sorted as well. I suspect this is a function of the while loop, but if so I'm confused at to why the "a" list would take on the characteristics of the temp list and not vise versa as the "var temp = a;" would suggest. I was able to work around the problem by converting temp to an int array and sorting that, but I'm still curious as to what's going on here.
I copied an int list into a temporary list
No you didn't - var temp = a; does not create a copy of the list - they are referencing the same list.
I would just do
var temp = a.OrderBy(x => x).ToList();
if you want a separate, sorted list. There may even be more efficient ways to do what you're trying to do, but your logic is not clear enough to make a better suggestion.

Find remaining elements in the sequence

everyone. I've this small task to do:
There are two sequences of numbers:
A[0], A[1], ... , A[n].
B[0], B[1], ... , B[m].
Do the following operations with the sequence A:
Remove the items whose indices are divisible by B[0].
In the items remained, remove those whose indices are divisible by B[1].
Repeat this process up to B[m].
Output the items finally remained.
Input is like this: (where -1 is delimiter for two sequences A and B)
1 2 4 3 6 5 -1 2 -1
Here goes my code (explanation done via comments):
List<int> result = new List<int>(); // list for sequence A
List<int> values = new List<int>(); // list for holding value to remove
var input = Console.ReadLine().Split().Select(int.Parse).ToArray();
var len = Array.IndexOf(input, -1); // getting index of the first -1 (delimiter)
result = input.ToList(); // converting input array to List
result.RemoveRange(len, input.Length - len); // and deleting everything beyond first delimiter (including it)
for (var i = len + 1; i < input.Length - 1; i++) // for the number of elements in the sequence B
{
for (var j = 0; j < result.Count; j++) // going through all elmnts in sequence A
{
if (j % input[i] == 0) // if index is divisible by B[i]
{
values.Add(result[j]); // adding associated value to List<int> values
}
}
foreach (var value in values) // after all elements in sequence A have been looked upon, now deleting those who apply to criteria
{
result.Remove(value);
}
}
But the problem is that I'm only passing 5/11 tests cases. The 25% is 'Wrong result' and the rest 25% - 'Timed out'. I understand that my code is probably very badly written, but I really can't get to understand how to improve it.
So, if someone more experienced could explain (clarify) next points to me it would be very cool:
1. Am I doing parsing from the console input right? I feel like it could be done in a more elegant/efficient way.
2. Is my logic of getting value which apply to criteria and then storing them for later deleting is efficient in terms of performance? Or is there any other way to do it?
3. Why is this code not passing all test-cases or how would you change it in order to pass all of them?
I'm writing the answer once again, since I have misunderstood the problem completely. So undoubtly the problem in your code is a removal of elements. Let's try to avoid that. Let's try to make a new array C, where you can store all the correct numbers that should be left in the A array after each removal. So if index id is not divisible by B[i], you should add A[id] to the array C. Then, after checking all the indices with the B[i] value, you should replace the array A with the array C and do the same for B[i + 1]. Repeat until you reach the end of the array B.
The algorithm:
1. For each value in B:
2. For each id from 1 to length(A):
3. If id % value != 0, add A[id] to C
4. A = C
5. Return A.
EDIT: Be sure to make a new array C for each iteration of the 1. loop (or clear C after replacing A with it)

Switching around elements in an array based on calculations (in a nested for loop?) [duplicate]

This question already has answers here:
Sorting an array related to another array
(4 answers)
Sorting two arrays (values,keys), then sorting the keys
(5 answers)
Closed 5 years ago.
This is my first post on stackoverflow, so forgive any formatting mistakes.
I have a project named BOGOTotal - basically, its job is to take a decimal array of prices, sort them in ascending order, and then determine which prices will be bought and which prices will be free. Anyways, that's just a bit of backstory, but I need something more specific.
I've got two arrays - one of the prices, and one of the quantities of those prices. For example, in my Items array (should have been named "prices"), Items[0] is set to 2.20m, and my Quantities array, Quantites[0] is set to 5. Meaning I have five of the same item that are priced at $2.20.
//create items array
decimal[] Items = new decimal[5];
Items[0] = 2.20m;
Items[1] = 1.50m;
Items[2] = 8.40m;
Items[3] = 4.60m;
Items[4] = 3.75m;
//create quantity array
int[] Quantity = new int[Items.Length];
Quantity[0] = 5;
Quantity[1] = 2;
Quantity[2] = 1;
Quantity[3] = 3;
Quantity[4] = 6;
I then had to sort the Items array in ascending order.
Array.Sort(Items);
However, when I sorted my Items array, the relation of each item to its quantity is now lost, because Items[0] and Quantity[0] no longer are related. Now, instead of Items[0] = 2.20m, it has become Items[0] = 1.50m. Now, I have 5 items that are $1.50 instead of $2.20.
Here's where I had my idea - I would go ahead and calculate the prices of the old arrays by creating a firstPrices array, putting them in a for loop, and saying
decimal[] firstPrices = new decimal[Items.Length];
//calculate prices before sorting - will match back up afterward
for (int i = 0; i < Items.Length; i++)
{
firstPrices[i] = Items[i] * Convert.ToDecimal(Quantity[i]);
}
Here comes the hard part: I'm trying to re-align (for lack of a better word) each quantity to its Item - meaning I'm trying to make the item that is $2.20 match back up with its correct quantity (being 5). However, I'm having a hard time doing this. I tried a nested for loop within another for loop that tested each quantity by multiplying it by the current Item and then comparing it to that spot in firstPrices:
//i would be newItems
//j would be quantity
for (int i = 0; i < Items.Length; i++)
{
for (int j = 0; j < Items.Length; j++)
{
if (Items[i] * Quantity[j] == firstPrices[i])
{
Quantity[i] = Quantity[j];
break;
}
}
}
When it found a match, I set it to break out of the nested loop and increment "i", which goes to the next item in the Items array. Is there something I'm doing wrong here?
You got two seperate arrays that are related, wich is not a good thing. Make a Struct, Class or Tupel containing both values. Optionally also a custom comparer. Make a array of that type.
Then it would be as simple as calling Array.Sort().
In caess where there is no single order (sometimes you want to sort by prices times quantity. Sometimes single item price), Array.Sort() has overrides that allow you to specify the comparer to be used.
You could also go for Linq, if you have experience with it. But getting both values into one type is a requirement. And the perfect time to learn that.

How to delete element from array?

I have an string array like this
K={"book","handbook","car"}
I would like to check if any string contains other string,if it does I would like to remove it from array .In the case of array K,new array should be like this
K="{"book","car"}
for (i = 0; i < 10; i++)
{
if (keywords.Contains(keywords[i])) {
//I have no idea for this part
}
}
It might make more sense to use a List<>, a data structure designed for editing, whereas an array is a fixed structure. But, assuming you have an array, and need to end up with a modified array, you could convert:
IEnumerable<string> invalid_words = // ... list of words K cannot contain
string[] K = // .. array of strings you are given
K = K.Where(p => !invalid_words.Contains(p)).ToArray();
This might be a little "smelly" but it's better than try to modify the array when you are in an iteration.
The idea is this: save all the indexes where the word appears, and then erase those words. This is not the best solution, but it can help you with your problem. I highly recommends you to read about "Lists" because there are great on C# and it's easier use them than use arrays
K="{"book","car"};
//Never use a number, try to use the .length propertie
List<int> indexes=new List<int>();//using lists is easier than arrays
enter code here
for (i = 0; i < K.length; i++)
{
if (keywords.Contains(K[i]))
{
//You save the index where the word is
indexes.add(i);
}
}
//Here you take those indexes and create a new Array
int[] theNewArray=new int[K.length-indexes.Count];
int positionInTheNewArray=0;
for (i = 0; i < K.length; i++)
{
if(!indexes.Contains(i))
{ theNewArray[positionInTheNewArray]=K[i];
positionInTheNewArray++;
}
}
}
That fits if your array allows duplicated words and also if duplicated words are not allowed.

"Contains" method doesn't seem to working the way it should

I'm trying to see if when a user enters some text it searches the array for any matches, and whatever doesn't match gets removed from the array;
string search = textBox1.Text;
for (int i = 0; i < staffUsers.Count; i++)
{
if (!(staffUsers[i].staff_name.Contains(search)))
{
staffUsers.Remove(staffUsers[i]);
}
}
I have some rubbish names in my array 'Rob Dob','Joe Bloggs', 'h h', 'ghg hgh', and if the search variable ended up being 'R', Joe Bloggs would get removed but 'h h' and 'ghg hgh' stay there, but there is no R involved there at all? any reason why>?!
You have to iterate backwards in order to remove from an array. Every time you remove an item, your array gets smaller. By going backwards, that fact does not matter.
string search = textBox1.Text;
for (int i = staffUsers.Count - 1; i >= 0 ; i--)
{
if (!(staffUsers[i].staff_name.Contains(search)))
{
staffUsers.Remove(staffUsers[i]);
}
}
The problem with your code is that you are removing items as you iterate over it. You remove an item, but keep iterating, even though the size of the array changes when you remove an item.
You need to reset your i value after you remove something. Alternatively, you need to use a built in to do the heavy lifting:
staffUsers.RemoveAll(i => !(i.staff_name.Contains(search)));
Uses a tiny LINQ expression to do the work. Remove all items where that predicate matches. i represents an item to apply the expression to. If that expression evaluates to true, away it goes.
Long story short, whenever you remove an item at index [i], you skip the item at index [i+1]. For example, if your array looks like:
{'Joe Bloggs', 'Rob Dobb', 'h h', 'gafddf'}; i=0
remove Joe Bloggs, which is at position 0.
{Rob Dobb', 'h h', 'gafddf'}; i=1
remove 'h h', which is at position 1
{Rob Dobb', 'gafddf'}; i=2
i is not less than yourArray.Count, so the loop stops. There is no position 2.
The quickest fix is to add i-- if you remove something from index [i]. In your case,
staffUsers.Remove(staffUsers[i]);
i--;
Hope this helps!
In each iteration of the loop, either remove an item or increment the counter, not both operations. Otherwise, you'll skip the next array element whenever you remove an array element:
string search = textBox1.Text;
for (int i = 0; i < staffUsers.Count;)
{
if (!(staffUsers[i].staff_name.Contains(search)))
{
staffUsers.Remove(staffUsers[i]);
}
else
{
i++;
}
}
The simplest way to solve the above problem is using LINQ.
Following code disentangle above problem.
string search = textBox1.Text;
staffUsers= (from user in staffUsers
where !user.Contains(search)
select user).ToArray<string>();
Note: I assumed staffUsers is array of string.
string search = textBox1.Text;
for (int i = 0; i < staffUsers.Count; i++)
{
if (!(staffUsers[i].staff_name.Contains(search)))
{
staffUsers.Remove(staffUsers[i]);
// reset the index one stepback
i--;
}
}

Categories

Resources