I don't have idea how make functional program and I wanna transfer text file into 2D array.
Thank you for answers
This is content of my text file:
0000000011
0011100000
0000001110
1000011100
1000000000
0000111111
1000001100
1000000000
1000011000
1000001111
Code:
static void Main(string[] args)
{
int[,] map = new int[10, 10];
StreamReader reader = new StreamReader(#"Lode.txt");
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
**WHAT I SHOULD PUT HERE**
}
}
reader.Close();
}
You should do following (code with my comments):
var map = new int[10, 10];
using (var reader = new StreamReader("Lode.txt")) // using will call close automatically
{
for (var i = 0; i < 10; i++)
{
var line = reader.ReadLine(); // read one line from file
for (var j = 0; j < 10; j++)
{
map[i, j] = Int32.Parse(line[j].ToString()); // get one symbol from current line and convert it to int
}
}
}
You can try with a little LINQ as follows:
static void Main(string[] args)
{
string filePath = #"Lode.txt";
// Read file contents and store it into a local variable
string fileContents = File.ReadAllText(filePath);
/* Split by CR-LF in a windows system,
then convert it into a list of chars
and then finally do a int.Parse on them
*/
int[][] map = fileContents.Split('\r', '\n')
.Select(x => x.ToList())
.Select(x => x.Select(y => int.Parse(new string(y, 1))).ToArray())
.ToArray();
}
Related
I wrote the following code to generate a population of 6 chromosomes in which each chromosome is an array of 5x5. Then I print each chromosome using another method. The problem is that I got the same array each time!!.
static List<int[,]> PopulationChromosomes = new List<int[,]>();
private void moveGenetic_Click(object sender, EventArgs e)
{
FileStream fs = new FileStream("C:/temp/intialPopulation.txt", FileMode.Append, FileAccess.Write);
writer = new StreamWriter("C:/temp/listOfChromosomesForAllRounds.txt", true);
population = new int[6][,]; // jagged array
Random rnd = new Random(); // to gereate random number (either 0 or 1)
auvChromosomes = new int[5, 5];
for (int i = 0; i < population.Length; i++)
{
population[i] = new int[5, 5];
}
using (StreamWriter sw = new StreamWriter(fs))
{
for (int i = 0; i < population.Length; i++)
{
for (int j = 0; j < 5; j++)
{
for (int k = 0; k < 5; k++)
{
auvChromosomes[j, k] = rnd.Next(0, 2);
sw.Write("|" + auvChromosomes[j, k] + "|");
} // end-inner-for
sw.WriteLine();
} // end-outer-inner-for
PopulationChromosomes.Add(auvChromosomes);
Array.Clear(auvChromosomes, 0, auvChromosomes.Length);
} // end-outer-for
} // end-using
Chromosomes(PopulationChromosomes, 1);
}
Your problem is that you are treating an int[,] as a value type, while in fact it is a reference type. When you add it to your list
PopulationChromosomes.Add(auvChromosomes);
and then clear it
Array.Clear(auvChromosomes, 0, auvChromosomes.Length);
you are clearing the instance which you just put in the list. So the array in the list will be full of zeroes.
Even without the clear, you would keep adding the same instance of the array over and over. You need to create a new array for every iteration.
Solution:
Create a new array instance within your for cycle and skip the Array.Clear part, you shouldn't need it if you create a new instance
for (int i = 0; i < population.Length; i++)
{
auvChromosomes = new int[5, 5];
...
#Michal S's answer already addresses the main issue, but I also wanted to help you clean up your code.
static List<int[,]> PopulationChromosomes = new List<int[,]>();
#region AUV Genetic Movement
private Random rnd = new Random(); // to generate random number (either 0 or 1)
private void moveGenetic_Click(object sender, EventArgs e)
{
using (StreamWriter sw = new StreamWriter(new FileStream("C:/Users/Welcome/Desktop/intialPopulation.txt", FileMode.Append, FileAccess.Write)))
{
var population = new int[6][,]; // define this in the scope where you use it
for (int i = 0; i < population.Length; i++)
{
population[i] = new int[5, 5];
for (int j = 0; j < 5; j++)
{
for (int k = 0; k < 5; k++)
{
population[i][j, k] = rnd.Next(0, 2);
sw.Write("|{0}|", population[i][j, k]);
} // end-inner-for
sw.WriteLine();
} // end-outer-inner-for
PopulationChromosomes.Add(population[i]);
} // end-outer-for
} // end-using
Chromosomes(PopulationChromosomes, 1);
}
and
private const string lineSeparator = new string('-', 90);
public void Chromosomes(IEnumerable<int[,]> population, int round)
{
//////////////// print each chromosome matrix ////////////////
using (writer = new StreamWriter("C:/Users/Welcome/Desktop/listOfChromosomesForAllRounds.txt", true))
{
writer.WriteLine("{0}\n********************************* List of Chrmomsomes (Round : {1})**********************************\n{2}", lineSeparator, round, lineSeparator);
foreach (int[,] chromosme in population)
{
for (int h = 0; h < chromosme.GetLength(0); h++)
{
for (int k = 0; k < chromosme.GetLength(1); k++)
{
writer.Write("|{0}|", chromosme[h, k]);
}
writer.WriteLine();
}
writer.WriteLine(lineSeparator);
}
}
}
Going deeper, you really should have a Chromesome class to encapsulate the 2-d array.
I am trying to generate a random alphanumeric array that consist of 3 letters and 6 digits. The entire array must be random. The only way I could think of is generating 2 individual random arrays and then merging them and randomizing the merged array. Any help would be appreciated. I specifically need help on ensuring that the correct number of variable types are stored. Here is my semi-working code:
static void Main(string[] args)
{
var alphabetic = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var numeric = "0123456789";
var stringChars = new char[9];
var random = new Random();
for (int i = 0; i < 3; i++)
{
stringChars[i] = alphabetic[random.Next(alphabetic.Length)];
}
for(int i = 3; i< stringChars.Length; i++)
{
stringChars[i] = numeric[random.Next(numeric.Length)];
}
var ranChars = new char[9];
var semisorted = new String(stringChars);
for (int i=0; i< ranChars.Length; i++)
{
ranChars[i] = semisorted[random.Next(semisorted.Length)];
}
var final = new string(ranChars);
Console.WriteLine("{0}", final);
Console.ReadLine();
}
You're close. But the problem here is that you're selecting randomly from the "semi-sorted" array, while what's really necessary at that point is picking a random permutation. One way to do that is with a Fisher-Yates shuffle.
So combining that with the code you had that worked: (not tested)
for (int i = 0; i < 3; i++)
{
stringChars[i] = alphabetic[random.Next(alphabetic.Length)];
}
for(int i = 3; i< stringChars.Length; i++)
{
stringChars[i] = numeric[random.Next(numeric.Length)];
}
int n = stringChars.Length;
while (n > 1)
{
int k = random.Next(n--);
char temp = stringChars[n];
stringChars[n] = stringChars[k];
stringChars[k] = temp;
}
string result = new string(stringChars);
Harold's answer is way cleaner, but here's another approach for the whole '100 ways to do the same thing in programming' concept. [Edit: Doh, I reversed the number of digits and letters. Here's a fix:]
public static void Main(string[] args)
{
var random = new Random();
var finalString = string.Empty;
var finalArray = new string[9];
for (var i = 0; i < 3; i++)
{
var alphabet = random.Next(0, 26);
var letter = (char) ('a' + alphabet);
finalArray[i] = letter.ToString().ToUpper();
}
for (var i = 3; i < 9; i++)
{
var number = random.Next(0, 9);
finalArray[i] = number.ToString();
}
var shuffleArray = finalArray.OrderBy(x => random.Next()).ToArray();
for (var i = 0; i < finalArray.Length; i++)
{
finalString += shuffleArray[i];
}
Console.WriteLine(finalString);
Console.ReadKey();
}
As much as I tried to find a similar version in the question here, I couldn't find something.. so I am asking your help.
After reading some numbers from a textfile (now in string format), I split them in rows and columns and add them to a 2d-array (in string format as well). Now I want to convert everythinh in integers so that I can play with sorting the numbers out later.
Here is my code...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace ArrayProgram
{
class Program
{
int number = 0;
int i = 0;
int k = 0;
string strnum;
public void onetohundredints()
{
StreamWriter writer = new StreamWriter("numberstored.txt");
for (i = 0; i < 10; i++)
{
for (k = 0; k < 10; k++)
{
number++;
Console.Write(number + " ");
strnum = number.ToString();
writer.Write(strnum + " ");
}
Console.WriteLine();
writer.WriteLine();
}
writer.Close();
}
public void readints()
{
StreamReader reader = new StreamReader("numberstored.txt");
string data = reader.ReadToEnd();
reader.Close();
string[,] dataarray = new string[10,10];
int[] numbers = new int[100];
string[] dataperlines = data.Split(new[] { '\r','\n' },StringSplitOptions.RemoveEmptyEntries);
for(int i=0; i<=dataperlines.Count()-1; i++)
{
string[] numbersperrow = dataperlines[i].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
for (int j=0; j<=numbersperrow.Count()-1; j++)
{
dataarray[i, j] = numbersperrow[j];
}
}
}
public static void Main(string[] args)
{
Program prog = new Program();
prog.onetohundredints();
prog.readints();
Console.ReadKey();
}
}
}
After I insert the number into the 2d-array, how do I convert all of it in integers?
If you don't have a particular reason to have an array of strings, you can just save you data as int in the first place. Just change your inner for loop to do:
var parsed = int.TryParse(numbersperrow[j], out dataarray[i, j]);
if (!parsed)
{
// Error
}
While that should work, I would suggest to re-write your ReadData method to look similar to the sample below.
public int[,] ReadData(string filePath, int xDimension, int yDimension)
{
var results = new int[xDimension, yDimension];
var lines = File.ReadLines(filePath);
for (var i = 0; i < allLines.Count(); i++)
{
var values = lines[i].Split(new[] { ' ' },
StringSplitOptions.RemoveEmptyEntries);
for (var j = 0; j < values.Count(); j++)
{
var parsed = int.TryParse(values[j], out results[i, j]);
if (!parsed) { }
}
}
return results;
}
You're putting everything into a string array. That array can only hold strings, not numbers. If you want to make the 2d array hold numbers, define it as int[,] dataarray = new int[10,10]; Next, in the final loop, simply do dataarray[i, j] = Convert.ToInt32(numbersperrow[j]);
Edit: You can use int.TryParse(numbersperrow[j], out value) if you aren't sure that numbersperrow[j] will be a number. Value will return false if the conversion is not successful.
I am happy to say that both solutions work. I now have my numbers in my 2d array. But now I wish to play with them. Let's say that I want the numbers printed on the screen in reverse order.
Having this correct solution:
int numbers;
int[,] dataarray = new int[10,10];
string[] dataperlines = data.Split(new[] { '\r','\n' },StringSplitOptions.RemoveEmptyEntries);
for(int i=0; i<=dataperlines.Count()-1; i++)
{
string[] numbersperrow = dataperlines[i].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
for (int j=0; j<=numbersperrow.Count()-1; j++)
{
numbers = int.Parse(numbersperrow[j]);
dataarray[i, j] = numbers;
Console.Write(numbers + " ");
}
Console.WriteLine();
}
I know that I have to make a double for loop. But how do I write a succesful syntax for the numbers to be printed properly?
I also tried this:
int[,] reversedarray = new int[10, 10];
reversedarray[i, j] = Array.Reverse(dataarray[i,j]);
but the dataarray[i,j] becomes red and the error "cannot convert from int to system.Array occurs... what am I missing?
I also tried this...
for (i = 10; i <= dataperlines.Count(); i--)
{
string[] numbersperrow = dataperlines[i].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
for (j =10; j <= numbersperrow.Count(); j--)
{
numbers = int.Parse(numbersperrow[j]);
reversedarray[i, j] = numbers;
Console.Write(numbers + " ");
}
Console.WriteLine();
}
But I have an IndexOutOfRange exception coming from
string[] numbersperrow = dataperlines[i].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
I understood that since I splitted the columns into rows too, it is unecessary to write it again, but I am stuck. I tried simplifying the code since I have my 2darray with its elements and I my tries were fallacious. Any more suggestions?
I would like to create an array of an array from a text file...
There are 20000 line with 21 strings in each line separated by ',' .
I would like to read each line and make it into an array , each line being a new array within.
So I wanted to create the jagged array by starting it like this:
string[][] SqlArray = new string[200000][21];
But it gives: ERROR MESSAGE : Invalid rank specifier: expected ',' or ]
How would I create this array or initialize it?
I will be populating the data in the array like this:
while (true)
{
string theline = readIn.ReadLine();
if (theline == null) break;
string[] workingArray = theline.Split(',');
for (int i = 0; i < workingArray.Length; i++)
{
for (int k = 0; k < 20; k++)
{
SqlArray[i][k] = workingArray[k];
}
}
}
Thank you
That type of initialization only works in Java. You must declare an array of arrays then initialize each in a loop.
string[][] SqlArray = new string[21][];
for(int index = 0; index < SqlArray.Length; index++)
{
SqlArray[index] = new string[2000000];
}
Alternatively, you can use a non-jagged array. It will probably work for what you need.
string[,] SqlArray = new string[21 , 2000000];
It can be accessed like so:
SqlArray[2,6264] = x;
To anyone who is interested this is how I ended up implementing it:
TextReader readIn = File.OpenText("..\\..\\datafile.txt");
string[][] SqlArray = new string[rowNumCreate][];
int e = 0;
while (true)
{
string theline = readIn.ReadLine();
if (theline == null) break;
string[] workingArray = theline.Split(',');
SqlArray[e] = new string[valuesInRow +1];
for (int k = 0; k < workingArray.Length; k++)
{
SqlArray[e][k] = workingArray[k];
}
e++;
}
The file being read is a simple mock database set as a flat file that was auto-generated to test an algorithm that I am implementing, which works with jagged arrays; hence instead of working with a data base I just created this for ease of use and to increase and decrease size at will.
Here is the code to build the text file:
Random skill_id;
skill_id = new Random();
// int counter =0;
string seedvalue = TicksToString();
int rowNumCreate = 200000;
int valuesInRow = 20;
string lineInFile = seedvalue;
string delimiter = ",";
for (int i = 0; i < rowNumCreate; i++)
{
for (int t = 0; t < valuesInRow; t++)
{
int skill = skill_id.Next(40);
string SCon = Convert.ToString(skill);
lineInFile += delimiter + SCon;
}
if (rowNumCreate >= i + 1)
{
dataFile.WriteLine(lineInFile);
lineInFile = "";
string userPK = TicksToString();
lineInFile += userPK;
}
}
dataFile.Close();
public static string TicksToString()
{
long ms = DateTime.Now.Second;
long ms2 = DateTime.Now.Millisecond;
Random seeds;
seeds = new Random();
int ran = seeds.GetHashCode();
return string.Format("{0:X}{1:X}{2:X}", ms, ms2, ran).ToLower();
}
I am still a student so not sure if the code is A-grade but it works :)
Can you please help me with C#.
I am trying to create a function in C# that opens a CSV file and save them to an array:
FileStream fileStream = new FileStream(guid.ToString(), FileMode.Open);
for (int i = 1; i > 200; i++) // it checks the first 200 lines
{
int j = 0;
string[] str = new string[j];
do
{
// saving each character to the variable until comma is found
} while(str == '\n'); // read each character in a for loop until new line character found
}
Can you please help me out?
Something like this:
using (StreamReader r = new StreamReader(guid.ToString()))
{
string line;
int linesCount;
ArrayList result = new ArrayList();
while ((line = r.ReadLine()) != null && linesCount++ <= 200)
{
result.AddRange(line.Split(','));
}
}
Parsing CSV by hand is actually pretty tricky. You might be better off reusing the TextFieldParser (add a reference to the Microsoft.VisualBasic assembly).
using Microsoft.VisualBasic.FileIO;
....
string[,] parsedCsv;
List<string[]> csvLines = new List<string[]>();
TextFieldParser parser = new TextFieldParser(new FileStream(guid.ToString(), FileMode.Open));
parser.Delimiters = new string[] { "," };
parser.TextFieldType = FieldType.Delimited;
int maxLines = 200, lineCount = 0;
try
{
while (!parser.EndOfData && lineCount++ < maxLines)
{
csvLines.Add(parser.ReadFields());
}
}
catch (MalformedLineException)
{
Console.WriteLine("Line Number: {0} Value: {1}", parser.ErrorLineNumber, parser.ErrorLine);
return;
}
parsedCsv = new string[csvLines.Count, csvLines[0].Length];
for (int i = 0; i < csvLines.Count; i++)
{
for (int j = 0; j < csvLines[i].Length; j++)
{
parsedCsv[i, j] = csvLines[i][j];
}
}
I have assumed here that the output is going to be a 2-D array of strings - you may need to adjust this code depending on what you are after, especially if you have to cope with the situation where each line does not have the same number of fields (perhaps unlikely, but still).
The really useful thing about TextFieldParser is that it will cope with different kinds of delimeters. By setting parser.Delimiters = new string[] { "\t" };, for example, this same code could parse tab-delimited text.
What about:
string[] lines = File.ReadAllLines(path);
if(lines.Length >= 200){
for(int i = 0; i < 200; i++){
string[] str = lines[i].Split(',');
//do something here
}
}
You can just use the string.Split(',') extension method.
using (StreamReader streamReader = new StreamReader(File.OpenRead(guid.ToString())))
{
for (int i = 0; i <= 200; ++i)
{
string[] str = streamReader.ReadLine().Split(',');
}
}
The Split extension method will return a string array of the individual values separated by a comma.