Search multi-dimensional array - c#

I have a multi-dimensional array in a text file:
a,1,2,3
b,4,5,6
c,7,8,9
d,10,11,12
I want to input one of the numbers, search the array, and display the corresponding letter for the row the number appears in.
Any help would be greatly appreciated.
Edit:
I have a csv file containing the information given above.
So far I have:
1. Created an array to store the read all the lines in the file
2. Created a second array to store the final array values
3. Created a third array to store the line splits at , and place values back into second array.
This is the code:
string[] as_FirstArray = System.IO.File.ReadAllLines("PartNumbersFile.csv");
string[,] as_SecondArray = new string[4, as_FirstArray.Length];
string[] as_ThirdArray;
string s_Input = Console.ReadLine();
for (int i_Count1 = 0; i_Count1 < as_FirstArray.Length; i_Count1++)
{
as_ThirdArray = as_FirstArray[i_Count1].Split(',');
as_SecondArray[0, i_Count1] = as_ThirdArray[0];
as_SecondArray[1, i_Count1] = as_ThirdArray[1];
as_SecondArray[2, i_Count1] = as_ThirdArray[2];
as_SecondArray[3, i_Count1] = as_ThirdArray[3];
}
And now I'm totally stuck. I have been told that, from here, I need to:
1. use a for loop on as_SecondArray index[1] from first row to last row.
2. use an if statement to determine if userinput is found in index[1] and, if so, store the loop count number. (Here, if no match is found, I will repeat for index[2] and again, if no match found, repeat for index[3].)
3. use another for loop and if statement on index[0] to match the count number from the found match, and display the corresponding entry. (I can do this step but that's hopeless without knowing how to do steps 1 and 2.)
I don't how to specify a particular index as the loop target. Or where I place the loop in relation to the loop I already have - inside it or not.
Edit:
THANK YOU TO WHOEVER EDITED MY POST AND I HAVE NOW DELETED MY ANSWER :-)
After A LOT more time I have made a little progress. I have figured out how to loop a particular index and identify if userinput is found in that index:
for (int i_Count2 = 0; i_Count2 < as_SecondArray.GetLength(1); i_Count2++)
{
for (int i_Count3 = 0; i_Count3 < as_SecondArray.GetLength(0); i_Count3++)
{
if (as_SecondArray[1, i_Count3].Equals(s_Input))
{
s_Found = as_SecondArray[1, i_Count3];
}
else { lblOutput.Text = "not found"; }
}
}
But I am stuck at how to retrieve the i_Count3 loop number.

Don't create multidimensional array instead create a Dictionary or Hashtable where key will be the number and value will be the letter. Now you can easily search the number and find associated letter with the search time of O(1).

Related

How can I check for integers in list and print the index of them?

so my problem is that I don't know how to go forward in the list and print the next same integer if there is one.
Here is what I have at the moment:
while (list.Contains(input1))
{
Console.WriteLine(input1 + " is at index " + list.IndexOf(input1))
}
I am trying to list all of the integers that are in the list and print the index of them. But not remove after finding one of the integers (this was at least my first idea.).
IndexOf has an overload with two parameters, which allows you to start searching at a later position in the list.
Since this is obviously a learning exercise, I won't spoil it by providing the full code, but rather suggest that you try to implement the following algorithm:
Find the index of input starting at position 0.
If not found (i.e., IndexOf returns -1): we're done. Otherwise:
Print and remember that index.
Start again at step 1, but this time, don't start searching at 0 but at the index you remembered + 1.
You can do the following:
go through the list/array using for statement
for(int i=0; i < list.length; i++) // loop though list
then inside the loop check the value of the current item using if statement:
if(list[i] == input1)
//do smothing
The list[0] represent the first item in the array, which means the index is 0.
so in the example above the i will be the current index so long that you in the loop.
I didn't write the full code for learning purpose in reference to #Heinzi answer.
Hope that could be helpful!
This is an implementation possibility. It is longer than it has to be, but it makes it clearer for beginners how one could tackle this problem.
Since you wanted to only show numbers that come up more than once here is an implementation method. If you want to show numbers that come up only once too just erase everything about lastindex
List<int> yourlist = new List<int> { 1,1,1,1,1,11,2,3,3,4,4,5 };
int input = 0;
input = Convert.ToInt32(Console.ReadLine());
var index = yourlist.IndexOf(input);
//this checks if your input is in the list
var lastindex = yourlist.LastIndexOf(input);
//this does the same but it searches for the last implementation of your input
if (index != -1 && lastindex != index)
//this if checks if your number comes up more than once. IndexOf returns -1 if there is no occurence of your input
{
Console.Write($"the index of {input} is {index}");
for (int i = index+1; i <= yourlist.Count; i++)
//this loop takes the position of the first occurence of your number and then counts up from there
{
var tempindex = yourlist.IndexOf(input, i);
if (tempindex != -1)
//this if lets everything except -1 through
{
Console.Write($" and {tempindex}");
}
}
}
else
{
Console.WriteLine("your number cannot be found twice in the list");
}

Count the filled array elements and display result into label

I've got a string[] Brands = new string[10];
With the following code i'm giving it 4 standard values. I can add values with a add button. (I already got this part of code)
public Form1()
{
{
InitializeComponent();
Merken[0] = "Yamaha";
Merken[1] = "Suzuki";
Merken[2] = "Harley";
Merken[3] = "Kawasaki";
merkNr = 4;
listBoxMotoren.DataSource = Brands;
}
}
I want to display the FILLED elements of the array into a `label.text.
So, when I run the program the label shows the numer 4 (because 4 elements of the array are filled). When I add a value to the array with btnclick, the label needs to display the number 5 and so on...`
You can use Linq to get count of filled elements from array.
int count = Merken.ToList().Where(x => (!string.IsNullOrEmpty(x))).Count();
yourLabel.Text = count.ToString();
An easier way would be to use a List<string> and display the Count() of the list. Lists are data structures which grow dynamically, thus each time you add an item to the list, the list grows automatically.
If you want to use arrays, you could start from the first element and use the String.IsNullorEmpty(string str) and a counter which is incremented each time you find a string which is neither null or empty.
Once that you hit a null/empty string, you stop your loop and display the counter.
Forgive me if I'm interpreting this as more simple than it is, but as far as I can tell all you need to do is add "[name of label on form].Text = Merken.Count().ToString();" in the code that adds the new item.
Is there a particular reason you used Merken in the setup but declared it initially as Brands?
why you arent using List
it has Count property. and if you need array for export you call .ToArray() method to get array of your list.
Will you ever have blank indexes?
Merken[4] = ""
Merken[5] = "Honda"
If you are not going to ever have blank indexes, you can set your label to:
[arrayName].length
This will add together the number of indexes in the array.
EDIT: OP says there will be blank indexes
I would recommend looping through the array to see which indexes have values and then increment a counter which you will set as the label text.
int indexesWithValues = 0;
for (int i = 0; i < Brands.length; i++)
{
if (Brands[i] != "")
{
indexesWithValues++;
}
}
Then you set your label text to the counter.
You can get the number of elements in array using
Using System.LINQ
-----
Marken.Count();

"Index Out of Bounds" error when using the Split method for an Array

I am trying to split the data in this array, but it keeps giving me this error:
index out of bounds.
The size of the array is 10. The line of code that is creating the error is
int score = int.Parse(scoreInfo[1]);
This is the code that I have:
static void Main(string[] args)
{
const int SIZE = 10;
for (int j = 0; j < SIZE; j++)
{
// prompt the user
Console.WriteLine("Enter player name and score on one line");
Console.WriteLine("seperated by a space.");
// Read one line of data from the file and save it in inputStr
string inputStr = Console.ReadLine();
// The split method creates an array of two strings
string[] scoreInfo = inputStr.Split();
// Parse each element of the array into the correct data type.
string name = (scoreInfo[0]);
int score = int.Parse(scoreInfo[1]);
if (inputStr == "")
{
Console.WriteLine(scoreInfo[j]);
}
}
Console.ReadLine();
}
A few things of note. You are using SIZE to denote how many iterations your loop should make. It is not the size of your array. Your array is only going to be large as the split makes it. If you split with a space as the delimiter, you're going to have 2 objects in the array at indices 0 and 1.
That last section where you're saying to write scoreInfo[j] will fail as soon as j is larger than 1.
I tried your code using a constant, something like "Guy 19". The .Split() method will break up your input string based on spaces. If you're not entering a space followed by a number, then your scoreInfo[1] will be empty and parsing will fail.
Try adding a break point after your .Split() to determine if scoreInfo is correctly split into a size 2 array, with [0] being the name of the player and [1] being an integer score. If you're entering a name like "FirstName LastName 20" then the information at position [1] is not going to be an integer and the parsing will also fail.
Your for-loop is sort of puzzling, are you looping through 10 times for a team of 10 players? You could put your dialog in a while loop and break out when parsing fails or the user types something like "exit".

Searching the same line in different arrays c#

I have six different arrays each with the same amount of elements in them, my question is, if I want to view the line that says 'test' and it happens to be the 22nd line, is there a way so that I can view the 22nd of all the arrays at the same time and then print them to the console, is it possible to do that?
e.g. I want to search through one array and then when it finds 'test' it prints out the same index of all arrays, including the one which 'test' was contained in.
Could a Binary Search be used here?
Thanks.
Yes you can.
Simply iterate through the first array until you find the string you are looking for, then use the counter to access the remaining arrays. Your code should look something like this:
for (int counter = 0; counter < Array1.Length; counter++)
{
if (Array1[counter] == "your string here")
{
//Print same line on remaining arrays, eg:
Console.WriteLine(Array2[counter]);
Console.WriteLine(Array3[counter]);
//Then you can break out of the loop
break;
}
}
If those are arrays, i can't see any problem doing this:
string[] array1, array2, array3..// etc
...
var stringToSearch = "someValue";
...
int matchPosition = Array.IndexOf(array1, stringToSearch);
if(matchPosition != -1)
{
// just sample of usage - access string by array2[matchPosition]
Console.WriteLine(array2[matchPosition]);
Console.WriteLine(array3[matchPosition]);
}

Create text files of every combination of specific lines within a base text file

Ok, so hopefully I can explain this in enough detail for somebody to be able to help me.. I am writing a program in C# that is supposed to take a text file and replace specific text, which happen to be names of files, and print a new text file for every single combination of the given filenames. The specific places to change the text of filenames have their own set of possible filenames, listed as an array described below. The program should run regardless of how many filenames are available for each location as well as how many total locations for the filenames. If you really wanted to make it awesome, it can be slightly optimized knowing that no filenames should be duplicated throughout any single text file.
text is an array of lines that make up the base of the total file.
lineNum holds an array of the line locations of the filename entries.
previousFiles is an array of previously used filenames, starting with what is already in the file.
files is a jagged 2-dimensional array of possible filenames where files[1] would be an array of all the possible filenames for the 2nd location
Here is an example of how it would work with 3 separate filename locations, the first one given 3 possible filenames, the second given 8 possible filenames, and the third given 3 possible filenames.
Oh and assume buildNewFile works.
int iterator = 0;
for (int a = 0; a < 3; a++)
{
for (int b = 0; b < 8; b++)
{
for (int c = 0; c < 3; c++)
{
iterator++;
text[lineNums[0]] = text[lineNums[0]].Replace(previousFiles[0], files[0][a]);
text[lineNums[1]] = text[lineNums[1]].Replace(previousFiles[0], files[0][a]);
text[lineNums[2]] = text[lineNums[2]].Replace(previousFiles[1], files[1][b]);
text[lineNums[3]] = text[lineNums[3]].Replace(previousFiles[1], files[1][b]);
text[lineNums[4]] = text[lineNums[4]].Replace(previousFiles[2], files[2][c]);
text[lineNums[5]] = text[lineNums[5]].Replace(previousFiles[2], files[2][c]);
previousFiles = new string[] { files[0][a], files[1][b], files[2][c] };
buildNewFile(text, Info.baseFolder + "networks\\" + Info.dsnFilename + iterator + ".dsn");
}
}
}
If you guys can help me, thank you so much, I just can't figure out how to do it recursively or anything. If you have any questions I'll answer them and edit up here to reflect that.
It took me a little while to figure out what you really wanted to do. This problem can be solved without recursion, the trick is to look at the data you have and get it into a more usable format.
Your "files" array is the one that is the most inconvenient. The trick is to transform the data into usable permutations. To do that, I suggest taking advantage of yield and using a method that returns IEnumerable. The code for it is here:
public IEnumerable<string[]> GenerateFileNameStream(string[][] files)
{
int[] current_indices = new int[files.Length];
current_indices.Initialize();
List<string> file_names = new List<string>();
while (current_indices[0] < files[0].Length)
{
file_names.Clear();
for (var index_index = 0; index_index < current_indices.Length; index_index++)
{
file_names.Add(files[index_index][current_indices[index_index]]);
}
yield return file_names.ToArray();
// increment the indices, trickle down as needed
for (var check_index = 0; check_index < current_indices.Length; check_index++)
{
current_indices[check_index]++;
// if the index hasn't rolled over, we're done here
if (current_indices[check_index] < files[check_index].Length) break;
// if the last location rolls over, then we are totally done
if (check_index == current_indices.Length - 1) yield break;
// reset this index, increment the next one in the next iteration
current_indices[check_index] = 0;
}
}
}
Basically, it keeps track of the current index for each row of the files 2D array and returns the file name at each current index. Then it increments the first index. If the first index rolls over, then it resets to 0 and increments the next index instead. This way we can iterate through every permutation of the file names.
Now, looking at the relationship between lineNum and files, I assume that each location in the file is copied to two lines. The rest of the code is here:
public void MakeItWork(string[][] files, int[] lineNum, string[] text, string[] previousFiles)
{
var iterator = 0;
var filenames = GenerateFileNameStream(files);
// work a copy of the text, assume the "previousFiles" are in this text
var text_copy = new string[text.Length];
foreach (var filenameset in filenames)
{
iterator++;
Array.Copy(text, text_copy, text.Length);
for (var line_index = 0; line_index < lineNum.Length; line_index++)
{
var line_number = lineNum[line_index];
text[line_number] = text[line_number].Replace(previousFiles[line_index], filenameset[line_index / 2]);
}
buildNewFile(text_copy, Info.baseFolder + "networks\\" + Info.dsnFilename + iterator + ".dsn");
}
}
This code just takes the results from the enumerator and generates the files for you. The assumption based on your sample code is that each filename location is used twice per file (since the lineNum array was twice as long as the files location count.
I haven't fully tested all the code, but the crux of the algorithm is there. The key is to transform your data into a more usable form, then process it. The other suggestion I have when asking a question here is to describe the problem more as a "problem" and not in the terms of your current solution. If you detailed the goal you are trying to achieve instead of showing code, you can get more insights into the problem.

Categories