Array's value is changed for no ostensible reason - c#

I'm trying to embed a very basic AI in a game of Tic Tac Toe and I'm running into a problem with the arrays that I use to discern the most suitable square to claim.
I have one array that represents the game grid in its current state and another that represents the way it would look if a certain square were claimed.
The AI kept making weird decisions, so I decided to have it report various information at certain milestones.
string[,] currentGrid;
string[,] hypotheticalGrid;
MessageBox.Show(currentGrid);
hypotheticalGrid = currentGrid;
hypotheticalGrid[x, y] = "O";
MessageBox.Show(currentGrid);
Bear in mind that the above is a very simplified version of the actual code.
The arrays are assigned values along the line and the message boxes are set to display currentGrid as a sequence of its contained values.
Everything works properly except the code between the message boxes.
The problem is that the two message boxes display different results even though the latter is a copy of the former and no changes to currentGrid are specified in the space between the two.
The two lines in between are copied directly from the source code and should only affect the hypothetical grid. As should be obvious, these lines are supposed to reset the hypothetical grid and then add an "O" to the square in question.
However, the "O" also gets placed in the current grid for some reason.
What am I doing wrong?

The line hypotheticalGrid = currentGrid; does not make a copy of currentGrid, instead both variables point to the same array. So any change made in hypotheticalGrid will be seen in currentGrid too.
You should have hypotheticalGrid be a copy of currentGrid:
hypotheticalGrid = (string[,])currentGrid.Clone();
In this case, Clone() will work, because strings are immutable in .NET. In other cases, Clone might not be good enough, just something to be aware of.

The problem is that your assignment:
hypotheticalGrid = currentGrid;
is merely a reference assignment, meaning that now they both point to the same array in memory, so any changes to the hypothetical grid will affect the current grid as well.
You'd need a full item copy in order for them to not interfere with each other.

Keep in mind, that arrays are reference types. Your assignment copies the reference but does not create a duplicate of the array. After the assignment both array variables point to the same array!
You can create an array duplicate like this:
string[] hypotheticalGrid = new string[currentGrid.Length];
Array.Copy(currentGrid, hypotheticalGrid, currentGrid.Length);
Note that this does not create a duplicate of the items contained in the array, but this is not a problem, since strings are immutable. I.e. if you manipulate a string in one of the arrays, this creates a new string and therefore has no effect on the second array.
EDIT:
By looking at the other posts I see that it can be done easier with the Clone method:
string[] hypotheticalGrid = currentGrid.Clone();

Related

can sort some arrays but not others?

I'm sorting the lines of a text box in reverse alphabetical order, and the code I have works fine:
string[] temp = textBox.Lines;
Array.Sort(temp);
Array.Reverse(temp);
textBox.Lines = temp;
But I'm confused as to why Visual Studio wouldn't let me do:
Array.Sort(textBox.Lines);
Array.Reverse(textBox.Lines);
Mostly I'm trying to figure out the subtleties of C# since I'm still new to it.
EDIT: The second snippet doesn't error out, but it doesn't execute any code (i.e. doesn't appear to do anything).
Here's a few lines of the getter for TextBox.Lines:
public string[] Lines
{
get
{
string text = Text;
ArrayList list = new ArrayList();
...
...
return(string[]) list.ToArray(typeof(string));
}
You're getting a new collection, which has a copy of the data in it from the TextBox. You're not actually sorting the data in the TextBox.
When void Array.Sort is done sorting the array passed back from that property, the original TextBox remains unchanged.
Indeed, your array will be sorted and reversed, but what happens is that will not be assigned to TextBox. Modifying the Lines array has no effect since it is computed property.
You need to assign it to Lines property to see the effect.
Here is the reference to source
This is because textBox.Lines is not exposed as a member variable on the class but rather as a property. Behind the scenes, a property is really two methods, e.g. get_Lines and set_Lines. All you know about the array you get back from get_Lines is that it's an array of strings. There's no guarantee that that property is backed by an actual array--maybe TextBox keeps the text internally as one big string that it then breaks into pieces for you when you call get_Lines. So you're not necessarily modifying the internal list when you call Sort() and Reverse() on the result of get_Lines.

Replace values located close to themselves with the mean value

I'm not sure if SO is the proper place for asking this, if it's not, I will remove the question and try it in some other place. Said that I'm trying to do the following:
I have a List<double> and want to replace the block of values whose values are situated very close (say 0.75 in this example) to a single value, representing the mean of the replaced values.
The values that are isolated, or alone, should not be modified.
Also the replaced block can't be longer than 5.
Computing the mean value for each interval from 0, 5, 10.. would not provide the expected results.
It happened many times that LINQ power surprised me gladly and I would be happy if someone could guide me in the creation of this little method.
What I've thought is to first find the closest values for each one, calculate the distance, if the distance is less than minimum (0.75 in this example) then assign those values to the same block.
When all values are assigned to their blocks run a second loop that replaces each block (with one value, or many values) to its mean.
The problem that I have in this approach is to assign the "block": if several values are together, I need to check if the evaluating value is contained in another block, and if it so, the new value should be in that block too.
I don't know if this is the right way of doing this or I'm over complicating it.
EDIT: the expected result:
Although you see two axes only one is used, the List is 1D, I should have drawn only the X axis.
The length of the lines that are represented is irrelevant. It's just to mark on the axis where the value is situated.
It turns out that MSDN has already done this, and provided an in-depth example application with code:
Data Clustering - Detecting Abnormal Data Using k-Means Clustering

Is prototype pattern the right fit here?

I have an array of type Cell. This is a 2D array.
Depending on certain conditions, I might have to resize this array and shift the Cell objects one row or column down/right/left.
I was thinking of using the prototype pattern to copy the original array into another larger array.
Does this offer any more benefits over simply doing an array resize?
Edit: I realized that I have not mentioned my intent. I don't really need another object. I just want a larger array based on certain conditions.
The only reason this could be of help is if you are making a shallow copy: copying would save you the costs of creating new objects. The flip side of it is that all Cell objects inside the array would be shared among multiple 2D arrays; if this presents a problem, you should go back to creating arrays from scratch.
Short answer No.
There is an alternative solution that will solve your problem without needing a prototype.
Don't store the cells in an array.
The cells don't know their row and column numbers but instead ask the row/column for it.
This allows the columns to be rearranged without having to update every item.
Have a container object that represents the array and can return the cell at a given (x,y) coordinate. If the array is sparce (or if it has a sensible default) then treat a missing cell as the default. This will massively reduce storage costs.
The columns and rows belong to the container. Adding an empty row or column now becomes a case of inserting a row or column object.

How do I take data from a text file and split it into Arrays?

I have a project where I need to split data from a text file into an array or an "array of structure" as my professor said, and I'm pretty confused as to how to go about doing it.
Basically I have data arranged like this in a text file (doesn't have to be like this.. can be one thing per line):
PR214;MR43T;RBL8;14K22
PR223;R43;RJ6;14K24
PR224;R43N;RN4;14K30
PR246;R46N;RN8;14K32
PR247;R46TS;RBL17Y;14K33
PR248;R46TX;RBL12-6;14K35
PR324;S46;J11;14K38
PR326;SR46E;XEJ8;14K40
PR444;47L;H12;14K44
The numbers in the first column (PR...) represent a CCC number. The 2nd, 3rd, and 4th columns represent part numbers for three different companies (column 2 is one company, column 3 another, etc). The user will tell me the company, and the part number under the company by selecting a radio button and then typing in the part (ie company 3, and "RJ6") and then I'm supposed to give the customer the CCC number ("PR223").
I'm not asking you guys to do my homework for me but I have a hard time grasping arrays. Could you point me in the right as to how to go about doing this?
The other answers are correct. You read in each line from the text file and insert the values into a structure defined by your data. For each new line you need to use an instance of the structure, so you do that be making an array of structures which just a group of structures.
If you are struggling understanding arrays, you really need to work on that. Think of arrays like group of boxes. Let's start with 3 boxes in row. Each is the same size and can only hold what fits inside them. You can assigned type of item (data) to the boxes but all the boxes can only hold that type of item. The boxes are numbered from 0 to 2. In some languages, you can name the boxes (an associative array) but not in C# AFAIK. So that gives you a one dimensional array.
For two dimensonal array think of a Chess board. Do you know how to record a chess match? Chess notation uses A to H for the horizontal position and 1 to 8 for the vertical position. So the white queen starts in position D1. Now if I was programming a chess game I would use and 8x8 array just like the chess board. Of course the numbering on my array will be 0-7 across the top and 0-7 up the side. The Position of the white queen in my array would then be [3][0]. So placing data in a two dimensional array is like placing piece on a chess board. The game battleship is another example of a 2 dimensional array.
Adding dimensions to your array is like adding a new coordinate to your graph. You start with X, then you add Y and they add Z. So on and so forth.
You can use the ReadLine method of a StreamReader to read your file one line at a time. Then you can use the String.Split(char[]) method to get a string array of the values in each line. If you already know how to make structures you should be set.
If you look at each line of data there's a common delimiter between the 'columns', so you want to get each line split into four separate entities. As you work line by
line and get those four discrete elements should can assign each to the appropriate part of the structure. You'll of course have one 'structure' for each line, so an array of structure here at the end.

What is the fast way of getting an index of an element in an array? [duplicate]

This question already has answers here:
How to find the index of an element in an array in Java?
(15 answers)
Closed 6 years ago.
I was asked this question in an interview. Although the interview was for dot net position, he asked me this question in context to java, because I had mentioned java also in my resume.
How to find the index of an element having value X in an array ?
I said iterating from the first element till last and checking whether the value is X would give the result. He asked about a method involving less number of iterations, I said using binary search but that is only possible for sorted array. I tried saying using IndexOf function in the Array class. But nothing from my side answered that question.
Is there any fast way of getting the index of an element having value X in an array ?
As long as there is no knowledge about the array (is it sorted? ascending or descending? etc etc), there is no way of finding an element without inspecting each one.
Also, that is exactly what indexOf does (when using lists).
How to find the index of an element having value X in an array ?
This would be fast:
int getXIndex(int x){
myArray[0] = x;
return 0;
}
A practical way of finding it faster is by parallel processing.
Just divide the array in N parts and assign every part to a thread that iterates through the elements of its part until value is found. N should preferably be the processor's number of cores.
If a binary search isn't possible (beacuse the array isn't sorted) and you don't have some kind of advanced search index, the only way I could think of that isn't O(n) is if the item's position in the array is a function of the item itself (like, if the array is [10, 20, 30, 40], the position of an element n is (n / 10) - 1).
Maybe he wants to test your knowledge about Java.
There is Utility Class called Arrays, this class contains various methods for manipulating arrays (such as sorting and searching)
http://download.oracle.com/javase/6/docs/api/java/util/Arrays.html
In 2 lines you can have a O(n * log n) result:
Arrays.sort(list); //O(n * log n)
Arrays.binarySearch(list, 88)); //O(log n)
Puneet - in .net its:
string[] testArray = {"fred", "bill"};
var indexOffset = Array.IndexOf(testArray, "fred");
[edit] - having read the question properly now, :) an alternative in linq would be:
string[] testArray = { "cat", "dog", "banana", "orange" };
int firstItem = testArray.Select((item, index) => new
{
ItemName = item,
Position = index
}).Where(i => i.ItemName == "banana")
.First()
.Position;
this of course would find the FIRST occurence of the string. subsequent duplicates would require additional logic. but then so would a looped approach.
jim
It's a question about data structures and algorithms (altough a very simple data structure). It goes beyond the language you are using.
If the array is ordered you can get O(log n) using binary search and a modified version of it for border cases (not using always (a+b)/2 as the pivot point, but it's a pretty sophisticated quirk).
If the array is not ordered then... good luck.
He can be asking you about what methods you have in order to find an item in Java. But anyway they're not faster. They can be olny simpler to use (than a for-each - compare - return).
There's another solution that's creating an auxiliary structure to do a faster search (like a hashmap) but, OF COURSE, it's more expensive to create it and use it once than to do a simple linear search.
Take a perfectly unsorted array, just a list of numbers in memory. All the machine can do is look at individual numbers in memory, and check if they are the right number. This is the "password cracker problem". There is no faster way than to search from the beginning until the correct value is hit.
Are you sure about the question? I have got a questions somewhat similar to your question.
Given a sorted array, there is one element "x" whose value is same as its index find the index of that element.
For example:
//0,1,2,3,4,5,6,7,8,9, 10
int a[10]={1,3,5,5,6,6,6,8,9,10,11};
at index 6 that value and index are same.
for this array a, answer should be 6.
This is not an answer, in case there was something missed in the original question this would clarify that.
If the only information you have is the fact that it's an unsorted array, with no reletionship between the index and value, and with no auxiliary data structures, then you have to potentially examine every element to see if it holds the information you want.
However, interviews are meant to separate the wheat from the chaff so it's important to realise that they want to see how you approach problems. Hence the idea is to ask questions to see if any more information is (or could be made) available, information that can make your search more efficient.
Questions like:
1/ Does the data change very often?
If not, then you can use an extra data structure.
For example, maintain a dirty flag which is initially true. When you want to find an item and it's true, build that extra structure (sorted array, tree, hash or whatever) which will greatly speed up searches, then set the dirty flag to false, then use that structure to find the item.
If you want to find an item and the dirty flag is false, just use the structure, no need to rebuild it.
Of course, any changes to the data should set the dirty flag to true so that the next search rebuilds the structure.
This will greatly speed up (through amortisation) queries for data that's read far more often than written.
In other words, the first search after a change will be relatively slow but subsequent searches can be much faster.
You'll probably want to wrap the array inside a class so that you can control the dirty flag correctly.
2/ Are we allowed to use a different data structure than a raw array?
This will be similar to the first point given above. If we modify the data structure from an array into an arbitrary class containing the array, you can still get all the advantages such as quick random access to each element.
But we gain the ability to update extra information within the data structure whenever the data changes.
So, rather than using a dirty flag and doing a large update on the next search, we can make small changes to the extra information whenever the array is changed.
This gets rid of the slow response of the first search after a change by amortising the cost across all changes (each change having a small cost).
3. How many items will typically be in the list?
This is actually more important than most people realise.
All talk of optimisation tends to be useless unless your data sets are relatively large and performance is actually important.
For example, if you have a 100-item array, it's quite acceptable to use even the brain-dead bubble sort since the difference in timings between that and the fastest sort you can find tend to be irrelevant (unless you need to do it thousands of times per second of course).
For this case, finding the first index for a given value, it's probably perfectly acceptable to do a sequential search as long as your array stays under a certain size.
The bottom line is that you're there to prove your worth, and the interviewer is (usually) there to guide you. Unless they're sadistic, they're quite happy for you to ask them questions to try an narrow down the scope of the problem.
Ask the questions (as you have for the possibility the data may be sorted. They should be impressed with your approach even if you can't come up with a solution.
In fact (and I've done this in the past), they may reject all your possibile approaches (no, it's not sorted, no, no other data structures are allowed, and so on) just to see how far you get.
And maybe, just maybe, like the Kobayashi Maru, it may not be about winning, it may be how you deal with failure :-)

Categories